@@ -133,6 +133,8 @@ Address::Address(int disp, address loc, relocInfo::relocType rtype) {
133
133
_index = noreg;
134
134
_scale = no_scale;
135
135
_disp = disp;
136
+ _xmmindex = xnoreg;
137
+ _isxmmindex = false ;
136
138
switch (rtype) {
137
139
case relocInfo::external_word_type:
138
140
_rspec = external_word_Relocation::spec (loc);
@@ -172,6 +174,8 @@ Address::Address(address loc, RelocationHolder spec) {
172
174
_scale = no_scale;
173
175
_disp = (intptr_t ) loc;
174
176
_rspec = spec;
177
+ _xmmindex = xnoreg;
178
+ _isxmmindex = false ;
175
179
}
176
180
177
181
#endif // _LP64
@@ -604,6 +608,21 @@ void Assembler::emit_operand(XMMRegister reg, Register base, Register index,
604
608
emit_operand ((Register)reg, base, index, scale, disp, rspec);
605
609
}
606
610
611
+ void Assembler::emit_operand (XMMRegister reg, Register base, XMMRegister index,
612
+ Address::ScaleFactor scale, int disp,
613
+ RelocationHolder const & rspec) {
614
+ if (UseAVX > 2 ) {
615
+ int xreg_enc = reg->encoding ();
616
+ int xmmindex_enc = index->encoding ();
617
+ XMMRegister new_reg = as_XMMRegister (xreg_enc & 0xf );
618
+ XMMRegister new_index = as_XMMRegister (xmmindex_enc & 0xf );
619
+ emit_operand ((Register)new_reg, base, (Register)new_index, scale, disp, rspec);
620
+ } else {
621
+ emit_operand ((Register)reg, base, (Register)index, scale, disp, rspec);
622
+ }
623
+ }
624
+
625
+
607
626
// Secret local extension to Assembler::WhichOperand:
608
627
#define end_pc_operand (_WhichOperand_limit)
609
628
@@ -1104,8 +1123,12 @@ void Assembler::emit_operand(Register reg, Address adr,
1104
1123
}
1105
1124
1106
1125
void Assembler::emit_operand (XMMRegister reg, Address adr) {
1107
- emit_operand (reg, adr._base , adr._index , adr._scale , adr._disp ,
1108
- adr._rspec );
1126
+ if (adr.isxmmindex ()) {
1127
+ emit_operand (reg, adr._base , adr._xmmindex , adr._scale , adr._disp , adr._rspec );
1128
+ } else {
1129
+ emit_operand (reg, adr._base , adr._index , adr._scale , adr._disp ,
1130
+ adr._rspec );
1131
+ }
1109
1132
}
1110
1133
1111
1134
// MMX operations
@@ -3419,6 +3442,15 @@ void Assembler::vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, in
3419
3442
emit_int8 (imm8);
3420
3443
}
3421
3444
3445
+ void Assembler::evpermi2q (XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3446
+ assert (VM_Version::supports_evex (), " " );
3447
+ InstructionAttr attributes (vector_len, /* vex_w */ true , /* legacy_mode */ false , /* no_mask_reg */ true , /* uses_vl */ true );
3448
+ attributes.set_is_evex_instruction ();
3449
+ int encode = vex_prefix_and_encode (dst->encoding (), nds->encoding (), src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3450
+ emit_int8 (0x76 );
3451
+ emit_int8 ((unsigned char )(0xC0 | encode));
3452
+ }
3453
+
3422
3454
3423
3455
void Assembler::pause () {
3424
3456
emit_int8 ((unsigned char )0xF3 );
@@ -3870,6 +3902,17 @@ void Assembler::vpmovzxbw(XMMRegister dst, Address src, int vector_len) {
3870
3902
emit_operand (dst, src);
3871
3903
}
3872
3904
3905
+ void Assembler::vpmovzxbw (XMMRegister dst, XMMRegister src, int vector_len) {
3906
+ assert (vector_len == AVX_128bit? VM_Version::supports_avx () :
3907
+ vector_len == AVX_256bit? VM_Version::supports_avx2 () :
3908
+ vector_len == AVX_512bit? VM_Version::supports_avx512bw () : 0 , " " );
3909
+ InstructionAttr attributes (vector_len, /* rex_w */ false , /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true , /* uses_vl */ false );
3910
+ int encode = vex_prefix_and_encode (dst->encoding (), 0 , src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3911
+ emit_int8 (0x30 );
3912
+ emit_int8 ((unsigned char ) (0xC0 | encode));
3913
+ }
3914
+
3915
+
3873
3916
void Assembler::evpmovzxbw (XMMRegister dst, KRegister mask, Address src, int vector_len) {
3874
3917
assert (is_vector_masking (), " " );
3875
3918
assert (VM_Version::supports_avx512vlbw (), " " );
@@ -3883,7 +3926,6 @@ void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vec
3883
3926
emit_int8 (0x30 );
3884
3927
emit_operand (dst, src);
3885
3928
}
3886
-
3887
3929
void Assembler::evpmovwb (Address dst, XMMRegister src, int vector_len) {
3888
3930
assert (VM_Version::supports_avx512vlbw (), " " );
3889
3931
assert (src != xnoreg, " sanity" );
@@ -3911,6 +3953,28 @@ void Assembler::evpmovwb(Address dst, KRegister mask, XMMRegister src, int vecto
3911
3953
emit_operand (src, dst);
3912
3954
}
3913
3955
3956
+ void Assembler::evpmovdb (Address dst, XMMRegister src, int vector_len) {
3957
+ assert (VM_Version::supports_evex (), " " );
3958
+ assert (src != xnoreg, " sanity" );
3959
+ InstructionMark im (this );
3960
+ InstructionAttr attributes (vector_len, /* rex_w */ false , /* legacy_mode */ false , /* no_mask_reg */ true , /* uses_vl */ false );
3961
+ attributes.set_address_attributes (/* tuple_type */ EVEX_QVM, /* input_size_in_bits */ EVEX_NObit);
3962
+ attributes.set_is_evex_instruction ();
3963
+ vex_prefix (dst, 0 , src->encoding (), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
3964
+ emit_int8 (0x31 );
3965
+ emit_operand (src, dst);
3966
+ }
3967
+
3968
+ void Assembler::vpmovzxwd (XMMRegister dst, XMMRegister src, int vector_len) {
3969
+ assert (vector_len == AVX_128bit? VM_Version::supports_avx () :
3970
+ vector_len == AVX_256bit? VM_Version::supports_avx2 () :
3971
+ vector_len == AVX_512bit? VM_Version::supports_evex () : 0 , " " );
3972
+ InstructionAttr attributes (vector_len, /* rex_w */ false , /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true , /* uses_vl */ false );
3973
+ int encode = vex_prefix_and_encode (dst->encoding (), 0 , src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3974
+ emit_int8 (0x33 );
3975
+ emit_int8 ((unsigned char )(0xC0 | encode));
3976
+ }
3977
+
3914
3978
// generic
3915
3979
void Assembler::pop (Register dst) {
3916
3980
int encode = prefix_and_encode (dst->encoding ());
@@ -6080,6 +6144,24 @@ void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int
6080
6144
emit_int8 ((unsigned char )(0xC0 | encode));
6081
6145
}
6082
6146
6147
+ void Assembler::evpsrlvw (XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6148
+ assert (VM_Version::supports_avx512bw (), " " );
6149
+ InstructionAttr attributes (vector_len, /* vex_w */ true , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
6150
+ attributes.set_is_evex_instruction ();
6151
+ int encode = vex_prefix_and_encode (dst->encoding (), nds->encoding (), src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6152
+ emit_int8 (0x10 );
6153
+ emit_int8 ((unsigned char )(0xC0 | encode));
6154
+ }
6155
+
6156
+ void Assembler::evpsllvw (XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6157
+ assert (VM_Version::supports_avx512bw (), " " );
6158
+ InstructionAttr attributes (vector_len, /* rex_w */ true , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
6159
+ attributes.set_is_evex_instruction ();
6160
+ int encode = vex_prefix_and_encode (dst->encoding (), nds->encoding (), src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6161
+ emit_int8 (0x12 );
6162
+ emit_int8 ((unsigned char )(0xC0 | encode));
6163
+ }
6164
+
6083
6165
// Shift packed integers arithmetically right by specified number of bits.
6084
6166
void Assembler::psraw (XMMRegister dst, int shift) {
6085
6167
NOT_LP64 (assert (VM_Version::supports_sse2 (), " " ));
@@ -6181,6 +6263,15 @@ void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_
6181
6263
emit_operand (dst, src);
6182
6264
}
6183
6265
6266
+ void Assembler::vpandq (XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6267
+ assert (VM_Version::supports_evex (), " " );
6268
+ InstructionAttr attributes (vector_len, /* vex_w */ true , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
6269
+ int encode = vex_prefix_and_encode (dst->encoding (), nds->encoding (), src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6270
+ emit_int8 ((unsigned char )0xDB );
6271
+ emit_int8 ((unsigned char )(0xC0 | encode));
6272
+ }
6273
+
6274
+
6184
6275
void Assembler::pandn (XMMRegister dst, XMMRegister src) {
6185
6276
NOT_LP64 (assert (VM_Version::supports_sse2 (), " " ));
6186
6277
InstructionAttr attributes (AVX_128bit, /* vex_w */ VM_Version::supports_evex (), /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
@@ -6216,6 +6307,15 @@ void Assembler::vpor(XMMRegister dst, XMMRegister nds, Address src, int vector_l
6216
6307
emit_operand (dst, src);
6217
6308
}
6218
6309
6310
+ void Assembler::vporq (XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6311
+ assert (VM_Version::supports_evex (), " " );
6312
+ InstructionAttr attributes (vector_len, /* vex_w */ true , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
6313
+ int encode = vex_prefix_and_encode (dst->encoding (), nds->encoding (), src->encoding (), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6314
+ emit_int8 ((unsigned char )0xEB );
6315
+ emit_int8 ((unsigned char )(0xC0 | encode));
6316
+ }
6317
+
6318
+
6219
6319
void Assembler::pxor (XMMRegister dst, XMMRegister src) {
6220
6320
NOT_LP64 (assert (VM_Version::supports_sse2 (), " " ));
6221
6321
InstructionAttr attributes (AVX_128bit, /* rex_w */ false , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
@@ -6849,6 +6949,20 @@ void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) {
6849
6949
emit_int8 ((unsigned char )(0xC0 | encode));
6850
6950
}
6851
6951
6952
+ void Assembler::evpgatherdd (XMMRegister dst, KRegister mask, Address src, int vector_len) {
6953
+ assert (VM_Version::supports_evex (), " " );
6954
+ assert (dst != xnoreg, " sanity" );
6955
+ InstructionMark im (this );
6956
+ InstructionAttr attributes (vector_len, /* vex_w */ false , /* legacy_mode */ false , /* no_mask_reg */ false , /* uses_vl */ true );
6957
+ attributes.set_address_attributes (/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
6958
+ attributes.reset_is_clear_context ();
6959
+ attributes.set_embedded_opmask_register_specifier (mask);
6960
+ attributes.set_is_evex_instruction ();
6961
+ // swap src<->dst for encoding
6962
+ vex_prefix (src, 0 , dst->encoding (), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6963
+ emit_int8 ((unsigned char )0x90 );
6964
+ emit_operand (dst, src);
6965
+ }
6852
6966
6853
6967
// Carry-Less Multiplication Quadword
6854
6968
void Assembler::pclmulqdq (XMMRegister dst, XMMRegister src, int mask) {
@@ -7474,7 +7588,12 @@ void Assembler::evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_r, boo
7474
7588
void Assembler::vex_prefix (Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
7475
7589
bool vex_r = ((xreg_enc & 8 ) == 8 ) ? 1 : 0 ;
7476
7590
bool vex_b = adr.base_needs_rex ();
7477
- bool vex_x = adr.index_needs_rex ();
7591
+ bool vex_x;
7592
+ if (adr.isxmmindex ()) {
7593
+ vex_x = adr.xmmindex_needs_rex ();
7594
+ } else {
7595
+ vex_x = adr.index_needs_rex ();
7596
+ }
7478
7597
set_attributes (attributes);
7479
7598
attributes->set_current_assembler (this );
7480
7599
@@ -7511,7 +7630,13 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix
7511
7630
if (UseAVX > 2 && !attributes->is_legacy_mode ())
7512
7631
{
7513
7632
bool evex_r = (xreg_enc >= 16 );
7514
- bool evex_v = (nds_enc >= 16 );
7633
+ bool evex_v;
7634
+ // EVEX.V' is set to true when VSIB is used as we may need to use higher order XMM registers (16-31)
7635
+ if (adr.isxmmindex ()) {
7636
+ evex_v = ((adr._xmmindex ->encoding () > 15 ) ? true : false );
7637
+ } else {
7638
+ evex_v = (nds_enc >= 16 );
7639
+ }
7515
7640
attributes->set_is_evex_instruction ();
7516
7641
evex_prefix (vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
7517
7642
} else {
0 commit comments