@@ -332,6 +332,21 @@ void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
332332 }
333333}
334334
335+ void Assembler::emit_arith_ndd(int op1, int op2, Register dst, int32_t imm32) {
336+ assert(isByte(op1) && isByte(op2), "wrong opcode");
337+ assert(op1 == 0x81, "Unexpected opcode");
338+ // This code cache friendly optimization saves 3 bytes per encoding, which offsets the EVEX encoding penalty.
339+ if (is8bit(imm32)) {
340+ emit_int24(op1 | 0x02, // set sign bit
341+ op2 | encode(dst),
342+ imm32 & 0xFF);
343+ }
344+ else {
345+ emit_int16(op1, (op2 | encode(dst)));
346+ emit_int32(imm32);
347+ }
348+ }
349+
335350// Force generation of a 4 byte immediate value even if it fits into 8bit
336351void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
337352 assert(isByte(op1) && isByte(op2), "wrong opcode");
@@ -1461,7 +1476,7 @@ void Assembler::addl(Register dst, int32_t imm32) {
14611476void Assembler::eaddl(Register dst, Register src, int32_t imm32, bool no_flags) {
14621477 InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
14631478 (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
1464- emit_arith (0x81, 0xC0, src, imm32);
1479+ emit_arith_ndd (0x81, 0xC0, src, imm32);
14651480}
14661481
14671482void Assembler::addl(Register dst, Address src) {
@@ -1695,7 +1710,7 @@ void Assembler::andl(Register dst, int32_t imm32) {
16951710void Assembler::eandl(Register dst, Register src, int32_t imm32, bool no_flags) {
16961711 InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
16971712 (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
1698- emit_arith (0x81, 0xE0, src, imm32);
1713+ emit_arith_ndd (0x81, 0xE0, src, imm32);
16991714}
17001715
17011716void Assembler::andl(Address dst, Register src) {
@@ -4532,7 +4547,7 @@ void Assembler::orl(Register dst, int32_t imm32) {
45324547void Assembler::eorl(Register dst, Register src, int32_t imm32, bool no_flags) {
45334548 InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
45344549 evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
4535- emit_arith (0x81, 0xC8, src, imm32);
4550+ emit_arith_ndd (0x81, 0xC8, src, imm32);
45364551}
45374552
45384553void Assembler::orl(Register dst, Address src) {
@@ -7171,7 +7186,7 @@ void Assembler::subl(Register dst, int32_t imm32) {
71717186void Assembler::esubl(Register dst, Register src, int32_t imm32, bool no_flags) {
71727187 InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
71737188 (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
7174- emit_arith (0x81, 0xE8, src, imm32);
7189+ emit_arith_ndd (0x81, 0xE8, src, imm32);
71757190}
71767191
71777192// Force generation of a 4 byte immediate value even if it fits into 8bit
@@ -7512,7 +7527,7 @@ void Assembler::xorl(Register dst, int32_t imm32) {
75127527void Assembler::exorl(Register dst, Register src, int32_t imm32, bool no_flags) {
75137528 InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
75147529 evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
7515- emit_arith (0x81, 0xF0, src, imm32);
7530+ emit_arith_ndd (0x81, 0xF0, src, imm32);
75167531}
75177532
75187533void Assembler::xorl(Register dst, Address src) {
@@ -15158,7 +15173,7 @@ void Assembler::addq(Register dst, int32_t imm32) {
1515815173void Assembler::eaddq(Register dst, Register src, int32_t imm32, bool no_flags) {
1515915174 InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1516015175 (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
15161- emit_arith (0x81, 0xC0, src, imm32);
15176+ emit_arith_ndd (0x81, 0xC0, src, imm32);
1516215177}
1516315178
1516415179void Assembler::addq(Register dst, Address src) {
@@ -15255,7 +15270,7 @@ void Assembler::andq(Register dst, int32_t imm32) {
1525515270void Assembler::eandq(Register dst, Register src, int32_t imm32, bool no_flags) {
1525615271 InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1525715272 evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
15258- emit_arith (0x81, 0xE0, src, imm32);
15273+ emit_arith_ndd (0x81, 0xE0, src, imm32);
1525915274}
1526015275
1526115276void Assembler::andq(Register dst, Address src) {
@@ -16142,7 +16157,7 @@ void Assembler::orq(Register dst, int32_t imm32) {
1614216157void Assembler::eorq(Register dst, Register src, int32_t imm32, bool no_flags) {
1614316158 InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1614416159 evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
16145- emit_arith (0x81, 0xC8, src, imm32);
16160+ emit_arith_ndd (0x81, 0xC8, src, imm32);
1614616161}
1614716162
1614816163void Assembler::orq_imm32(Register dst, int32_t imm32) {
@@ -16830,7 +16845,7 @@ void Assembler::subq(Register dst, int32_t imm32) {
1683016845void Assembler::esubq(Register dst, Register src, int32_t imm32, bool no_flags) {
1683116846 InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1683216847 (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
16833- emit_arith (0x81, 0xE8, src, imm32);
16848+ emit_arith_ndd (0x81, 0xE8, src, imm32);
1683416849}
1683516850
1683616851// Force generation of a 4 byte immediate value even if it fits into 8bit
@@ -16961,7 +16976,7 @@ void Assembler::xorq(Register dst, int32_t imm32) {
1696116976void Assembler::exorq(Register dst, Register src, int32_t imm32, bool no_flags) {
1696216977 InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1696316978 evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags);
16964- emit_arith (0x81, 0xF0, src, imm32);
16979+ emit_arith_ndd (0x81, 0xF0, src, imm32);
1696516980}
1696616981
1696716982void Assembler::xorq(Address dst, int32_t imm32) {
0 commit comments