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