diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index e4ab99bf1c3..03ce06726c6 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -1488,9 +1488,10 @@ void Assembler::addl(Register dst, Register src) { void Assembler::eaddl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x01, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void)evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x03, 0xC0, src1, src2); } void Assembler::addr_nop_4() { @@ -1728,9 +1729,10 @@ void Assembler::andl(Register dst, Register src) { void Assembler::eandl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x21, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x23, 0xC0, src1, src2); } void Assembler::andnl(Register dst, Register src1, Register src2) { @@ -2637,7 +2639,7 @@ void Assembler::eimull(Register dst, Address src, int32_t value, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); if (is8bit(value)) { emit_int8((unsigned char)0x6B); emit_operand(dst, src, 1); @@ -4467,7 +4469,9 @@ void Assembler::enotl(Register dst, Register src) { void Assembler::eorw(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_arith(0x0B, 0xC0, src1, src2); } @@ -4519,9 +4523,10 @@ void Assembler::orl(Register dst, Register src) { void Assembler::eorl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x09, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x0B, 0xC0, src1, src2); } void Assembler::orl(Address dst, Register src) { @@ -6938,7 +6943,9 @@ void Assembler::shldl(Register dst, Register src) { void Assembler::eshldl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int16(0xA5, (0xC0 | encode)); } @@ -6949,7 +6956,9 @@ void Assembler::shldl(Register dst, Register src, int8_t imm8) { void Assembler::eshldl(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int24(0x24, (0xC0 | encode), imm8); } @@ -6960,7 +6969,9 @@ void Assembler::shrdl(Register dst, Register src) { void Assembler::eshrdl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int16(0xAD, (0xC0 | encode)); } @@ -6971,7 +6982,9 @@ void Assembler::shrdl(Register dst, Register src, int8_t imm8) { void Assembler::eshrdl(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int24(0x2C, (0xC0 | encode), imm8); } @@ -6983,7 +6996,9 @@ void Assembler::shldq(Register dst, Register src, int8_t imm8) { void Assembler::eshldq(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int24(0x24, (0xC0 | encode), imm8); } @@ -6994,7 +7009,9 @@ void Assembler::shrdq(Register dst, Register src, int8_t imm8) { void Assembler::eshrdq(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int24(0x2C, (0xC0 | encode), imm8); } #endif @@ -7155,11 +7172,12 @@ void Assembler::subl(Register dst, Register src) { emit_arith(0x2B, 0xC0, dst, src); } -void Assembler::esubl(Register dst, Register src2, Register src1, bool no_flags) { +void Assembler::esubl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x29, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x2B, 0xC0, src1, src2); } void Assembler::subsd(XMMRegister dst, XMMRegister src) { @@ -7485,9 +7503,10 @@ void Assembler::xorl(Register dst, Register src) { void Assembler::exorl(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x31, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x33, 0xC0, src1, src2); } void Assembler::xorl(Address dst, Register src) { @@ -7548,10 +7567,11 @@ void Assembler::xorw(Register dst, Address src) { void Assembler::exorw(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - emit_int8(0x66); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C, &attributes, no_flags); + attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_16bit); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_66, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); emit_int8(0x33); emit_operand(src1, src2, 0); } @@ -15064,9 +15084,10 @@ void Assembler::addq(Register dst, Register src) { void Assembler::eaddq(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x01, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x03, 0xC0, src1, src2); } void Assembler::adcxq(Register dst, Register src) { @@ -15160,9 +15181,10 @@ void Assembler::andq(Register dst, Register src) { void Assembler::eandq(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x21, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x23, 0xC0, src1, src2); } void Assembler::andq(Address dst, Register src) { @@ -15591,7 +15613,7 @@ void Assembler::imulq(Register dst, Register src, int value) { void Assembler::eimulq(Register dst, Register src, int value, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, /* src_is_gpr */ true, /* nds_is_ndd */ false, no_flags); + int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); if (is8bit(value)) { emit_int24(0x6B, (0xC0 | encode), (value & 0xFF)); } else { @@ -15610,7 +15632,9 @@ void Assembler::imulq(Register dst, Address src) { void Assembler::eimulq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes, /* nds_is_ndd */ false, no_flags); + attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); + evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_int8((unsigned char)0xAF); emit_operand(dst, src, 0); } @@ -16055,9 +16079,10 @@ void Assembler::orq(Register dst, Register src) { void Assembler::eorq(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x09, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x0B, 0xC0, src1, src2); } void Assembler::popcntq(Register dst, Address src) { @@ -16743,9 +16768,10 @@ void Assembler::subq(Register dst, Register src) { void Assembler::esubq(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x29, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x2B, 0xC0, src1, src2); } void Assembler::testq(Address dst, int32_t imm32) { @@ -16807,9 +16833,10 @@ void Assembler::xorq(Register dst, Register src) { void Assembler::exorq(Register dst, Register src1, Register src2, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - // opcode matches gcc - emit_arith(0x31, 0xC0, src1, src2); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + emit_arith(0x33, 0xC0, src1, src2); } void Assembler::xorq(Register dst, Address src) {