@@ -300,12 +300,24 @@ void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
300300
301301void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
302302 assert(isByte(op1) && isByte(op2), "wrong opcode");
303- assert((op1 & 0x01) == 1, "should be 32bit operation");
304- assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
303+ assert(op1 == 0x81, "Unexpected opcode");
305304 if (is8bit(imm32)) {
306305 emit_int24(op1 | 0x02, // set sign bit
307306 op2 | encode(dst),
308307 imm32 & 0xFF);
308+ } else if (dst == rax) {
309+ switch (op2) {
310+ case 0xD0: emit_int8(0x15); break; // adc
311+ case 0xC0: emit_int8(0x05); break; // add
312+ case 0xE0: emit_int8(0x25); break; // and
313+ case 0xF8: emit_int8(0x3D); break; // cmp
314+ case 0xC8: emit_int8(0x0D); break; // or
315+ case 0xD8: emit_int8(0x1D); break; // sbb
316+ case 0xE8: emit_int8(0x2D); break; // sub
317+ case 0xF0: emit_int8(0x35); break; // xor
318+ default: ShouldNotReachHere();
319+ }
320+ emit_int32(imm32);
309321 } else {
310322 emit_int16(op1, (op2 | encode(dst)));
311323 emit_int32(imm32);
@@ -929,6 +941,16 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
929941 tail_size = 1;
930942 break;
931943
944+ case 0x15: // adc rax, #32
945+ case 0x05: // add rax, #32
946+ case 0x25: // and rax, #32
947+ case 0x3D: // cmp rax, #32
948+ case 0x0D: // or rax, #32
949+ case 0x1D: // sbb rax, #32
950+ case 0x2D: // sub rax, #32
951+ case 0x35: // xor rax, #32
952+ return which == end_pc_operand ? ip + 4 : ip;
953+
932954 case 0x9B:
933955 switch (0xFF & *ip++) {
934956 case 0xD9: // fnstcw a
@@ -954,6 +976,11 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
954976 debug_only(has_disp32 = true); // has both kinds of operands!
955977 break;
956978
979+ case 0xA8: // testb rax, #8
980+ return which == end_pc_operand ? ip + 1 : ip;
981+ case 0xA9: // testl/testq rax, #32
982+ return which == end_pc_operand ? ip + 4 : ip;
983+
957984 case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8
958985 case 0xC6: // movb a, #8
959986 case 0x80: // cmpb a, #8
@@ -1683,12 +1710,6 @@ void Assembler::cmpl(Address dst, int32_t imm32) {
16831710 emit_int32(imm32);
16841711}
16851712
1686- void Assembler::cmp(Register dst, int32_t imm32) {
1687- prefix(dst);
1688- emit_int8((unsigned char)0x3D);
1689- emit_int32(imm32);
1690- }
1691-
16921713void Assembler::cmpl(Register dst, int32_t imm32) {
16931714 prefix(dst);
16941715 emit_arith(0x81, 0xF8, dst, imm32);
@@ -5775,8 +5796,13 @@ void Assembler::subss(XMMRegister dst, Address src) {
57755796
57765797void Assembler::testb(Register dst, int imm8) {
57775798 NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
5778- (void) prefix_and_encode(dst->encoding(), true);
5779- emit_arith_b(0xF6, 0xC0, dst, imm8);
5799+ if (dst == rax) {
5800+ emit_int8((unsigned char)0xA8);
5801+ emit_int8(imm8);
5802+ } else {
5803+ (void) prefix_and_encode(dst->encoding(), true);
5804+ emit_arith_b(0xF6, 0xC0, dst, imm8);
5805+ }
57805806}
57815807
57825808void Assembler::testb(Address dst, int imm8) {
@@ -5787,14 +5813,34 @@ void Assembler::testb(Address dst, int imm8) {
57875813 emit_int8(imm8);
57885814}
57895815
5816+ void Assembler::testl(Address dst, int32_t imm32) {
5817+ if (imm32 >= 0 && is8bit(imm32)) {
5818+ testb(dst, imm32);
5819+ return;
5820+ }
5821+ InstructionMark im(this);
5822+ emit_int8((unsigned char)0xF7);
5823+ emit_operand(as_Register(0), dst);
5824+ emit_int32(imm32);
5825+ }
5826+
57905827void Assembler::testl(Register dst, int32_t imm32) {
5828+ if (imm32 >= 0 && is8bit(imm32) && dst->has_byte_register()) {
5829+ testb(dst, imm32);
5830+ return;
5831+ }
57915832 // not using emit_arith because test
57925833 // doesn't support sign-extension of
57935834 // 8bit operands
5794- int encode = dst->encoding();
5795- encode = prefix_and_encode(encode);
5796- emit_int16((unsigned char)0xF7, (0xC0 | encode));
5797- emit_int32(imm32);
5835+ if (dst == rax) {
5836+ emit_int8((unsigned char)0xA9);
5837+ emit_int32(imm32);
5838+ } else {
5839+ int encode = dst->encoding();
5840+ encode = prefix_and_encode(encode);
5841+ emit_int16((unsigned char)0xF7, (0xC0 | encode));
5842+ emit_int32(imm32);
5843+ }
57985844}
57995845
58005846void Assembler::testl(Register dst, Register src) {
@@ -13013,20 +13059,34 @@ void Assembler::subq(Register dst, Register src) {
1301313059}
1301413060
1301513061void Assembler::testq(Address dst, int32_t imm32) {
13062+ if (imm32 >= 0) {
13063+ testl(dst, imm32);
13064+ return;
13065+ }
1301613066 InstructionMark im(this);
1301713067 emit_int16(get_prefixq(dst), (unsigned char)0xF7);
1301813068 emit_operand(as_Register(0), dst);
1301913069 emit_int32(imm32);
1302013070}
1302113071
1302213072void Assembler::testq(Register dst, int32_t imm32) {
13073+ if (imm32 >= 0) {
13074+ testl(dst, imm32);
13075+ return;
13076+ }
1302313077 // not using emit_arith because test
1302413078 // doesn't support sign-extension of
1302513079 // 8bit operands
13026- int encode = dst->encoding();
13027- encode = prefixq_and_encode(encode);
13028- emit_int16((unsigned char)0xF7, (0xC0 | encode));
13029- emit_int32(imm32);
13080+ if (dst == rax) {
13081+ prefix(REX_W);
13082+ emit_int8((unsigned char)0xA9);
13083+ emit_int32(imm32);
13084+ } else {
13085+ int encode = dst->encoding();
13086+ encode = prefixq_and_encode(encode);
13087+ emit_int16((unsigned char)0xF7, (0xC0 | encode));
13088+ emit_int32(imm32);
13089+ }
1303013090}
1303113091
1303213092void Assembler::testq(Register dst, Register src) {
0 commit comments