1696 // Check for 8-bit immediate, and set sign extend bit in opcode 1697 int con = (int)$imm$$constant; // Throw away top bits 1698 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1699 // Emit r/m byte with secondary opcode, after primary opcode. 1700 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1701 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1702 else emit_d32(cbuf,con); 1703 %} 1704 1705 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{ 1706 // Emit primary opcode and set sign-extend bit 1707 // Check for 8-bit immediate, and set sign extend bit in opcode 1708 int con = (int)($imm$$constant >> 32); // Throw away bottom bits 1709 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1710 // Emit r/m byte with tertiary opcode, after primary opcode. 1711 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg)); 1712 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1713 else emit_d32(cbuf,con); 1714 %} 1715 1716 enc_class Lbl (label labl) %{ // JMP, CALL 1717 Label *l = $labl$$label; 1718 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0); 1719 %} 1720 1721 enc_class LblShort (label labl) %{ // JMP, CALL 1722 Label *l = $labl$$label; 1723 int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0; 1724 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 1725 emit_d8(cbuf, disp); 1726 %} 1727 1728 enc_class OpcSReg (eRegI dst) %{ // BSWAP 1729 emit_cc(cbuf, $secondary, $dst$$reg ); 1730 %} 1731 1732 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP 1733 int destlo = $dst$$reg; 1734 int desthi = HIGH_FROM_LOW(destlo); 1735 // bswap lo 1736 emit_opcode(cbuf, 0x0F); 1737 emit_cc(cbuf, 0xC8, destlo); 1738 // bswap hi 1739 emit_opcode(cbuf, 0x0F); 1740 emit_cc(cbuf, 0xC8, desthi); 1741 // xchg lo and hi 1742 emit_opcode(cbuf, 0x87); 1743 emit_rm(cbuf, 0x3, destlo, desthi); 1744 %} 1745 1746 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ... 1747 emit_rm(cbuf, 0x3, $secondary, $div$$reg ); 1748 %} 1749 1750 enc_class Jcc (cmpOp cop, label labl) %{ // JCC 1751 Label *l = $labl$$label; 1752 $$$emit8$primary; 1753 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1754 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0); 1755 %} 1756 1757 enc_class JccShort (cmpOp cop, label labl) %{ // JCC 1758 Label *l = $labl$$label; 1759 emit_cc(cbuf, $primary, $cop$$cmpcode); 1760 int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0; 1761 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 1762 emit_d8(cbuf, disp); 1763 %} 1764 1765 enc_class enc_cmov(cmpOp cop ) %{ // CMOV 1766 $$$emit8$primary; 1767 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1768 %} 1769 1770 enc_class enc_cmov_d(cmpOp cop, regD src ) %{ // CMOV 1771 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1); 1772 emit_d8(cbuf, op >> 8 ); 1773 emit_d8(cbuf, op & 255); 1774 %} 1775 1776 // emulate a CMOV with a conditional branch around a MOV 1777 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV 1778 // Invert sense of branch from sense of CMOV 1779 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) ); 1780 emit_d8( cbuf, $brOffs$$constant ); 13155 format %{ $$template 13156 if ($cop$$cmpcode == Assembler::notEqual) { 13157 $$emit$$"JP,u $labl\n\t" 13158 $$emit$$"J$cop,u $labl" 13159 } else { 13160 $$emit$$"JP,u done\n\t" 13161 $$emit$$"J$cop,u $labl\n\t" 13162 $$emit$$"done:" 13163 } 13164 %} 13165 size(12); 13166 opcode(0x0F, 0x80); 13167 ins_encode %{ 13168 Label* l = $labl$$label; 13169 $$$emit8$primary; 13170 emit_cc(cbuf, $secondary, Assembler::parity); 13171 int parity_disp = -1; 13172 bool ok = false; 13173 if ($cop$$cmpcode == Assembler::notEqual) { 13174 // the two jumps 6 bytes apart so the jump distances are too 13175 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 13176 } else if ($cop$$cmpcode == Assembler::equal) { 13177 parity_disp = 6; 13178 ok = true; 13179 } else { 13180 ShouldNotReachHere(); 13181 } 13182 emit_d32(cbuf, parity_disp); 13183 $$$emit8$primary; 13184 emit_cc(cbuf, $secondary, $cop$$cmpcode); 13185 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 13186 emit_d32(cbuf, disp); 13187 %} 13188 ins_pipe(pipe_jcc); 13189 ins_pc_relative(1); 13190 %} 13191 13192 // ============================================================================ 13193 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 13194 // array for an instance of the superklass. Set a hidden internal cache on a 13195 // hit (cache is checked with exposed code in gen_subtype_check()). Return 13196 // NZ for a miss or zero for a hit. The encoding ALSO sets flags. 13197 instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ 13198 match(Set result (PartialSubtypeCheck sub super)); 13199 effect( KILL rcx, KILL cr ); 13200 13201 ins_cost(1100); // slightly larger than the next version 13202 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 13203 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 13204 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 13205 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 13351 effect(USE labl); 13352 13353 ins_cost(300); 13354 format %{ $$template 13355 if ($cop$$cmpcode == Assembler::notEqual) { 13356 $$emit$$"JP,u,s $labl\n\t" 13357 $$emit$$"J$cop,u,s $labl" 13358 } else { 13359 $$emit$$"JP,u,s done\n\t" 13360 $$emit$$"J$cop,u,s $labl\n\t" 13361 $$emit$$"done:" 13362 } 13363 %} 13364 size(4); 13365 opcode(0x70); 13366 ins_encode %{ 13367 Label* l = $labl$$label; 13368 emit_cc(cbuf, $primary, Assembler::parity); 13369 int parity_disp = -1; 13370 if ($cop$$cmpcode == Assembler::notEqual) { 13371 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 13372 } else if ($cop$$cmpcode == Assembler::equal) { 13373 parity_disp = 2; 13374 } else { 13375 ShouldNotReachHere(); 13376 } 13377 emit_d8(cbuf, parity_disp); 13378 emit_cc(cbuf, $primary, $cop$$cmpcode); 13379 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 13380 emit_d8(cbuf, disp); 13381 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 13382 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 13383 %} 13384 ins_pipe(pipe_jcc); 13385 ins_pc_relative(1); 13386 ins_short_branch(1); 13387 %} 13388 13389 // ============================================================================ 13390 // Long Compare 13391 // 13392 // Currently we hold longs in 2 registers. Comparing such values efficiently 13393 // is tricky. The flavor of compare used depends on whether we are testing 13394 // for LT, LE, or EQ. For a simple LT test we can check just the sign bit. 13395 // The GE test is the negated LT test. The LE test can be had by commuting 13396 // the operands (yielding a GE test) and then negating; negate again for the 13397 // GT test. The EQ test is done by ORcc'ing the high and low halves, and the 13398 // NE test is negated from that. 13399 | 1696 // Check for 8-bit immediate, and set sign extend bit in opcode 1697 int con = (int)$imm$$constant; // Throw away top bits 1698 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1699 // Emit r/m byte with secondary opcode, after primary opcode. 1700 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1701 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1702 else emit_d32(cbuf,con); 1703 %} 1704 1705 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{ 1706 // Emit primary opcode and set sign-extend bit 1707 // Check for 8-bit immediate, and set sign extend bit in opcode 1708 int con = (int)($imm$$constant >> 32); // Throw away bottom bits 1709 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1710 // Emit r/m byte with tertiary opcode, after primary opcode. 1711 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg)); 1712 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1713 else emit_d32(cbuf,con); 1714 %} 1715 1716 enc_class Lbl (label labl) %{ // GOTO 1717 Label *l = $labl$$label; 1718 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4))); 1719 %} 1720 1721 enc_class LblShort (label labl) %{ // GOTO 1722 Label *l = $labl$$label; 1723 int disp = l->loc_pos() - (cbuf.insts_size()+1); 1724 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 1725 emit_d8(cbuf, disp); 1726 %} 1727 1728 enc_class OpcSReg (eRegI dst) %{ // BSWAP 1729 emit_cc(cbuf, $secondary, $dst$$reg ); 1730 %} 1731 1732 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP 1733 int destlo = $dst$$reg; 1734 int desthi = HIGH_FROM_LOW(destlo); 1735 // bswap lo 1736 emit_opcode(cbuf, 0x0F); 1737 emit_cc(cbuf, 0xC8, destlo); 1738 // bswap hi 1739 emit_opcode(cbuf, 0x0F); 1740 emit_cc(cbuf, 0xC8, desthi); 1741 // xchg lo and hi 1742 emit_opcode(cbuf, 0x87); 1743 emit_rm(cbuf, 0x3, destlo, desthi); 1744 %} 1745 1746 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ... 1747 emit_rm(cbuf, 0x3, $secondary, $div$$reg ); 1748 %} 1749 1750 enc_class Jcc (cmpOp cop, label labl) %{ // JCC 1751 Label *l = $labl$$label; 1752 $$$emit8$primary; 1753 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1754 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4))); 1755 %} 1756 1757 enc_class JccShort (cmpOp cop, label labl) %{ // JCC 1758 Label *l = $labl$$label; 1759 emit_cc(cbuf, $primary, $cop$$cmpcode); 1760 int disp = l->loc_pos() - (cbuf.insts_size()+1); 1761 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 1762 emit_d8(cbuf, disp); 1763 %} 1764 1765 enc_class enc_cmov(cmpOp cop ) %{ // CMOV 1766 $$$emit8$primary; 1767 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1768 %} 1769 1770 enc_class enc_cmov_d(cmpOp cop, regD src ) %{ // CMOV 1771 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1); 1772 emit_d8(cbuf, op >> 8 ); 1773 emit_d8(cbuf, op & 255); 1774 %} 1775 1776 // emulate a CMOV with a conditional branch around a MOV 1777 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV 1778 // Invert sense of branch from sense of CMOV 1779 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) ); 1780 emit_d8( cbuf, $brOffs$$constant ); 13155 format %{ $$template 13156 if ($cop$$cmpcode == Assembler::notEqual) { 13157 $$emit$$"JP,u $labl\n\t" 13158 $$emit$$"J$cop,u $labl" 13159 } else { 13160 $$emit$$"JP,u done\n\t" 13161 $$emit$$"J$cop,u $labl\n\t" 13162 $$emit$$"done:" 13163 } 13164 %} 13165 size(12); 13166 opcode(0x0F, 0x80); 13167 ins_encode %{ 13168 Label* l = $labl$$label; 13169 $$$emit8$primary; 13170 emit_cc(cbuf, $secondary, Assembler::parity); 13171 int parity_disp = -1; 13172 bool ok = false; 13173 if ($cop$$cmpcode == Assembler::notEqual) { 13174 // the two jumps 6 bytes apart so the jump distances are too 13175 parity_disp = l->loc_pos() - (cbuf.insts_size() + 4); 13176 } else if ($cop$$cmpcode == Assembler::equal) { 13177 parity_disp = 6; 13178 ok = true; 13179 } else { 13180 ShouldNotReachHere(); 13181 } 13182 emit_d32(cbuf, parity_disp); 13183 $$$emit8$primary; 13184 emit_cc(cbuf, $secondary, $cop$$cmpcode); 13185 int disp = l->loc_pos() - (cbuf.insts_size() + 4); 13186 emit_d32(cbuf, disp); 13187 %} 13188 ins_pipe(pipe_jcc); 13189 ins_pc_relative(1); 13190 %} 13191 13192 // ============================================================================ 13193 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 13194 // array for an instance of the superklass. Set a hidden internal cache on a 13195 // hit (cache is checked with exposed code in gen_subtype_check()). Return 13196 // NZ for a miss or zero for a hit. The encoding ALSO sets flags. 13197 instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ 13198 match(Set result (PartialSubtypeCheck sub super)); 13199 effect( KILL rcx, KILL cr ); 13200 13201 ins_cost(1100); // slightly larger than the next version 13202 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 13203 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 13204 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 13205 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 13351 effect(USE labl); 13352 13353 ins_cost(300); 13354 format %{ $$template 13355 if ($cop$$cmpcode == Assembler::notEqual) { 13356 $$emit$$"JP,u,s $labl\n\t" 13357 $$emit$$"J$cop,u,s $labl" 13358 } else { 13359 $$emit$$"JP,u,s done\n\t" 13360 $$emit$$"J$cop,u,s $labl\n\t" 13361 $$emit$$"done:" 13362 } 13363 %} 13364 size(4); 13365 opcode(0x70); 13366 ins_encode %{ 13367 Label* l = $labl$$label; 13368 emit_cc(cbuf, $primary, Assembler::parity); 13369 int parity_disp = -1; 13370 if ($cop$$cmpcode == Assembler::notEqual) { 13371 parity_disp = l->loc_pos() - (cbuf.insts_size() + 1); 13372 } else if ($cop$$cmpcode == Assembler::equal) { 13373 parity_disp = 2; 13374 } else { 13375 ShouldNotReachHere(); 13376 } 13377 emit_d8(cbuf, parity_disp); 13378 emit_cc(cbuf, $primary, $cop$$cmpcode); 13379 int disp = l->loc_pos() - (cbuf.insts_size() + 1); 13380 emit_d8(cbuf, disp); 13381 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 13382 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 13383 %} 13384 ins_pipe(pipe_jcc); 13385 ins_pc_relative(1); 13386 ins_short_branch(1); 13387 %} 13388 13389 // ============================================================================ 13390 // Long Compare 13391 // 13392 // Currently we hold longs in 2 registers. Comparing such values efficiently 13393 // is tricky. The flavor of compare used depends on whether we are testing 13394 // for LT, LE, or EQ. For a simple LT test we can check just the sign bit. 13395 // The GE test is the negated LT test. The LE test can be had by commuting 13396 // the operands (yielding a GE test) and then negating; negate again for the 13397 // GT test. The EQ test is done by ORcc'ing the high and low halves, and the 13398 // NE test is negated from that. 13399 |