Skip to content
This repository was archived by the owner on Mar 2, 2019. It is now read-only.

Commit d764765

Browse files
author
kvn
committed
8205528: Base64 encoding algorithm using AVX512 instructions
Reviewed-by: kvn, psandoz Contributed-by: smita.kamath@intel.com
1 parent 8a8f702 commit d764765

File tree

28 files changed

+1851
-23
lines changed

28 files changed

+1851
-23
lines changed

src/hotspot/cpu/x86/assembler_x86.cpp

Lines changed: 130 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ Address::Address(int disp, address loc, relocInfo::relocType rtype) {
133133
_index = noreg;
134134
_scale = no_scale;
135135
_disp = disp;
136+
_xmmindex = xnoreg;
137+
_isxmmindex = false;
136138
switch (rtype) {
137139
case relocInfo::external_word_type:
138140
_rspec = external_word_Relocation::spec(loc);
@@ -172,6 +174,8 @@ Address::Address(address loc, RelocationHolder spec) {
172174
_scale = no_scale;
173175
_disp = (intptr_t) loc;
174176
_rspec = spec;
177+
_xmmindex = xnoreg;
178+
_isxmmindex = false;
175179
}
176180

177181
#endif // _LP64
@@ -604,6 +608,21 @@ void Assembler::emit_operand(XMMRegister reg, Register base, Register index,
604608
emit_operand((Register)reg, base, index, scale, disp, rspec);
605609
}
606610

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+
607626
// Secret local extension to Assembler::WhichOperand:
608627
#define end_pc_operand (_WhichOperand_limit)
609628

@@ -1104,8 +1123,12 @@ void Assembler::emit_operand(Register reg, Address adr,
11041123
}
11051124

11061125
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+
}
11091132
}
11101133

11111134
// MMX operations
@@ -3419,6 +3442,15 @@ void Assembler::vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, in
34193442
emit_int8(imm8);
34203443
}
34213444

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+
34223454

34233455
void Assembler::pause() {
34243456
emit_int8((unsigned char)0xF3);
@@ -3870,6 +3902,17 @@ void Assembler::vpmovzxbw(XMMRegister dst, Address src, int vector_len) {
38703902
emit_operand(dst, src);
38713903
}
38723904

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+
38733916
void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
38743917
assert(is_vector_masking(), "");
38753918
assert(VM_Version::supports_avx512vlbw(), "");
@@ -3883,7 +3926,6 @@ void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vec
38833926
emit_int8(0x30);
38843927
emit_operand(dst, src);
38853928
}
3886-
38873929
void Assembler::evpmovwb(Address dst, XMMRegister src, int vector_len) {
38883930
assert(VM_Version::supports_avx512vlbw(), "");
38893931
assert(src != xnoreg, "sanity");
@@ -3911,6 +3953,28 @@ void Assembler::evpmovwb(Address dst, KRegister mask, XMMRegister src, int vecto
39113953
emit_operand(src, dst);
39123954
}
39133955

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+
39143978
// generic
39153979
void Assembler::pop(Register dst) {
39163980
int encode = prefix_and_encode(dst->encoding());
@@ -6080,6 +6144,24 @@ void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int
60806144
emit_int8((unsigned char)(0xC0 | encode));
60816145
}
60826146

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+
60836165
// Shift packed integers arithmetically right by specified number of bits.
60846166
void Assembler::psraw(XMMRegister dst, int shift) {
60856167
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -6181,6 +6263,15 @@ void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_
61816263
emit_operand(dst, src);
61826264
}
61836265

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+
61846275
void Assembler::pandn(XMMRegister dst, XMMRegister src) {
61856276
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
61866277
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
62166307
emit_operand(dst, src);
62176308
}
62186309

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+
62196319
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
62206320
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
62216321
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) {
68496949
emit_int8((unsigned char)(0xC0 | encode));
68506950
}
68516951

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+
}
68526966

68536967
// Carry-Less Multiplication Quadword
68546968
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
74747588
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
74757589
bool vex_r = ((xreg_enc & 8) == 8) ? 1 : 0;
74767590
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+
}
74787597
set_attributes(attributes);
74797598
attributes->set_current_assembler(this);
74807599

@@ -7511,7 +7630,13 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix
75117630
if (UseAVX > 2 && !attributes->is_legacy_mode())
75127631
{
75137632
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+
}
75157640
attributes->set_is_evex_instruction();
75167641
evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
75177642
} else {

0 commit comments

Comments
 (0)