src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7063628 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/x86_32.ad

Print this page




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 


src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File