5289 %{
5290 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
5291 match(ConL);
5292
5293 op_cost(0);
5294 format %{ %}
5295 interface(CONST_INTER);
5296 %}
5297
5298 // Offset for scaled or unscaled immediate loads and stores
5299 operand immIOffset()
5300 %{
5301 predicate(Address::offset_ok_for_immed(n->get_int()));
5302 match(ConI);
5303
5304 op_cost(0);
5305 format %{ %}
5306 interface(CONST_INTER);
5307 %}
5308
5309 operand immLoffset()
5310 %{
5311 predicate(Address::offset_ok_for_immed(n->get_long()));
5312 match(ConL);
5313
5314 op_cost(0);
5315 format %{ %}
5316 interface(CONST_INTER);
5317 %}
5318
5319 // 32 bit integer valid for add sub immediate
5320 operand immIAddSub()
5321 %{
5322 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int()));
5323 match(ConI);
5324 op_cost(0);
5325 format %{ %}
5326 interface(CONST_INTER);
5327 %}
5328
5329 // 32 bit unsigned integer valid for logical immediate
5330 // TODO -- check this is right when e.g the mask is 0x80000000
5331 operand immILog()
5332 %{
5333 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int()));
5334 match(ConI);
5335
5336 op_cost(0);
5337 format %{ %}
5338 interface(CONST_INTER);
6133 index($lreg);
6134 scale(0x0);
6135 disp(0x0);
6136 %}
6137 %}
6138
6139 operand indOffI(iRegP reg, immIOffset off)
6140 %{
6141 constraint(ALLOC_IN_RC(ptr_reg));
6142 match(AddP reg off);
6143 op_cost(0);
6144 format %{ "[$reg, $off]" %}
6145 interface(MEMORY_INTER) %{
6146 base($reg);
6147 index(0xffffffff);
6148 scale(0x0);
6149 disp($off);
6150 %}
6151 %}
6152
6153 operand indOffL(iRegP reg, immLoffset off)
6154 %{
6155 constraint(ALLOC_IN_RC(ptr_reg));
6156 match(AddP reg off);
6157 op_cost(0);
6158 format %{ "[$reg, $off]" %}
6159 interface(MEMORY_INTER) %{
6160 base($reg);
6161 index(0xffffffff);
6162 scale(0x0);
6163 disp($off);
6164 %}
6165 %}
6166
6167
6168 operand indirectN(iRegN reg)
6169 %{
6170 predicate(Universe::narrow_oop_shift() == 0);
6171 constraint(ALLOC_IN_RC(ptr_reg));
6172 match(DecodeN reg);
6173 op_cost(0);
6174 format %{ "[$reg]\t# narrow" %}
6175 interface(MEMORY_INTER) %{
6176 base($reg);
6177 index(0xffffffff);
6178 scale(0x0);
6179 disp(0x0);
6180 %}
6181 %}
6182
6183 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off)
6184 %{
6185 predicate(Universe::narrow_oop_shift() == 0);
6186 constraint(ALLOC_IN_RC(ptr_reg));
6459 less_equal(0x9, "ls");
6460 greater(0x8, "hi");
6461 overflow(0x6, "vs");
6462 no_overflow(0x7, "vc");
6463 %}
6464 %}
6465
6466 // Special operand allowing long args to int ops to be truncated for free
6467
6468 operand iRegL2I(iRegL reg) %{
6469
6470 op_cost(0);
6471
6472 match(ConvL2I reg);
6473
6474 format %{ "l2i($reg)" %}
6475
6476 interface(REG_INTER)
6477 %}
6478
6479 opclass vmem(indirect, indIndex, indOffI, indOffL);
6480
6481 //----------OPERAND CLASSES----------------------------------------------------
6482 // Operand Classes are groups of operands that are used as to simplify
6483 // instruction definitions by not requiring the AD writer to specify
6484 // separate instructions for every form of operand when the
6485 // instruction accepts multiple operand types with the same basic
6486 // encoding and format. The classic case of this is memory operands.
6487
6488 // memory is used to define read/write location for load/store
6489 // instruction defs. we can turn a memory op into an Address
6490
6491 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL,
6492 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN);
6493
6494
6495 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
6496 // operations. it allows the src to be either an iRegI or a (ConvL2I
6497 // iRegL). in the latter case the l2i normally planted for a ConvL2I
6498 // can be elided because the 32-bit instruction will just employ the
6499 // lower 32 bits anyway.
6991 INS01 : ISS;
6992 NEON_FP : S3;
6993 %}
6994
6995 pipe_class vmovi_reg_imm64(vecD dst)
6996 %{
6997 single_instruction;
6998 dst : S3(write);
6999 INS01 : ISS;
7000 NEON_FP : S3;
7001 %}
7002
7003 pipe_class vmovi_reg_imm128(vecX dst)
7004 %{
7005 single_instruction;
7006 dst : S3(write);
7007 INS0 : ISS;
7008 NEON_FP : S3;
7009 %}
7010
7011 pipe_class vload_reg_mem64(vecD dst, vmem mem)
7012 %{
7013 single_instruction;
7014 dst : S5(write);
7015 mem : ISS(read);
7016 INS01 : ISS;
7017 NEON_FP : S3;
7018 %}
7019
7020 pipe_class vload_reg_mem128(vecX dst, vmem mem)
7021 %{
7022 single_instruction;
7023 dst : S5(write);
7024 mem : ISS(read);
7025 INS01 : ISS;
7026 NEON_FP : S3;
7027 %}
7028
7029 pipe_class vstore_reg_mem64(vecD src, vmem mem)
7030 %{
7031 single_instruction;
7032 mem : ISS(read);
7033 src : S2(read);
7034 INS01 : ISS;
7035 NEON_FP : S3;
7036 %}
7037
7038 pipe_class vstore_reg_mem128(vecD src, vmem mem)
7039 %{
7040 single_instruction;
7041 mem : ISS(read);
7042 src : S2(read);
7043 INS01 : ISS;
7044 NEON_FP : S3;
7045 %}
7046
7047 //------- Integer ALU operations --------------------------
7048
7049 // Integer ALU reg-reg operation
7050 // Operands needed in EX1, result generated in EX2
7051 // Eg. ADD x0, x1, x2
7052 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
7053 %{
7054 single_instruction;
7055 dst : EX2(write);
7056 src1 : EX1(read);
7057 src2 : EX1(read);
7058 INS01 : ISS; // Dual issue as instruction 0 or 1
14902 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
14903 // for this guy.
14904 instruct tlsLoadP(thread_RegP dst)
14905 %{
14906 match(Set dst (ThreadLocal));
14907
14908 ins_cost(0);
14909
14910 format %{ " -- \t// $dst=Thread::current(), empty" %}
14911
14912 size(0);
14913
14914 ins_encode( /*empty*/ );
14915
14916 ins_pipe(pipe_class_empty);
14917 %}
14918
14919 // ====================VECTOR INSTRUCTIONS=====================================
14920
14921 // Load vector (32 bits)
14922 instruct loadV4(vecD dst, vmem mem)
14923 %{
14924 predicate(n->as_LoadVector()->memory_size() == 4);
14925 match(Set dst (LoadVector mem));
14926 ins_cost(4 * INSN_COST);
14927 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %}
14928 ins_encode( aarch64_enc_ldrvS(dst, mem) );
14929 ins_pipe(vload_reg_mem64);
14930 %}
14931
14932 // Load vector (64 bits)
14933 instruct loadV8(vecD dst, vmem mem)
14934 %{
14935 predicate(n->as_LoadVector()->memory_size() == 8);
14936 match(Set dst (LoadVector mem));
14937 ins_cost(4 * INSN_COST);
14938 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %}
14939 ins_encode( aarch64_enc_ldrvD(dst, mem) );
14940 ins_pipe(vload_reg_mem64);
14941 %}
14942
14943 // Load Vector (128 bits)
14944 instruct loadV16(vecX dst, vmem mem)
14945 %{
14946 predicate(n->as_LoadVector()->memory_size() == 16);
14947 match(Set dst (LoadVector mem));
14948 ins_cost(4 * INSN_COST);
14949 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %}
14950 ins_encode( aarch64_enc_ldrvQ(dst, mem) );
14951 ins_pipe(vload_reg_mem128);
14952 %}
14953
14954 // Store Vector (32 bits)
14955 instruct storeV4(vecD src, vmem mem)
14956 %{
14957 predicate(n->as_StoreVector()->memory_size() == 4);
14958 match(Set mem (StoreVector mem src));
14959 ins_cost(4 * INSN_COST);
14960 format %{ "strs $mem,$src\t# vector (32 bits)" %}
14961 ins_encode( aarch64_enc_strvS(src, mem) );
14962 ins_pipe(vstore_reg_mem64);
14963 %}
14964
14965 // Store Vector (64 bits)
14966 instruct storeV8(vecD src, vmem mem)
14967 %{
14968 predicate(n->as_StoreVector()->memory_size() == 8);
14969 match(Set mem (StoreVector mem src));
14970 ins_cost(4 * INSN_COST);
14971 format %{ "strd $mem,$src\t# vector (64 bits)" %}
14972 ins_encode( aarch64_enc_strvD(src, mem) );
14973 ins_pipe(vstore_reg_mem64);
14974 %}
14975
14976 // Store Vector (128 bits)
14977 instruct storeV16(vecX src, vmem mem)
14978 %{
14979 predicate(n->as_StoreVector()->memory_size() == 16);
14980 match(Set mem (StoreVector mem src));
14981 ins_cost(4 * INSN_COST);
14982 format %{ "strq $mem,$src\t# vector (128 bits)" %}
14983 ins_encode( aarch64_enc_strvQ(src, mem) );
14984 ins_pipe(vstore_reg_mem128);
14985 %}
14986
14987 instruct replicate8B(vecD dst, iRegIorL2I src)
14988 %{
14989 predicate(n->as_Vector()->length() == 4 ||
14990 n->as_Vector()->length() == 8);
14991 match(Set dst (ReplicateB src));
14992 ins_cost(INSN_COST);
14993 format %{ "dup $dst, $src\t# vector (8B)" %}
14994 ins_encode %{
14995 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
14996 %}
14997 ins_pipe(vdup_reg_reg64);
|
5289 %{
5290 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
5291 match(ConL);
5292
5293 op_cost(0);
5294 format %{ %}
5295 interface(CONST_INTER);
5296 %}
5297
5298 // Offset for scaled or unscaled immediate loads and stores
5299 operand immIOffset()
5300 %{
5301 predicate(Address::offset_ok_for_immed(n->get_int()));
5302 match(ConI);
5303
5304 op_cost(0);
5305 format %{ %}
5306 interface(CONST_INTER);
5307 %}
5308
5309 operand immIOffset4()
5310 %{
5311 predicate(Address::offset_ok_for_immed(n->get_int(), 2));
5312 match(ConI);
5313
5314 op_cost(0);
5315 format %{ %}
5316 interface(CONST_INTER);
5317 %}
5318
5319 operand immIOffset8()
5320 %{
5321 predicate(Address::offset_ok_for_immed(n->get_int(), 3));
5322 match(ConI);
5323
5324 op_cost(0);
5325 format %{ %}
5326 interface(CONST_INTER);
5327 %}
5328
5329 operand immIOffset16()
5330 %{
5331 predicate(Address::offset_ok_for_immed(n->get_int(), 4));
5332 match(ConI);
5333
5334 op_cost(0);
5335 format %{ %}
5336 interface(CONST_INTER);
5337 %}
5338
5339 operand immLoffset()
5340 %{
5341 predicate(Address::offset_ok_for_immed(n->get_long()));
5342 match(ConL);
5343
5344 op_cost(0);
5345 format %{ %}
5346 interface(CONST_INTER);
5347 %}
5348
5349 operand immLoffset4()
5350 %{
5351 predicate(Address::offset_ok_for_immed(n->get_long(), 2));
5352 match(ConL);
5353
5354 op_cost(0);
5355 format %{ %}
5356 interface(CONST_INTER);
5357 %}
5358
5359 operand immLoffset8()
5360 %{
5361 predicate(Address::offset_ok_for_immed(n->get_long(), 3));
5362 match(ConL);
5363
5364 op_cost(0);
5365 format %{ %}
5366 interface(CONST_INTER);
5367 %}
5368
5369 operand immLoffset16()
5370 %{
5371 predicate(Address::offset_ok_for_immed(n->get_long(), 4));
5372 match(ConL);
5373
5374 op_cost(0);
5375 format %{ %}
5376 interface(CONST_INTER);
5377 %}
5378
5379 // 32 bit integer valid for add sub immediate
5380 operand immIAddSub()
5381 %{
5382 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int()));
5383 match(ConI);
5384 op_cost(0);
5385 format %{ %}
5386 interface(CONST_INTER);
5387 %}
5388
5389 // 32 bit unsigned integer valid for logical immediate
5390 // TODO -- check this is right when e.g the mask is 0x80000000
5391 operand immILog()
5392 %{
5393 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int()));
5394 match(ConI);
5395
5396 op_cost(0);
5397 format %{ %}
5398 interface(CONST_INTER);
6193 index($lreg);
6194 scale(0x0);
6195 disp(0x0);
6196 %}
6197 %}
6198
6199 operand indOffI(iRegP reg, immIOffset off)
6200 %{
6201 constraint(ALLOC_IN_RC(ptr_reg));
6202 match(AddP reg off);
6203 op_cost(0);
6204 format %{ "[$reg, $off]" %}
6205 interface(MEMORY_INTER) %{
6206 base($reg);
6207 index(0xffffffff);
6208 scale(0x0);
6209 disp($off);
6210 %}
6211 %}
6212
6213 operand indOffI4(iRegP reg, immIOffset4 off)
6214 %{
6215 constraint(ALLOC_IN_RC(ptr_reg));
6216 match(AddP reg off);
6217 op_cost(0);
6218 format %{ "[$reg, $off]" %}
6219 interface(MEMORY_INTER) %{
6220 base($reg);
6221 index(0xffffffff);
6222 scale(0x0);
6223 disp($off);
6224 %}
6225 %}
6226
6227 operand indOffI8(iRegP reg, immIOffset8 off)
6228 %{
6229 constraint(ALLOC_IN_RC(ptr_reg));
6230 match(AddP reg off);
6231 op_cost(0);
6232 format %{ "[$reg, $off]" %}
6233 interface(MEMORY_INTER) %{
6234 base($reg);
6235 index(0xffffffff);
6236 scale(0x0);
6237 disp($off);
6238 %}
6239 %}
6240
6241 operand indOffI16(iRegP reg, immIOffset16 off)
6242 %{
6243 constraint(ALLOC_IN_RC(ptr_reg));
6244 match(AddP reg off);
6245 op_cost(0);
6246 format %{ "[$reg, $off]" %}
6247 interface(MEMORY_INTER) %{
6248 base($reg);
6249 index(0xffffffff);
6250 scale(0x0);
6251 disp($off);
6252 %}
6253 %}
6254
6255 operand indOffL(iRegP reg, immLoffset off)
6256 %{
6257 constraint(ALLOC_IN_RC(ptr_reg));
6258 match(AddP reg off);
6259 op_cost(0);
6260 format %{ "[$reg, $off]" %}
6261 interface(MEMORY_INTER) %{
6262 base($reg);
6263 index(0xffffffff);
6264 scale(0x0);
6265 disp($off);
6266 %}
6267 %}
6268
6269 operand indOffL4(iRegP reg, immLoffset4 off)
6270 %{
6271 constraint(ALLOC_IN_RC(ptr_reg));
6272 match(AddP reg off);
6273 op_cost(0);
6274 format %{ "[$reg, $off]" %}
6275 interface(MEMORY_INTER) %{
6276 base($reg);
6277 index(0xffffffff);
6278 scale(0x0);
6279 disp($off);
6280 %}
6281 %}
6282
6283 operand indOffL8(iRegP reg, immLoffset8 off)
6284 %{
6285 constraint(ALLOC_IN_RC(ptr_reg));
6286 match(AddP reg off);
6287 op_cost(0);
6288 format %{ "[$reg, $off]" %}
6289 interface(MEMORY_INTER) %{
6290 base($reg);
6291 index(0xffffffff);
6292 scale(0x0);
6293 disp($off);
6294 %}
6295 %}
6296
6297 operand indOffL16(iRegP reg, immLoffset16 off)
6298 %{
6299 constraint(ALLOC_IN_RC(ptr_reg));
6300 match(AddP reg off);
6301 op_cost(0);
6302 format %{ "[$reg, $off]" %}
6303 interface(MEMORY_INTER) %{
6304 base($reg);
6305 index(0xffffffff);
6306 scale(0x0);
6307 disp($off);
6308 %}
6309 %}
6310
6311 operand indirectN(iRegN reg)
6312 %{
6313 predicate(Universe::narrow_oop_shift() == 0);
6314 constraint(ALLOC_IN_RC(ptr_reg));
6315 match(DecodeN reg);
6316 op_cost(0);
6317 format %{ "[$reg]\t# narrow" %}
6318 interface(MEMORY_INTER) %{
6319 base($reg);
6320 index(0xffffffff);
6321 scale(0x0);
6322 disp(0x0);
6323 %}
6324 %}
6325
6326 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off)
6327 %{
6328 predicate(Universe::narrow_oop_shift() == 0);
6329 constraint(ALLOC_IN_RC(ptr_reg));
6602 less_equal(0x9, "ls");
6603 greater(0x8, "hi");
6604 overflow(0x6, "vs");
6605 no_overflow(0x7, "vc");
6606 %}
6607 %}
6608
6609 // Special operand allowing long args to int ops to be truncated for free
6610
6611 operand iRegL2I(iRegL reg) %{
6612
6613 op_cost(0);
6614
6615 match(ConvL2I reg);
6616
6617 format %{ "l2i($reg)" %}
6618
6619 interface(REG_INTER)
6620 %}
6621
6622 opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
6623 opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
6624 opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
6625
6626 //----------OPERAND CLASSES----------------------------------------------------
6627 // Operand Classes are groups of operands that are used as to simplify
6628 // instruction definitions by not requiring the AD writer to specify
6629 // separate instructions for every form of operand when the
6630 // instruction accepts multiple operand types with the same basic
6631 // encoding and format. The classic case of this is memory operands.
6632
6633 // memory is used to define read/write location for load/store
6634 // instruction defs. we can turn a memory op into an Address
6635
6636 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL,
6637 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN);
6638
6639
6640 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
6641 // operations. it allows the src to be either an iRegI or a (ConvL2I
6642 // iRegL). in the latter case the l2i normally planted for a ConvL2I
6643 // can be elided because the 32-bit instruction will just employ the
6644 // lower 32 bits anyway.
7136 INS01 : ISS;
7137 NEON_FP : S3;
7138 %}
7139
7140 pipe_class vmovi_reg_imm64(vecD dst)
7141 %{
7142 single_instruction;
7143 dst : S3(write);
7144 INS01 : ISS;
7145 NEON_FP : S3;
7146 %}
7147
7148 pipe_class vmovi_reg_imm128(vecX dst)
7149 %{
7150 single_instruction;
7151 dst : S3(write);
7152 INS0 : ISS;
7153 NEON_FP : S3;
7154 %}
7155
7156 pipe_class vload_reg_mem64(vecD dst, vmem8 mem)
7157 %{
7158 single_instruction;
7159 dst : S5(write);
7160 mem : ISS(read);
7161 INS01 : ISS;
7162 NEON_FP : S3;
7163 %}
7164
7165 pipe_class vload_reg_mem128(vecX dst, vmem16 mem)
7166 %{
7167 single_instruction;
7168 dst : S5(write);
7169 mem : ISS(read);
7170 INS01 : ISS;
7171 NEON_FP : S3;
7172 %}
7173
7174 pipe_class vstore_reg_mem64(vecD src, vmem8 mem)
7175 %{
7176 single_instruction;
7177 mem : ISS(read);
7178 src : S2(read);
7179 INS01 : ISS;
7180 NEON_FP : S3;
7181 %}
7182
7183 pipe_class vstore_reg_mem128(vecD src, vmem16 mem)
7184 %{
7185 single_instruction;
7186 mem : ISS(read);
7187 src : S2(read);
7188 INS01 : ISS;
7189 NEON_FP : S3;
7190 %}
7191
7192 //------- Integer ALU operations --------------------------
7193
7194 // Integer ALU reg-reg operation
7195 // Operands needed in EX1, result generated in EX2
7196 // Eg. ADD x0, x1, x2
7197 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
7198 %{
7199 single_instruction;
7200 dst : EX2(write);
7201 src1 : EX1(read);
7202 src2 : EX1(read);
7203 INS01 : ISS; // Dual issue as instruction 0 or 1
15047 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
15048 // for this guy.
15049 instruct tlsLoadP(thread_RegP dst)
15050 %{
15051 match(Set dst (ThreadLocal));
15052
15053 ins_cost(0);
15054
15055 format %{ " -- \t// $dst=Thread::current(), empty" %}
15056
15057 size(0);
15058
15059 ins_encode( /*empty*/ );
15060
15061 ins_pipe(pipe_class_empty);
15062 %}
15063
15064 // ====================VECTOR INSTRUCTIONS=====================================
15065
15066 // Load vector (32 bits)
15067 instruct loadV4(vecD dst, vmem4 mem)
15068 %{
15069 predicate(n->as_LoadVector()->memory_size() == 4);
15070 match(Set dst (LoadVector mem));
15071 ins_cost(4 * INSN_COST);
15072 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %}
15073 ins_encode( aarch64_enc_ldrvS(dst, mem) );
15074 ins_pipe(vload_reg_mem64);
15075 %}
15076
15077 // Load vector (64 bits)
15078 instruct loadV8(vecD dst, vmem8 mem)
15079 %{
15080 predicate(n->as_LoadVector()->memory_size() == 8);
15081 match(Set dst (LoadVector mem));
15082 ins_cost(4 * INSN_COST);
15083 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %}
15084 ins_encode( aarch64_enc_ldrvD(dst, mem) );
15085 ins_pipe(vload_reg_mem64);
15086 %}
15087
15088 // Load Vector (128 bits)
15089 instruct loadV16(vecX dst, vmem16 mem)
15090 %{
15091 predicate(n->as_LoadVector()->memory_size() == 16);
15092 match(Set dst (LoadVector mem));
15093 ins_cost(4 * INSN_COST);
15094 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %}
15095 ins_encode( aarch64_enc_ldrvQ(dst, mem) );
15096 ins_pipe(vload_reg_mem128);
15097 %}
15098
15099 // Store Vector (32 bits)
15100 instruct storeV4(vecD src, vmem4 mem)
15101 %{
15102 predicate(n->as_StoreVector()->memory_size() == 4);
15103 match(Set mem (StoreVector mem src));
15104 ins_cost(4 * INSN_COST);
15105 format %{ "strs $mem,$src\t# vector (32 bits)" %}
15106 ins_encode( aarch64_enc_strvS(src, mem) );
15107 ins_pipe(vstore_reg_mem64);
15108 %}
15109
15110 // Store Vector (64 bits)
15111 instruct storeV8(vecD src, vmem8 mem)
15112 %{
15113 predicate(n->as_StoreVector()->memory_size() == 8);
15114 match(Set mem (StoreVector mem src));
15115 ins_cost(4 * INSN_COST);
15116 format %{ "strd $mem,$src\t# vector (64 bits)" %}
15117 ins_encode( aarch64_enc_strvD(src, mem) );
15118 ins_pipe(vstore_reg_mem64);
15119 %}
15120
15121 // Store Vector (128 bits)
15122 instruct storeV16(vecX src, vmem16 mem)
15123 %{
15124 predicate(n->as_StoreVector()->memory_size() == 16);
15125 match(Set mem (StoreVector mem src));
15126 ins_cost(4 * INSN_COST);
15127 format %{ "strq $mem,$src\t# vector (128 bits)" %}
15128 ins_encode( aarch64_enc_strvQ(src, mem) );
15129 ins_pipe(vstore_reg_mem128);
15130 %}
15131
15132 instruct replicate8B(vecD dst, iRegIorL2I src)
15133 %{
15134 predicate(n->as_Vector()->length() == 4 ||
15135 n->as_Vector()->length() == 8);
15136 match(Set dst (ReplicateB src));
15137 ins_cost(INSN_COST);
15138 format %{ "dup $dst, $src\t# vector (8B)" %}
15139 ins_encode %{
15140 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
15141 %}
15142 ins_pipe(vdup_reg_reg64);
|