535 XMM9, XMM9_H,
536 XMM10, XMM10_H,
537 XMM11, XMM11_H,
538 XMM12, XMM12_H,
539 XMM13, XMM13_H,
540 XMM14, XMM14_H,
541 XMM15, XMM15_H);
542 %}
543
544
545 //----------SOURCE BLOCK-------------------------------------------------------
546 // This is a block of C++ code which provides values, functions, and
547 // definitions necessary in the rest of the architecture description
548 source %{
549 #define RELOC_IMM64 Assembler::imm_operand
550 #define RELOC_DISP32 Assembler::disp32_operand
551
552 #define __ _masm.
553
554 static int preserve_SP_size() {
555 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
556 }
557
558 // !!!!! Special hack to get all types of calls to specify the byte offset
559 // from the start of the call to the point where the return address
560 // will point.
561 int MachCallStaticJavaNode::ret_addr_offset()
562 {
563 int offset = 5; // 5 bytes from start of call to where return address points
564 if (_method_handle_invoke)
565 offset += preserve_SP_size();
566 return offset;
567 }
568
569 int MachCallDynamicJavaNode::ret_addr_offset()
570 {
571 return 15; // 15 bytes from start of call to where return address points
572 }
573
574 // In os_cpu .ad file
575 // int MachCallRuntimeNode::ret_addr_offset()
780 emit_d8(cbuf, disp);
781 } else {
782 // If 32-bit displacement
783 if (base == 0x04 ) {
784 emit_rm(cbuf, 0x2, regenc, 0x4);
785 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
786 } else {
787 emit_rm(cbuf, 0x2, regenc, 0x4);
788 emit_rm(cbuf, scale, indexenc, baseenc); // *
789 }
790 if (disp_is_oop) {
791 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
792 } else {
793 emit_d32(cbuf, disp);
794 }
795 }
796 }
797 }
798 }
799
800 void encode_copy(CodeBuffer &cbuf, int dstenc, int srcenc)
801 {
802 if (dstenc != srcenc) {
803 if (dstenc < 8) {
804 if (srcenc >= 8) {
805 emit_opcode(cbuf, Assembler::REX_B);
806 srcenc -= 8;
807 }
808 } else {
809 if (srcenc < 8) {
810 emit_opcode(cbuf, Assembler::REX_R);
811 } else {
812 emit_opcode(cbuf, Assembler::REX_RB);
813 srcenc -= 8;
814 }
815 dstenc -= 8;
816 }
817
818 emit_opcode(cbuf, 0x8B);
819 emit_rm(cbuf, 0x3, dstenc, srcenc);
820 }
821 }
822
823 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
824 if( dst_encoding == src_encoding ) {
825 // reg-reg copy, use an empty encoding
826 } else {
827 MacroAssembler _masm(&cbuf);
828
829 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
830 }
831 }
832
833 // This could be in MacroAssembler but it's fairly C2 specific
834 void emit_cmpfp_fixup(MacroAssembler& _masm) {
835 Label exit;
836 __ jccb(Assembler::noParity, exit);
837 __ pushf();
838 __ andq(Address(rsp, 0), 0xffffff2b);
839 __ popf();
840 __ bind(exit);
841 __ nop(); // (target for branch to avoid branch to branch)
842 }
843
844
845 //=============================================================================
846 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
847
848 int Compile::ConstantTable::calculate_table_base_offset() const {
849 return 0; // absolute addressing, no offset
850 }
851
852 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
853 // Empty encoding
854 }
855
856 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
857 return 0;
858 }
859
860 #ifndef PRODUCT
861 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
862 st->print("# MachConstantBaseNode (empty encoding)");
863 }
864 #endif
1257 #ifndef PRODUCT
1258 } else if (!do_size) {
1259 st->print("movl %s, [rsp + #%d]\t# spill",
1260 Matcher::regName[dst_first],
1261 offset);
1262 #endif
1263 }
1264 return
1265 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1266 ((Matcher::_regEncode[dst_first] < 8)
1267 ? 3
1268 : 4); // REX
1269 }
1270 } else if (dst_first_rc == rc_float) {
1271 // mem-> xmm
1272 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1273 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1274 // 64-bit
1275 int offset = ra_->reg2offset(src_first);
1276 if (cbuf) {
1277 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
1278 if (Matcher::_regEncode[dst_first] >= 8) {
1279 emit_opcode(*cbuf, Assembler::REX_R);
1280 }
1281 emit_opcode(*cbuf, 0x0F);
1282 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
1283 encode_RegMem(*cbuf,
1284 Matcher::_regEncode[dst_first],
1285 RSP_enc, 0x4, 0, offset,
1286 false);
1287 #ifndef PRODUCT
1288 } else if (!do_size) {
1289 st->print("%s %s, [rsp + #%d]\t# spill",
1290 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1291 Matcher::regName[dst_first],
1292 offset);
1293 #endif
1294 }
1295 return
1296 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1297 ((Matcher::_regEncode[dst_first] < 8)
1298 ? 5
1299 : 6); // REX
1300 } else {
1301 // 32-bit
1302 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1303 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1304 int offset = ra_->reg2offset(src_first);
1305 if (cbuf) {
1306 emit_opcode(*cbuf, 0xF3);
1307 if (Matcher::_regEncode[dst_first] >= 8) {
1308 emit_opcode(*cbuf, Assembler::REX_R);
1309 }
1310 emit_opcode(*cbuf, 0x0F);
1311 emit_opcode(*cbuf, 0x10);
1312 encode_RegMem(*cbuf,
1313 Matcher::_regEncode[dst_first],
1314 RSP_enc, 0x4, 0, offset,
1315 false);
1316 #ifndef PRODUCT
1317 } else if (!do_size) {
1318 st->print("movss %s, [rsp + #%d]\t# spill",
1319 Matcher::regName[dst_first],
1320 offset);
1321 #endif
1322 }
1323 return
1324 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1325 ((Matcher::_regEncode[dst_first] < 8)
1326 ? 5
1327 : 6); // REX
1328 }
1329 }
1330 } else if (src_first_rc == rc_int) {
1331 // gpr ->
1332 if (dst_first_rc == rc_stack) {
1333 // gpr -> mem
1334 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1335 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1336 // 64-bit
1337 int offset = ra_->reg2offset(dst_first);
1338 if (cbuf) {
1339 if (Matcher::_regEncode[src_first] < 8) {
1340 emit_opcode(*cbuf, Assembler::REX_W);
1341 } else {
1342 emit_opcode(*cbuf, Assembler::REX_WR);
1343 }
1344 emit_opcode(*cbuf, 0x89);
1345 encode_RegMem(*cbuf,
1346 Matcher::_regEncode[src_first],
1347 RSP_enc, 0x4, 0, offset,
1433 Matcher::_regEncode[dst_first] & 7,
1434 Matcher::_regEncode[src_first] & 7);
1435 #ifndef PRODUCT
1436 } else if (!do_size) {
1437 st->print("movl %s, %s\t# spill",
1438 Matcher::regName[dst_first],
1439 Matcher::regName[src_first]);
1440 #endif
1441 }
1442 return
1443 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1444 ? 2
1445 : 3; // REX
1446 }
1447 } else if (dst_first_rc == rc_float) {
1448 // gpr -> xmm
1449 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1450 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1451 // 64-bit
1452 if (cbuf) {
1453 emit_opcode(*cbuf, 0x66);
1454 if (Matcher::_regEncode[dst_first] < 8) {
1455 if (Matcher::_regEncode[src_first] < 8) {
1456 emit_opcode(*cbuf, Assembler::REX_W);
1457 } else {
1458 emit_opcode(*cbuf, Assembler::REX_WB);
1459 }
1460 } else {
1461 if (Matcher::_regEncode[src_first] < 8) {
1462 emit_opcode(*cbuf, Assembler::REX_WR);
1463 } else {
1464 emit_opcode(*cbuf, Assembler::REX_WRB);
1465 }
1466 }
1467 emit_opcode(*cbuf, 0x0F);
1468 emit_opcode(*cbuf, 0x6E);
1469 emit_rm(*cbuf, 0x3,
1470 Matcher::_regEncode[dst_first] & 7,
1471 Matcher::_regEncode[src_first] & 7);
1472 #ifndef PRODUCT
1473 } else if (!do_size) {
1474 st->print("movdq %s, %s\t# spill",
1475 Matcher::regName[dst_first],
1476 Matcher::regName[src_first]);
1477 #endif
1478 }
1479 return 5; // REX
1480 } else {
1481 // 32-bit
1482 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1483 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1484 if (cbuf) {
1485 emit_opcode(*cbuf, 0x66);
1486 if (Matcher::_regEncode[dst_first] < 8) {
1487 if (Matcher::_regEncode[src_first] >= 8) {
1488 emit_opcode(*cbuf, Assembler::REX_B);
1489 }
1490 } else {
1491 if (Matcher::_regEncode[src_first] < 8) {
1492 emit_opcode(*cbuf, Assembler::REX_R);
1493 } else {
1494 emit_opcode(*cbuf, Assembler::REX_RB);
1495 }
1496 }
1497 emit_opcode(*cbuf, 0x0F);
1498 emit_opcode(*cbuf, 0x6E);
1499 emit_rm(*cbuf, 0x3,
1500 Matcher::_regEncode[dst_first] & 7,
1501 Matcher::_regEncode[src_first] & 7);
1502 #ifndef PRODUCT
1503 } else if (!do_size) {
1504 st->print("movdl %s, %s\t# spill",
1505 Matcher::regName[dst_first],
1506 Matcher::regName[src_first]);
1507 #endif
1508 }
1509 return
1510 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1511 ? 4
1512 : 5; // REX
1513 }
1514 }
1515 } else if (src_first_rc == rc_float) {
1516 // xmm ->
1517 if (dst_first_rc == rc_stack) {
1518 // xmm -> mem
1519 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1520 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1521 // 64-bit
1522 int offset = ra_->reg2offset(dst_first);
1523 if (cbuf) {
1524 emit_opcode(*cbuf, 0xF2);
1525 if (Matcher::_regEncode[src_first] >= 8) {
1526 emit_opcode(*cbuf, Assembler::REX_R);
1527 }
1528 emit_opcode(*cbuf, 0x0F);
1529 emit_opcode(*cbuf, 0x11);
1530 encode_RegMem(*cbuf,
1531 Matcher::_regEncode[src_first],
1532 RSP_enc, 0x4, 0, offset,
1533 false);
1534 #ifndef PRODUCT
1535 } else if (!do_size) {
1536 st->print("movsd [rsp + #%d], %s\t# spill",
1537 offset,
1538 Matcher::regName[src_first]);
1539 #endif
1540 }
1541 return
1542 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1543 ((Matcher::_regEncode[src_first] < 8)
1544 ? 5
1545 : 6); // REX
1546 } else {
1547 // 32-bit
1548 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1549 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1550 int offset = ra_->reg2offset(dst_first);
1551 if (cbuf) {
1552 emit_opcode(*cbuf, 0xF3);
1553 if (Matcher::_regEncode[src_first] >= 8) {
1554 emit_opcode(*cbuf, Assembler::REX_R);
1555 }
1556 emit_opcode(*cbuf, 0x0F);
1557 emit_opcode(*cbuf, 0x11);
1558 encode_RegMem(*cbuf,
1559 Matcher::_regEncode[src_first],
1560 RSP_enc, 0x4, 0, offset,
1561 false);
1562 #ifndef PRODUCT
1563 } else if (!do_size) {
1564 st->print("movss [rsp + #%d], %s\t# spill",
1565 offset,
1566 Matcher::regName[src_first]);
1567 #endif
1568 }
1569 return
1570 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1571 ((Matcher::_regEncode[src_first] < 8)
1572 ? 5
1573 : 6); // REX
1574 }
1575 } else if (dst_first_rc == rc_int) {
1576 // xmm -> gpr
1577 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1578 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1579 // 64-bit
1580 if (cbuf) {
1581 emit_opcode(*cbuf, 0x66);
1582 if (Matcher::_regEncode[dst_first] < 8) {
1583 if (Matcher::_regEncode[src_first] < 8) {
1584 emit_opcode(*cbuf, Assembler::REX_W);
1585 } else {
1586 emit_opcode(*cbuf, Assembler::REX_WR); // attention!
1587 }
1588 } else {
1589 if (Matcher::_regEncode[src_first] < 8) {
1590 emit_opcode(*cbuf, Assembler::REX_WB); // attention!
1591 } else {
1592 emit_opcode(*cbuf, Assembler::REX_WRB);
1593 }
1594 }
1595 emit_opcode(*cbuf, 0x0F);
1596 emit_opcode(*cbuf, 0x7E);
1597 emit_rm(*cbuf, 0x3,
1598 Matcher::_regEncode[src_first] & 7,
1599 Matcher::_regEncode[dst_first] & 7);
1600 #ifndef PRODUCT
1601 } else if (!do_size) {
1602 st->print("movdq %s, %s\t# spill",
1603 Matcher::regName[dst_first],
1604 Matcher::regName[src_first]);
1605 #endif
1606 }
1607 return 5; // REX
1608 } else {
1609 // 32-bit
1610 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1611 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1612 if (cbuf) {
1613 emit_opcode(*cbuf, 0x66);
1614 if (Matcher::_regEncode[dst_first] < 8) {
1615 if (Matcher::_regEncode[src_first] >= 8) {
1616 emit_opcode(*cbuf, Assembler::REX_R); // attention!
1617 }
1618 } else {
1619 if (Matcher::_regEncode[src_first] < 8) {
1620 emit_opcode(*cbuf, Assembler::REX_B); // attention!
1621 } else {
1622 emit_opcode(*cbuf, Assembler::REX_RB);
1623 }
1624 }
1625 emit_opcode(*cbuf, 0x0F);
1626 emit_opcode(*cbuf, 0x7E);
1627 emit_rm(*cbuf, 0x3,
1628 Matcher::_regEncode[src_first] & 7,
1629 Matcher::_regEncode[dst_first] & 7);
1630 #ifndef PRODUCT
1631 } else if (!do_size) {
1632 st->print("movdl %s, %s\t# spill",
1633 Matcher::regName[dst_first],
1634 Matcher::regName[src_first]);
1635 #endif
1636 }
1637 return
1638 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1639 ? 4
1640 : 5; // REX
1641 }
1642 } else if (dst_first_rc == rc_float) {
1643 // xmm -> xmm
1644 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1645 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1646 // 64-bit
1647 if (cbuf) {
1648 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
1649 if (Matcher::_regEncode[dst_first] < 8) {
1650 if (Matcher::_regEncode[src_first] >= 8) {
1651 emit_opcode(*cbuf, Assembler::REX_B);
1652 }
1653 } else {
1654 if (Matcher::_regEncode[src_first] < 8) {
1655 emit_opcode(*cbuf, Assembler::REX_R);
1656 } else {
1657 emit_opcode(*cbuf, Assembler::REX_RB);
1658 }
1659 }
1660 emit_opcode(*cbuf, 0x0F);
1661 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1662 emit_rm(*cbuf, 0x3,
1663 Matcher::_regEncode[dst_first] & 7,
1664 Matcher::_regEncode[src_first] & 7);
1665 #ifndef PRODUCT
1666 } else if (!do_size) {
1667 st->print("%s %s, %s\t# spill",
1668 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1669 Matcher::regName[dst_first],
1670 Matcher::regName[src_first]);
1671 #endif
1672 }
1673 return
1674 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1675 ? 4
1676 : 5; // REX
1677 } else {
1678 // 32-bit
1679 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1680 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1681 if (cbuf) {
1682 if (!UseXmmRegToRegMoveAll)
1683 emit_opcode(*cbuf, 0xF3);
1684 if (Matcher::_regEncode[dst_first] < 8) {
1685 if (Matcher::_regEncode[src_first] >= 8) {
1686 emit_opcode(*cbuf, Assembler::REX_B);
1687 }
1688 } else {
1689 if (Matcher::_regEncode[src_first] < 8) {
1690 emit_opcode(*cbuf, Assembler::REX_R);
1691 } else {
1692 emit_opcode(*cbuf, Assembler::REX_RB);
1693 }
1694 }
1695 emit_opcode(*cbuf, 0x0F);
1696 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1697 emit_rm(*cbuf, 0x3,
1698 Matcher::_regEncode[dst_first] & 7,
1699 Matcher::_regEncode[src_first] & 7);
1700 #ifndef PRODUCT
1701 } else if (!do_size) {
1702 st->print("%s %s, %s\t# spill",
1703 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1704 Matcher::regName[dst_first],
1705 Matcher::regName[src_first]);
1706 #endif
1707 }
1708 return
1709 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1710 ? (UseXmmRegToRegMoveAll ? 3 : 4)
1711 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX
1712 }
1713 }
1714 }
1715
1716 assert(0," foo ");
1717 Unimplemented();
1718
1719 return 0;
1720 }
1721
1722 #ifndef PRODUCT
1723 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
1724 {
1725 implementation(NULL, ra_, false, st);
1726 }
1727 #endif
1728
1729 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
1730 {
1731 implementation(&cbuf, ra_, false, NULL);
2188 %{
2189 emit_opcode(cbuf, 0x66);
2190 %}
2191
2192 enc_class reg(rRegI reg)
2193 %{
2194 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
2195 %}
2196
2197 enc_class reg_reg(rRegI dst, rRegI src)
2198 %{
2199 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2200 %}
2201
2202 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
2203 %{
2204 emit_opcode(cbuf, $opcode$$constant);
2205 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2206 %}
2207
2208 enc_class cmpfp_fixup() %{
2209 MacroAssembler _masm(&cbuf);
2210 emit_cmpfp_fixup(_masm);
2211 %}
2212
2213 enc_class cmpfp3(rRegI dst)
2214 %{
2215 int dstenc = $dst$$reg;
2216
2217 // movl $dst, -1
2218 if (dstenc >= 8) {
2219 emit_opcode(cbuf, Assembler::REX_B);
2220 }
2221 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2222 emit_d32(cbuf, -1);
2223
2224 // jp,s done
2225 emit_opcode(cbuf, 0x7A);
2226 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A);
2227
2228 // jb,s done
2229 emit_opcode(cbuf, 0x72);
2230 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2231
2232 // setne $dst
2233 if (dstenc >= 4) {
2234 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2235 }
2236 emit_opcode(cbuf, 0x0F);
2237 emit_opcode(cbuf, 0x95);
2238 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2239
2240 // movzbl $dst, $dst
2241 if (dstenc >= 4) {
2242 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2243 }
2244 emit_opcode(cbuf, 0x0F);
2245 emit_opcode(cbuf, 0xB6);
2246 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2247 %}
2248
2249 enc_class cdql_enc(no_rax_rdx_RegI div)
2250 %{
2251 // Full implementation of Java idiv and irem; checks for
2252 // special case as described in JVM spec., p.243 & p.271.
2253 //
2254 // normal case special case
2255 //
2256 // input : rax: dividend min_int
2257 // reg: divisor -1
2258 //
2259 // output: rax: quotient (= rax idiv reg) min_int
2260 // rdx: remainder (= rax irem reg) 0
2261 //
2262 // Code sequnce:
2263 //
2264 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
2265 // 5: 75 07/08 jne e <normal>
2266 // 7: 33 d2 xor %edx,%edx
2267 // [div >= 8 -> offset + 1]
2268 // [REX_B]
2455
2456 enc_class opc3_reg(rRegI dst)
2457 %{
2458 // BSWAP
2459 emit_cc(cbuf, $tertiary, $dst$$reg);
2460 %}
2461
2462 enc_class reg_opc(rRegI div)
2463 %{
2464 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2465 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2466 %}
2467
2468 enc_class enc_cmov(cmpOp cop)
2469 %{
2470 // CMOV
2471 $$$emit8$primary;
2472 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2473 %}
2474
2475 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src)
2476 %{
2477 // Invert sense of branch from sense of cmov
2478 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2479 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8)
2480 ? (UseXmmRegToRegMoveAll ? 3 : 4)
2481 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX
2482 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src)
2483 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3);
2484 if ($dst$$reg < 8) {
2485 if ($src$$reg >= 8) {
2486 emit_opcode(cbuf, Assembler::REX_B);
2487 }
2488 } else {
2489 if ($src$$reg < 8) {
2490 emit_opcode(cbuf, Assembler::REX_R);
2491 } else {
2492 emit_opcode(cbuf, Assembler::REX_RB);
2493 }
2494 }
2495 emit_opcode(cbuf, 0x0F);
2496 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2497 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2498 %}
2499
2500 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src)
2501 %{
2502 // Invert sense of branch from sense of cmov
2503 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2504 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX
2505
2506 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src)
2507 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
2508 if ($dst$$reg < 8) {
2509 if ($src$$reg >= 8) {
2510 emit_opcode(cbuf, Assembler::REX_B);
2511 }
2512 } else {
2513 if ($src$$reg < 8) {
2514 emit_opcode(cbuf, Assembler::REX_R);
2515 } else {
2516 emit_opcode(cbuf, Assembler::REX_RB);
2517 }
2518 }
2519 emit_opcode(cbuf, 0x0F);
2520 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2521 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2522 %}
2523
2524 enc_class enc_PartialSubtypeCheck()
2525 %{
2526 Register Rrdi = as_Register(RDI_enc); // result register
2527 Register Rrax = as_Register(RAX_enc); // super class
2528 Register Rrcx = as_Register(RCX_enc); // killed
2529 Register Rrsi = as_Register(RSI_enc); // sub class
2530 Label miss;
2531 const bool set_cond_codes = true;
2532
2533 MacroAssembler _masm(&cbuf);
2534 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2535 NULL, &miss,
2536 /*set_cond_codes:*/ true);
2537 if ($primary) {
2538 __ xorptr(Rrdi, Rrdi);
2539 }
2540 __ bind(miss);
2541 %}
2542
2543 enc_class Java_To_Interpreter(method meth)
2734 %}
2735
2736 enc_class load_immP(rRegP dst, immP src)
2737 %{
2738 int dstenc = $dst$$reg;
2739 if (dstenc < 8) {
2740 emit_opcode(cbuf, Assembler::REX_W);
2741 } else {
2742 emit_opcode(cbuf, Assembler::REX_WB);
2743 dstenc -= 8;
2744 }
2745 emit_opcode(cbuf, 0xB8 | dstenc);
2746 // This next line should be generated from ADLC
2747 if ($src->constant_is_oop()) {
2748 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2749 } else {
2750 emit_d64(cbuf, $src$$constant);
2751 }
2752 %}
2753
2754 // Encode a reg-reg copy. If it is useless, then empty encoding.
2755 enc_class enc_copy(rRegI dst, rRegI src)
2756 %{
2757 encode_copy(cbuf, $dst$$reg, $src$$reg);
2758 %}
2759
2760 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
2761 enc_class enc_CopyXD( RegD dst, RegD src ) %{
2762 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
2763 %}
2764
2765 enc_class enc_copy_always(rRegI dst, rRegI src)
2766 %{
2767 int srcenc = $src$$reg;
2768 int dstenc = $dst$$reg;
2769
2770 if (dstenc < 8) {
2771 if (srcenc >= 8) {
2772 emit_opcode(cbuf, Assembler::REX_B);
2773 srcenc -= 8;
2774 }
2775 } else {
2776 if (srcenc < 8) {
2777 emit_opcode(cbuf, Assembler::REX_R);
2778 } else {
2779 emit_opcode(cbuf, Assembler::REX_RB);
2780 srcenc -= 8;
2781 }
2782 dstenc -= 8;
2783 }
2784
2785 emit_opcode(cbuf, 0x8B);
2786 emit_rm(cbuf, 0x3, dstenc, srcenc);
2787 %}
2788
2789 enc_class enc_copy_wide(rRegL dst, rRegL src)
2790 %{
2791 int srcenc = $src$$reg;
2792 int dstenc = $dst$$reg;
2793
2794 if (dstenc != srcenc) {
2795 if (dstenc < 8) {
2796 if (srcenc < 8) {
2797 emit_opcode(cbuf, Assembler::REX_W);
2798 } else {
2799 emit_opcode(cbuf, Assembler::REX_WB);
2800 srcenc -= 8;
2801 }
2802 } else {
2803 if (srcenc < 8) {
2804 emit_opcode(cbuf, Assembler::REX_WR);
2805 } else {
2806 emit_opcode(cbuf, Assembler::REX_WRB);
2807 srcenc -= 8;
2808 }
2809 dstenc -= 8;
2810 }
2811 emit_opcode(cbuf, 0x8B);
2812 emit_rm(cbuf, 0x3, dstenc, srcenc);
2813 }
2814 %}
2815
2816 enc_class Con32(immI src)
2817 %{
2818 // Output immediate
2819 $$$emit32$src$$constant;
2820 %}
2821
2822 enc_class Con64(immL src)
2823 %{
2824 // Output immediate
2825 emit_d64($src$$constant);
2826 %}
2827
2828 enc_class Con32F_as_bits(immF src)
2829 %{
2830 // Output Float immediate bits
2831 jfloat jf = $src$$constant;
2832 jint jf_as_bits = jint_cast(jf);
2833 emit_d32(cbuf, jf_as_bits);
2834 %}
2835
3195 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
3196
3197 // setne $dst
3198 if (dstenc >= 4) {
3199 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
3200 }
3201 emit_opcode(cbuf, 0x0F);
3202 emit_opcode(cbuf, 0x95);
3203 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
3204
3205 // movzbl $dst, $dst
3206 if (dstenc >= 4) {
3207 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
3208 }
3209 emit_opcode(cbuf, 0x0F);
3210 emit_opcode(cbuf, 0xB6);
3211 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
3212 %}
3213
3214 enc_class Push_ResultXD(regD dst) %{
3215 int dstenc = $dst$$reg;
3216
3217 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP]
3218
3219 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp]
3220 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
3221 if (dstenc >= 8) {
3222 emit_opcode(cbuf, Assembler::REX_R);
3223 }
3224 emit_opcode (cbuf, 0x0F );
3225 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 );
3226 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false);
3227
3228 // add rsp,8
3229 emit_opcode(cbuf, Assembler::REX_W);
3230 emit_opcode(cbuf,0x83);
3231 emit_rm(cbuf,0x3, 0x0, RSP_enc);
3232 emit_d8(cbuf,0x08);
3233 %}
3234
3235 enc_class Push_SrcXD(regD src) %{
3236 int srcenc = $src$$reg;
3237
3238 // subq rsp,#8
3239 emit_opcode(cbuf, Assembler::REX_W);
3240 emit_opcode(cbuf, 0x83);
3241 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3242 emit_d8(cbuf, 0x8);
3243
3244 // movsd [rsp],src
3245 emit_opcode(cbuf, 0xF2);
3246 if (srcenc >= 8) {
3247 emit_opcode(cbuf, Assembler::REX_R);
3248 }
3249 emit_opcode(cbuf, 0x0F);
3250 emit_opcode(cbuf, 0x11);
3251 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false);
3252
3253 // fldd [rsp]
3254 emit_opcode(cbuf, 0x66);
3255 emit_opcode(cbuf, 0xDD);
3256 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false);
3257 %}
3258
3259
3260 enc_class movq_ld(regD dst, memory mem) %{
3261 MacroAssembler _masm(&cbuf);
3262 __ movq($dst$$XMMRegister, $mem$$Address);
3263 %}
3264
3265 enc_class movq_st(memory mem, regD src) %{
3266 MacroAssembler _masm(&cbuf);
3267 __ movq($mem$$Address, $src$$XMMRegister);
3268 %}
3269
3270 enc_class pshufd_8x8(regF dst, regF src) %{
3271 MacroAssembler _masm(&cbuf);
3272
3273 encode_CopyXD(cbuf, $dst$$reg, $src$$reg);
3274 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg));
3275 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00);
3276 %}
3277
3278 enc_class pshufd_4x16(regF dst, regF src) %{
3279 MacroAssembler _masm(&cbuf);
3280
3281 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00);
3282 %}
3283
3284 enc_class pshufd(regD dst, regD src, int mode) %{
3285 MacroAssembler _masm(&cbuf);
3286
3287 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode);
3288 %}
3289
3290 enc_class pxor(regD dst, regD src) %{
3291 MacroAssembler _masm(&cbuf);
3292
3293 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg));
3294 %}
3295
3296 enc_class mov_i2x(regD dst, rRegI src) %{
3297 MacroAssembler _masm(&cbuf);
3298
3299 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg));
3300 %}
3301
3302 // obj: object to lock
3303 // box: box address (header location) -- killed
3304 // tmp: rax -- killed
3305 // scr: rbx -- killed
3306 //
3307 // What follows is a direct transliteration of fast_lock() and fast_unlock()
3308 // from i486.ad. See that file for comments.
3309 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
3310 // use the shorter encoding. (Movl clears the high-order 32-bits).
3311
3312
3313 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
3314 %{
3315 Register objReg = as_Register((int)$obj$$reg);
3316 Register boxReg = as_Register((int)$box$$reg);
3317 Register tmpReg = as_Register($tmp$$reg);
3318 Register scrReg = as_Register($scr$$reg);
3319 MacroAssembler masm(&cbuf);
3320
3321 // Verify uniqueness of register assignments -- necessary but not sufficient
3517 masm.bind (CheckSucc) ;
3518 }
3519 masm.bind(DONE_LABEL);
3520 if (EmitSync & 32768) {
3521 masm.nop(); // avoid branch to branch
3522 }
3523 }
3524 %}
3525
3526
3527 enc_class enc_rethrow()
3528 %{
3529 cbuf.set_insts_mark();
3530 emit_opcode(cbuf, 0xE9); // jmp entry
3531 emit_d32_reloc(cbuf,
3532 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
3533 runtime_call_Relocation::spec(),
3534 RELOC_DISP32);
3535 %}
3536
3537 enc_class absF_encoding(regF dst)
3538 %{
3539 int dstenc = $dst$$reg;
3540 address signmask_address = (address) StubRoutines::x86::float_sign_mask();
3541
3542 cbuf.set_insts_mark();
3543 if (dstenc >= 8) {
3544 emit_opcode(cbuf, Assembler::REX_R);
3545 dstenc -= 8;
3546 }
3547 // XXX reg_mem doesn't support RIP-relative addressing yet
3548 emit_opcode(cbuf, 0x0F);
3549 emit_opcode(cbuf, 0x54);
3550 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3551 emit_d32_reloc(cbuf, signmask_address);
3552 %}
3553
3554 enc_class absD_encoding(regD dst)
3555 %{
3556 int dstenc = $dst$$reg;
3557 address signmask_address = (address) StubRoutines::x86::double_sign_mask();
3558
3559 cbuf.set_insts_mark();
3560 emit_opcode(cbuf, 0x66);
3561 if (dstenc >= 8) {
3562 emit_opcode(cbuf, Assembler::REX_R);
3563 dstenc -= 8;
3564 }
3565 // XXX reg_mem doesn't support RIP-relative addressing yet
3566 emit_opcode(cbuf, 0x0F);
3567 emit_opcode(cbuf, 0x54);
3568 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3569 emit_d32_reloc(cbuf, signmask_address);
3570 %}
3571
3572 enc_class negF_encoding(regF dst)
3573 %{
3574 int dstenc = $dst$$reg;
3575 address signflip_address = (address) StubRoutines::x86::float_sign_flip();
3576
3577 cbuf.set_insts_mark();
3578 if (dstenc >= 8) {
3579 emit_opcode(cbuf, Assembler::REX_R);
3580 dstenc -= 8;
3581 }
3582 // XXX reg_mem doesn't support RIP-relative addressing yet
3583 emit_opcode(cbuf, 0x0F);
3584 emit_opcode(cbuf, 0x57);
3585 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3586 emit_d32_reloc(cbuf, signflip_address);
3587 %}
3588
3589 enc_class negD_encoding(regD dst)
3590 %{
3591 int dstenc = $dst$$reg;
3592 address signflip_address = (address) StubRoutines::x86::double_sign_flip();
3593
3594 cbuf.set_insts_mark();
3595 emit_opcode(cbuf, 0x66);
3596 if (dstenc >= 8) {
3597 emit_opcode(cbuf, Assembler::REX_R);
3598 dstenc -= 8;
3599 }
3600 // XXX reg_mem doesn't support RIP-relative addressing yet
3601 emit_opcode(cbuf, 0x0F);
3602 emit_opcode(cbuf, 0x57);
3603 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3604 emit_d32_reloc(cbuf, signflip_address);
3605 %}
3606
3607 enc_class f2i_fixup(rRegI dst, regF src)
3608 %{
3609 int dstenc = $dst$$reg;
3610 int srcenc = $src$$reg;
3611
3612 // cmpl $dst, #0x80000000
3613 if (dstenc >= 8) {
3614 emit_opcode(cbuf, Assembler::REX_B);
3615 }
3616 emit_opcode(cbuf, 0x81);
3617 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3618 emit_d32(cbuf, 0x80000000);
3619
3620 // jne,s done
3621 emit_opcode(cbuf, 0x75);
3622 if (srcenc < 8 && dstenc < 8) {
3623 emit_d8(cbuf, 0xF);
3624 } else if (srcenc >= 8 && dstenc >= 8) {
3625 emit_d8(cbuf, 0x11);
3626 } else {
3627 emit_d8(cbuf, 0x10);
3628 }
3629
3630 // subq rsp, #8
3631 emit_opcode(cbuf, Assembler::REX_W);
3632 emit_opcode(cbuf, 0x83);
3633 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3634 emit_d8(cbuf, 8);
3635
3636 // movss [rsp], $src
3637 emit_opcode(cbuf, 0xF3);
3638 if (srcenc >= 8) {
3639 emit_opcode(cbuf, Assembler::REX_R);
3640 }
3641 emit_opcode(cbuf, 0x0F);
3642 emit_opcode(cbuf, 0x11);
3643 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3644
3645 // call f2i_fixup
3646 cbuf.set_insts_mark();
3647 emit_opcode(cbuf, 0xE8);
3648 emit_d32_reloc(cbuf,
3649 (int)
3650 (StubRoutines::x86::f2i_fixup() - cbuf.insts_end() - 4),
3651 runtime_call_Relocation::spec(),
3652 RELOC_DISP32);
3653
3654 // popq $dst
3655 if (dstenc >= 8) {
3656 emit_opcode(cbuf, Assembler::REX_B);
3657 }
3658 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3659
3660 // done:
3661 %}
3662
3663 enc_class f2l_fixup(rRegL dst, regF src)
3664 %{
3665 int dstenc = $dst$$reg;
3666 int srcenc = $src$$reg;
3667 address const_address = (address) StubRoutines::x86::double_sign_flip();
3668
3669 // cmpq $dst, [0x8000000000000000]
3670 cbuf.set_insts_mark();
3671 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3672 emit_opcode(cbuf, 0x39);
3673 // XXX reg_mem doesn't support RIP-relative addressing yet
3674 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3675 emit_d32_reloc(cbuf, const_address);
3676
3677
3678 // jne,s done
3679 emit_opcode(cbuf, 0x75);
3680 if (srcenc < 8 && dstenc < 8) {
3681 emit_d8(cbuf, 0xF);
3682 } else if (srcenc >= 8 && dstenc >= 8) {
3683 emit_d8(cbuf, 0x11);
3684 } else {
3685 emit_d8(cbuf, 0x10);
3686 }
3687
3688 // subq rsp, #8
3689 emit_opcode(cbuf, Assembler::REX_W);
3690 emit_opcode(cbuf, 0x83);
3691 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3692 emit_d8(cbuf, 8);
3693
3694 // movss [rsp], $src
3695 emit_opcode(cbuf, 0xF3);
3696 if (srcenc >= 8) {
3697 emit_opcode(cbuf, Assembler::REX_R);
3698 }
3699 emit_opcode(cbuf, 0x0F);
3700 emit_opcode(cbuf, 0x11);
3701 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3702
3703 // call f2l_fixup
3704 cbuf.set_insts_mark();
3705 emit_opcode(cbuf, 0xE8);
3706 emit_d32_reloc(cbuf,
3707 (int)
3708 (StubRoutines::x86::f2l_fixup() - cbuf.insts_end() - 4),
3709 runtime_call_Relocation::spec(),
3710 RELOC_DISP32);
3711
3712 // popq $dst
3713 if (dstenc >= 8) {
3714 emit_opcode(cbuf, Assembler::REX_B);
3715 }
3716 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3717
3718 // done:
3719 %}
3720
3721 enc_class d2i_fixup(rRegI dst, regD src)
3722 %{
3723 int dstenc = $dst$$reg;
3724 int srcenc = $src$$reg;
3725
3726 // cmpl $dst, #0x80000000
3727 if (dstenc >= 8) {
3728 emit_opcode(cbuf, Assembler::REX_B);
3729 }
3730 emit_opcode(cbuf, 0x81);
3731 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3732 emit_d32(cbuf, 0x80000000);
3733
3734 // jne,s done
3735 emit_opcode(cbuf, 0x75);
3736 if (srcenc < 8 && dstenc < 8) {
3737 emit_d8(cbuf, 0xF);
3738 } else if (srcenc >= 8 && dstenc >= 8) {
3739 emit_d8(cbuf, 0x11);
3740 } else {
3741 emit_d8(cbuf, 0x10);
3742 }
3743
3744 // subq rsp, #8
3745 emit_opcode(cbuf, Assembler::REX_W);
3746 emit_opcode(cbuf, 0x83);
3747 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3748 emit_d8(cbuf, 8);
3749
3750 // movsd [rsp], $src
3751 emit_opcode(cbuf, 0xF2);
3752 if (srcenc >= 8) {
3753 emit_opcode(cbuf, Assembler::REX_R);
3754 }
3755 emit_opcode(cbuf, 0x0F);
3756 emit_opcode(cbuf, 0x11);
3757 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3758
3759 // call d2i_fixup
3760 cbuf.set_insts_mark();
3761 emit_opcode(cbuf, 0xE8);
3762 emit_d32_reloc(cbuf,
3763 (int)
3764 (StubRoutines::x86::d2i_fixup() - cbuf.insts_end() - 4),
3765 runtime_call_Relocation::spec(),
3766 RELOC_DISP32);
3767
3768 // popq $dst
3769 if (dstenc >= 8) {
3770 emit_opcode(cbuf, Assembler::REX_B);
3771 }
3772 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3773
3774 // done:
3775 %}
3776
3777 enc_class d2l_fixup(rRegL dst, regD src)
3778 %{
3779 int dstenc = $dst$$reg;
3780 int srcenc = $src$$reg;
3781 address const_address = (address) StubRoutines::x86::double_sign_flip();
3782
3783 // cmpq $dst, [0x8000000000000000]
3784 cbuf.set_insts_mark();
3785 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3786 emit_opcode(cbuf, 0x39);
3787 // XXX reg_mem doesn't support RIP-relative addressing yet
3788 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3789 emit_d32_reloc(cbuf, const_address);
3790
3791
3792 // jne,s done
3793 emit_opcode(cbuf, 0x75);
3794 if (srcenc < 8 && dstenc < 8) {
3795 emit_d8(cbuf, 0xF);
3796 } else if (srcenc >= 8 && dstenc >= 8) {
3797 emit_d8(cbuf, 0x11);
3798 } else {
3799 emit_d8(cbuf, 0x10);
3800 }
3801
3802 // subq rsp, #8
3803 emit_opcode(cbuf, Assembler::REX_W);
3804 emit_opcode(cbuf, 0x83);
3805 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3806 emit_d8(cbuf, 8);
3807
3808 // movsd [rsp], $src
3809 emit_opcode(cbuf, 0xF2);
3810 if (srcenc >= 8) {
3811 emit_opcode(cbuf, Assembler::REX_R);
3812 }
3813 emit_opcode(cbuf, 0x0F);
3814 emit_opcode(cbuf, 0x11);
3815 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3816
3817 // call d2l_fixup
3818 cbuf.set_insts_mark();
3819 emit_opcode(cbuf, 0xE8);
3820 emit_d32_reloc(cbuf,
3821 (int)
3822 (StubRoutines::x86::d2l_fixup() - cbuf.insts_end() - 4),
3823 runtime_call_Relocation::spec(),
3824 RELOC_DISP32);
3825
3826 // popq $dst
3827 if (dstenc >= 8) {
3828 emit_opcode(cbuf, Assembler::REX_B);
3829 }
3830 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3831
3832 // done:
3833 %}
3834 %}
3835
3836
3837
3838 //----------FRAME--------------------------------------------------------------
3839 // Definition of frame structure and management information.
3840 //
3841 // S T A C K L A Y O U T Allocators stack-slot number
3842 // | (to get allocators register number
3843 // G Owned by | | v add OptoReg::stack0())
3844 // r CALLER | |
3845 // o | +--------+ pad to even-align allocators stack-slot
3846 // w V | pad0 | numbers; owned by CALLER
3847 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3848 // h ^ | in | 5
3849 // | | args | 4 Holes in incoming args owned by SELF
3850 // | | | | 3
3851 // | | +--------+
3852 // V | | old out| Empty on Intel, window on Sparc
3853 // | old |preserve| Must be even aligned.
6139 // Load narrow Klass Pointer
6140 instruct loadNKlass(rRegN dst, memory mem)
6141 %{
6142 match(Set dst (LoadNKlass mem));
6143
6144 ins_cost(125); // XXX
6145 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
6146 ins_encode %{
6147 __ movl($dst$$Register, $mem$$Address);
6148 %}
6149 ins_pipe(ialu_reg_mem); // XXX
6150 %}
6151
6152 // Load Float
6153 instruct loadF(regF dst, memory mem)
6154 %{
6155 match(Set dst (LoadF mem));
6156
6157 ins_cost(145); // XXX
6158 format %{ "movss $dst, $mem\t# float" %}
6159 opcode(0xF3, 0x0F, 0x10);
6160 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6161 ins_pipe(pipe_slow); // XXX
6162 %}
6163
6164 // Load Double
6165 instruct loadD_partial(regD dst, memory mem)
6166 %{
6167 predicate(!UseXmmLoadAndClearUpper);
6168 match(Set dst (LoadD mem));
6169
6170 ins_cost(145); // XXX
6171 format %{ "movlpd $dst, $mem\t# double" %}
6172 opcode(0x66, 0x0F, 0x12);
6173 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6174 ins_pipe(pipe_slow); // XXX
6175 %}
6176
6177 instruct loadD(regD dst, memory mem)
6178 %{
6179 predicate(UseXmmLoadAndClearUpper);
6180 match(Set dst (LoadD mem));
6181
6182 ins_cost(145); // XXX
6183 format %{ "movsd $dst, $mem\t# double" %}
6184 opcode(0xF2, 0x0F, 0x10);
6185 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6186 ins_pipe(pipe_slow); // XXX
6187 %}
6188
6189 // Load Aligned Packed Byte to XMM register
6190 instruct loadA8B(regD dst, memory mem) %{
6191 match(Set dst (Load8B mem));
6192 ins_cost(125);
6193 format %{ "MOVQ $dst,$mem\t! packed8B" %}
6194 ins_encode( movq_ld(dst, mem));
6195 ins_pipe( pipe_slow );
6196 %}
6197
6198 // Load Aligned Packed Short to XMM register
6199 instruct loadA4S(regD dst, memory mem) %{
6200 match(Set dst (Load4S mem));
6201 ins_cost(125);
6202 format %{ "MOVQ $dst,$mem\t! packed4S" %}
6203 ins_encode( movq_ld(dst, mem));
6204 ins_pipe( pipe_slow );
6205 %}
6206
6207 // Load Aligned Packed Char to XMM register
6208 instruct loadA4C(regD dst, memory mem) %{
6209 match(Set dst (Load4C mem));
6210 ins_cost(125);
6211 format %{ "MOVQ $dst,$mem\t! packed4C" %}
6212 ins_encode( movq_ld(dst, mem));
6213 ins_pipe( pipe_slow );
6214 %}
6215
6216 // Load Aligned Packed Integer to XMM register
6217 instruct load2IU(regD dst, memory mem) %{
6218 match(Set dst (Load2I mem));
6219 ins_cost(125);
6220 format %{ "MOVQ $dst,$mem\t! packed2I" %}
6221 ins_encode( movq_ld(dst, mem));
6222 ins_pipe( pipe_slow );
6223 %}
6224
6225 // Load Aligned Packed Single to XMM
6226 instruct loadA2F(regD dst, memory mem) %{
6227 match(Set dst (Load2F mem));
6228 ins_cost(145);
6229 format %{ "MOVQ $dst,$mem\t! packed2F" %}
6230 ins_encode( movq_ld(dst, mem));
6231 ins_pipe( pipe_slow );
6232 %}
6233
6234 // Load Effective Address
6235 instruct leaP8(rRegP dst, indOffset8 mem)
6236 %{
6237 match(Set dst mem);
6238
6239 ins_cost(110); // XXX
6240 format %{ "leaq $dst, $mem\t# ptr 8" %}
6241 opcode(0x8D);
6242 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6243 ins_pipe(ialu_reg_reg_fat);
6244 %}
6245
6246 instruct leaP32(rRegP dst, indOffset32 mem)
6247 %{
6248 match(Set dst mem);
6249
6250 ins_cost(110);
6523
6524 ins_cost(125);
6525 format %{ "movl $dst, $src\t# compressed ptr" %}
6526 ins_encode %{
6527 address con = (address)$src$$constant;
6528 if (con == NULL) {
6529 ShouldNotReachHere();
6530 } else {
6531 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6532 }
6533 %}
6534 ins_pipe(ialu_reg_fat); // XXX
6535 %}
6536
6537 instruct loadConF0(regF dst, immF0 src)
6538 %{
6539 match(Set dst src);
6540 ins_cost(100);
6541
6542 format %{ "xorps $dst, $dst\t# float 0.0" %}
6543 opcode(0x0F, 0x57);
6544 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6545 ins_pipe(pipe_slow);
6546 %}
6547
6548 // Use the same format since predicate() can not be used here.
6549 instruct loadConD(regD dst, immD con) %{
6550 match(Set dst con);
6551 ins_cost(125);
6552 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
6553 ins_encode %{
6554 __ movdbl($dst$$XMMRegister, $constantaddress($con));
6555 %}
6556 ins_pipe(pipe_slow);
6557 %}
6558
6559 instruct loadConD0(regD dst, immD0 src)
6560 %{
6561 match(Set dst src);
6562 ins_cost(100);
6563
6564 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6565 opcode(0x66, 0x0F, 0x57);
6566 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst));
6567 ins_pipe(pipe_slow);
6568 %}
6569
6570 instruct loadSSI(rRegI dst, stackSlotI src)
6571 %{
6572 match(Set dst src);
6573
6574 ins_cost(125);
6575 format %{ "movl $dst, $src\t# int stk" %}
6576 opcode(0x8B);
6577 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
6578 ins_pipe(ialu_reg_mem);
6579 %}
6580
6581 instruct loadSSL(rRegL dst, stackSlotL src)
6582 %{
6583 match(Set dst src);
6584
6585 ins_cost(125);
6586 format %{ "movq $dst, $src\t# long stk" %}
6589 ins_pipe(ialu_reg_mem);
6590 %}
6591
6592 instruct loadSSP(rRegP dst, stackSlotP src)
6593 %{
6594 match(Set dst src);
6595
6596 ins_cost(125);
6597 format %{ "movq $dst, $src\t# ptr stk" %}
6598 opcode(0x8B);
6599 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6600 ins_pipe(ialu_reg_mem);
6601 %}
6602
6603 instruct loadSSF(regF dst, stackSlotF src)
6604 %{
6605 match(Set dst src);
6606
6607 ins_cost(125);
6608 format %{ "movss $dst, $src\t# float stk" %}
6609 opcode(0xF3, 0x0F, 0x10);
6610 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
6611 ins_pipe(pipe_slow); // XXX
6612 %}
6613
6614 // Use the same format since predicate() can not be used here.
6615 instruct loadSSD(regD dst, stackSlotD src)
6616 %{
6617 match(Set dst src);
6618
6619 ins_cost(125);
6620 format %{ "movsd $dst, $src\t# double stk" %}
6621 ins_encode %{
6622 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
6623 %}
6624 ins_pipe(pipe_slow); // XXX
6625 %}
6626
6627 // Prefetch instructions.
6628 // Must be safe to execute with invalid address (cannot fault).
6629
6630 instruct prefetchr( memory mem ) %{
6955 %}
6956 ins_pipe(ialu_mem_reg);
6957 %}
6958
6959 instruct storeImmB(memory mem, immI8 src)
6960 %{
6961 match(Set mem (StoreB mem src));
6962
6963 ins_cost(150); // XXX
6964 format %{ "movb $mem, $src\t# byte" %}
6965 opcode(0xC6); /* C6 /0 */
6966 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6967 ins_pipe(ialu_mem_imm);
6968 %}
6969
6970 // Store Aligned Packed Byte XMM register to memory
6971 instruct storeA8B(memory mem, regD src) %{
6972 match(Set mem (Store8B mem src));
6973 ins_cost(145);
6974 format %{ "MOVQ $mem,$src\t! packed8B" %}
6975 ins_encode( movq_st(mem, src));
6976 ins_pipe( pipe_slow );
6977 %}
6978
6979 // Store Aligned Packed Char/Short XMM register to memory
6980 instruct storeA4C(memory mem, regD src) %{
6981 match(Set mem (Store4C mem src));
6982 ins_cost(145);
6983 format %{ "MOVQ $mem,$src\t! packed4C" %}
6984 ins_encode( movq_st(mem, src));
6985 ins_pipe( pipe_slow );
6986 %}
6987
6988 // Store Aligned Packed Integer XMM register to memory
6989 instruct storeA2I(memory mem, regD src) %{
6990 match(Set mem (Store2I mem src));
6991 ins_cost(145);
6992 format %{ "MOVQ $mem,$src\t! packed2I" %}
6993 ins_encode( movq_st(mem, src));
6994 ins_pipe( pipe_slow );
6995 %}
6996
6997 // Store CMS card-mark Immediate
6998 instruct storeImmCM0_reg(memory mem, immI0 zero)
6999 %{
7000 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7001 match(Set mem (StoreCM mem zero));
7002
7003 ins_cost(125); // XXX
7004 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
7005 ins_encode %{
7006 __ movb($mem$$Address, r12);
7007 %}
7008 ins_pipe(ialu_mem_reg);
7009 %}
7010
7011 instruct storeImmCM0(memory mem, immI0 src)
7012 %{
7013 match(Set mem (StoreCM mem src));
7014
7015 ins_cost(150); // XXX
7016 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
7017 opcode(0xC6); /* C6 /0 */
7018 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
7019 ins_pipe(ialu_mem_imm);
7020 %}
7021
7022 // Store Aligned Packed Single Float XMM register to memory
7023 instruct storeA2F(memory mem, regD src) %{
7024 match(Set mem (Store2F mem src));
7025 ins_cost(145);
7026 format %{ "MOVQ $mem,$src\t! packed2F" %}
7027 ins_encode( movq_st(mem, src));
7028 ins_pipe( pipe_slow );
7029 %}
7030
7031 // Store Float
7032 instruct storeF(memory mem, regF src)
7033 %{
7034 match(Set mem (StoreF mem src));
7035
7036 ins_cost(95); // XXX
7037 format %{ "movss $mem, $src\t# float" %}
7038 opcode(0xF3, 0x0F, 0x11);
7039 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7040 ins_pipe(pipe_slow); // XXX
7041 %}
7042
7043 // Store immediate Float value (it is faster than store from XMM register)
7044 instruct storeF0(memory mem, immF0 zero)
7045 %{
7046 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7047 match(Set mem (StoreF mem zero));
7048
7049 ins_cost(25); // XXX
7050 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
7051 ins_encode %{
7052 __ movl($mem$$Address, r12);
7053 %}
7054 ins_pipe(ialu_mem_reg);
7055 %}
7056
7057 instruct storeF_imm(memory mem, immF src)
7058 %{
7059 match(Set mem (StoreF mem src));
7060
7061 ins_cost(50);
7062 format %{ "movl $mem, $src\t# float" %}
7063 opcode(0xC7); /* C7 /0 */
7064 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7065 ins_pipe(ialu_mem_imm);
7066 %}
7067
7068 // Store Double
7069 instruct storeD(memory mem, regD src)
7070 %{
7071 match(Set mem (StoreD mem src));
7072
7073 ins_cost(95); // XXX
7074 format %{ "movsd $mem, $src\t# double" %}
7075 opcode(0xF2, 0x0F, 0x11);
7076 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7077 ins_pipe(pipe_slow); // XXX
7078 %}
7079
7080 // Store immediate double 0.0 (it is faster than store from XMM register)
7081 instruct storeD0_imm(memory mem, immD0 src)
7082 %{
7083 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
7084 match(Set mem (StoreD mem src));
7085
7086 ins_cost(50);
7087 format %{ "movq $mem, $src\t# double 0." %}
7088 opcode(0xC7); /* C7 /0 */
7089 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7090 ins_pipe(ialu_mem_imm);
7091 %}
7092
7093 instruct storeD0(memory mem, immD0 zero)
7094 %{
7095 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7096 match(Set mem (StoreD mem zero));
7125 ins_pipe(ialu_mem_reg);
7126 %}
7127
7128 instruct storeSSP(stackSlotP dst, rRegP src)
7129 %{
7130 match(Set dst src);
7131
7132 ins_cost(100);
7133 format %{ "movq $dst, $src\t# ptr stk" %}
7134 opcode(0x89);
7135 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7136 ins_pipe(ialu_mem_reg);
7137 %}
7138
7139 instruct storeSSF(stackSlotF dst, regF src)
7140 %{
7141 match(Set dst src);
7142
7143 ins_cost(95); // XXX
7144 format %{ "movss $dst, $src\t# float stk" %}
7145 opcode(0xF3, 0x0F, 0x11);
7146 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7147 ins_pipe(pipe_slow); // XXX
7148 %}
7149
7150 instruct storeSSD(stackSlotD dst, regD src)
7151 %{
7152 match(Set dst src);
7153
7154 ins_cost(95); // XXX
7155 format %{ "movsd $dst, $src\t# double stk" %}
7156 opcode(0xF2, 0x0F, 0x11);
7157 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7158 ins_pipe(pipe_slow); // XXX
7159 %}
7160
7161 //----------BSWAP Instructions-------------------------------------------------
7162 instruct bytes_reverse_int(rRegI dst) %{
7163 match(Set dst (ReverseBytesI dst));
7164
7165 format %{ "bswapl $dst" %}
7166 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
7167 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
7168 ins_pipe( ialu_reg );
7169 %}
7170
7171 instruct bytes_reverse_long(rRegL dst) %{
7172 match(Set dst (ReverseBytesL dst));
7173
7174 format %{ "bswapq $dst" %}
7175
7176 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
7177 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
7434
7435 instruct unnecessary_membar_volatile()
7436 %{
7437 match(MemBarVolatile);
7438 predicate(Matcher::post_store_load_barrier(n));
7439 ins_cost(0);
7440
7441 size(0);
7442 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
7443 ins_encode();
7444 ins_pipe(empty);
7445 %}
7446
7447 //----------Move Instructions--------------------------------------------------
7448
7449 instruct castX2P(rRegP dst, rRegL src)
7450 %{
7451 match(Set dst (CastX2P src));
7452
7453 format %{ "movq $dst, $src\t# long->ptr" %}
7454 ins_encode(enc_copy_wide(dst, src));
7455 ins_pipe(ialu_reg_reg); // XXX
7456 %}
7457
7458 instruct castP2X(rRegL dst, rRegP src)
7459 %{
7460 match(Set dst (CastP2X src));
7461
7462 format %{ "movq $dst, $src\t# ptr -> long" %}
7463 ins_encode(enc_copy_wide(dst, src));
7464 ins_pipe(ialu_reg_reg); // XXX
7465 %}
7466
7467
7468 // Convert oop pointer into compressed form
7469 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
7470 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7471 match(Set dst (EncodeP src));
7472 effect(KILL cr);
7473 format %{ "encode_heap_oop $dst,$src" %}
7474 ins_encode %{
7475 Register s = $src$$Register;
7476 Register d = $dst$$Register;
7477 if (s != d) {
7478 __ movq(d, s);
7479 }
7480 __ encode_heap_oop(d);
7481 %}
7482 ins_pipe(ialu_reg_long);
7483 %}
7796 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7797 ins_pipe(pipe_cmov_mem); // XXX
7798 %}
7799
7800 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7801 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7802 ins_cost(200);
7803 expand %{
7804 cmovL_memU(cop, cr, dst, src);
7805 %}
7806 %}
7807
7808 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7809 %{
7810 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7811
7812 ins_cost(200); // XXX
7813 format %{ "jn$cop skip\t# signed cmove float\n\t"
7814 "movss $dst, $src\n"
7815 "skip:" %}
7816 ins_encode(enc_cmovf_branch(cop, dst, src));
7817 ins_pipe(pipe_slow);
7818 %}
7819
7820 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7821 // %{
7822 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7823
7824 // ins_cost(200); // XXX
7825 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7826 // "movss $dst, $src\n"
7827 // "skip:" %}
7828 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7829 // ins_pipe(pipe_slow);
7830 // %}
7831
7832 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7833 %{
7834 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7835
7836 ins_cost(200); // XXX
7837 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7838 "movss $dst, $src\n"
7839 "skip:" %}
7840 ins_encode(enc_cmovf_branch(cop, dst, src));
7841 ins_pipe(pipe_slow);
7842 %}
7843
7844 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7845 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7846 ins_cost(200);
7847 expand %{
7848 cmovF_regU(cop, cr, dst, src);
7849 %}
7850 %}
7851
7852 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7853 %{
7854 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7855
7856 ins_cost(200); // XXX
7857 format %{ "jn$cop skip\t# signed cmove double\n\t"
7858 "movsd $dst, $src\n"
7859 "skip:" %}
7860 ins_encode(enc_cmovd_branch(cop, dst, src));
7861 ins_pipe(pipe_slow);
7862 %}
7863
7864 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7865 %{
7866 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7867
7868 ins_cost(200); // XXX
7869 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7870 "movsd $dst, $src\n"
7871 "skip:" %}
7872 ins_encode(enc_cmovd_branch(cop, dst, src));
7873 ins_pipe(pipe_slow);
7874 %}
7875
7876 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7877 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7878 ins_cost(200);
7879 expand %{
7880 cmovD_regU(cop, cr, dst, src);
7881 %}
7882 %}
7883
7884 //----------Arithmetic Instructions--------------------------------------------
7885 //----------Addition Instructions----------------------------------------------
7886
7887 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7888 %{
7889 match(Set dst (AddI dst src));
7890 effect(KILL cr);
7891
7892 format %{ "addl $dst, $src\t# int" %}
10174 __ subl(Rp, Rq);
10175 __ sbbl(Rt, Rt);
10176 __ andl(Rt, Ry);
10177 __ addl(Rp, Rt);
10178 %}
10179 ins_pipe(pipe_cmplt);
10180 %}
10181
10182 //---------- FP Instructions------------------------------------------------
10183
10184 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
10185 %{
10186 match(Set cr (CmpF src1 src2));
10187
10188 ins_cost(145);
10189 format %{ "ucomiss $src1, $src2\n\t"
10190 "jnp,s exit\n\t"
10191 "pushfq\t# saw NaN, set CF\n\t"
10192 "andq [rsp], #0xffffff2b\n\t"
10193 "popfq\n"
10194 "exit: nop\t# avoid branch to branch" %}
10195 opcode(0x0F, 0x2E);
10196 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10197 cmpfp_fixup);
10198 ins_pipe(pipe_slow);
10199 %}
10200
10201 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10202 match(Set cr (CmpF src1 src2));
10203
10204 ins_cost(145);
10205 format %{ "ucomiss $src1, $src2" %}
10206 ins_encode %{
10207 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10208 %}
10209 ins_pipe(pipe_slow);
10210 %}
10211
10212 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
10213 %{
10214 match(Set cr (CmpF src1 (LoadF src2)));
10215
10216 ins_cost(145);
10217 format %{ "ucomiss $src1, $src2\n\t"
10218 "jnp,s exit\n\t"
10219 "pushfq\t# saw NaN, set CF\n\t"
10220 "andq [rsp], #0xffffff2b\n\t"
10221 "popfq\n"
10222 "exit: nop\t# avoid branch to branch" %}
10223 opcode(0x0F, 0x2E);
10224 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10225 cmpfp_fixup);
10226 ins_pipe(pipe_slow);
10227 %}
10228
10229 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10230 match(Set cr (CmpF src1 (LoadF src2)));
10231
10232 ins_cost(100);
10233 format %{ "ucomiss $src1, $src2" %}
10234 opcode(0x0F, 0x2E);
10235 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10236 ins_pipe(pipe_slow);
10237 %}
10238
10239 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10240 match(Set cr (CmpF src con));
10241
10242 ins_cost(145);
10243 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10244 "jnp,s exit\n\t"
10245 "pushfq\t# saw NaN, set CF\n\t"
10246 "andq [rsp], #0xffffff2b\n\t"
10247 "popfq\n"
10248 "exit: nop\t# avoid branch to branch" %}
10249 ins_encode %{
10250 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10251 emit_cmpfp_fixup(_masm);
10252 %}
10253 ins_pipe(pipe_slow);
10254 %}
10255
10256 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10257 match(Set cr (CmpF src con));
10258 ins_cost(100);
10259 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10260 ins_encode %{
10261 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10262 %}
10263 ins_pipe(pipe_slow);
10264 %}
10265
10266 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10267 %{
10268 match(Set cr (CmpD src1 src2));
10269
10270 ins_cost(145);
10271 format %{ "ucomisd $src1, $src2\n\t"
10272 "jnp,s exit\n\t"
10273 "pushfq\t# saw NaN, set CF\n\t"
10274 "andq [rsp], #0xffffff2b\n\t"
10275 "popfq\n"
10276 "exit: nop\t# avoid branch to branch" %}
10277 opcode(0x66, 0x0F, 0x2E);
10278 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10279 cmpfp_fixup);
10280 ins_pipe(pipe_slow);
10281 %}
10282
10283 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10284 match(Set cr (CmpD src1 src2));
10285
10286 ins_cost(100);
10287 format %{ "ucomisd $src1, $src2 test" %}
10288 ins_encode %{
10289 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10290 %}
10291 ins_pipe(pipe_slow);
10292 %}
10293
10294 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
10295 %{
10296 match(Set cr (CmpD src1 (LoadD src2)));
10297
10298 ins_cost(145);
10299 format %{ "ucomisd $src1, $src2\n\t"
10300 "jnp,s exit\n\t"
10301 "pushfq\t# saw NaN, set CF\n\t"
10302 "andq [rsp], #0xffffff2b\n\t"
10303 "popfq\n"
10304 "exit: nop\t# avoid branch to branch" %}
10305 opcode(0x66, 0x0F, 0x2E);
10306 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10307 cmpfp_fixup);
10308 ins_pipe(pipe_slow);
10309 %}
10310
10311 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10312 match(Set cr (CmpD src1 (LoadD src2)));
10313
10314 ins_cost(100);
10315 format %{ "ucomisd $src1, $src2" %}
10316 opcode(0x66, 0x0F, 0x2E);
10317 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10318 ins_pipe(pipe_slow);
10319 %}
10320
10321 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10322 match(Set cr (CmpD src con));
10323
10324 ins_cost(145);
10325 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10326 "jnp,s exit\n\t"
10327 "pushfq\t# saw NaN, set CF\n\t"
10328 "andq [rsp], #0xffffff2b\n\t"
10329 "popfq\n"
10330 "exit: nop\t# avoid branch to branch" %}
10331 ins_encode %{
10332 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10333 emit_cmpfp_fixup(_masm);
10334 %}
10335 ins_pipe(pipe_slow);
10336 %}
10337
10338 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10339 match(Set cr (CmpD src con));
10340 ins_cost(100);
10341 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10342 ins_encode %{
10343 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10344 %}
10345 ins_pipe(pipe_slow);
10346 %}
10347
10348 // Compare into -1,0,1
10349 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10350 %{
10351 match(Set dst (CmpF3 src1 src2));
10352 effect(KILL cr);
10353
10354 ins_cost(275);
10355 format %{ "ucomiss $src1, $src2\n\t"
10356 "movl $dst, #-1\n\t"
10357 "jp,s done\n\t"
10358 "jb,s done\n\t"
10359 "setne $dst\n\t"
10360 "movzbl $dst, $dst\n"
10361 "done:" %}
10362
10363 opcode(0x0F, 0x2E);
10364 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10365 cmpfp3(dst));
10366 ins_pipe(pipe_slow);
10367 %}
10368
10369 // Compare into -1,0,1
10370 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10371 %{
10372 match(Set dst (CmpF3 src1 (LoadF src2)));
10373 effect(KILL cr);
10374
10375 ins_cost(275);
10376 format %{ "ucomiss $src1, $src2\n\t"
10377 "movl $dst, #-1\n\t"
10378 "jp,s done\n\t"
10379 "jb,s done\n\t"
10380 "setne $dst\n\t"
10381 "movzbl $dst, $dst\n"
10382 "done:" %}
10383
10384 opcode(0x0F, 0x2E);
10385 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10386 cmpfp3(dst));
10387 ins_pipe(pipe_slow);
10388 %}
10389
10390 // Compare into -1,0,1
10391 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10392 match(Set dst (CmpF3 src con));
10393 effect(KILL cr);
10394
10395 ins_cost(275);
10396 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10397 "movl $dst, #-1\n\t"
10398 "jp,s done\n\t"
10399 "jb,s done\n\t"
10400 "setne $dst\n\t"
10401 "movzbl $dst, $dst\n"
10402 "done:" %}
10403 ins_encode %{
10404 Label L_done;
10405 Register Rdst = $dst$$Register;
10406 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10407 __ movl(Rdst, -1);
10408 __ jcc(Assembler::parity, L_done);
10409 __ jcc(Assembler::below, L_done);
10410 __ setb(Assembler::notEqual, Rdst);
10411 __ movzbl(Rdst, Rdst);
10412 __ bind(L_done);
10413 %}
10414 ins_pipe(pipe_slow);
10415 %}
10416
10417 // Compare into -1,0,1
10418 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10419 %{
10420 match(Set dst (CmpD3 src1 src2));
10421 effect(KILL cr);
10422
10423 ins_cost(275);
10424 format %{ "ucomisd $src1, $src2\n\t"
10425 "movl $dst, #-1\n\t"
10426 "jp,s done\n\t"
10427 "jb,s done\n\t"
10428 "setne $dst\n\t"
10429 "movzbl $dst, $dst\n"
10430 "done:" %}
10431
10432 opcode(0x66, 0x0F, 0x2E);
10433 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10434 cmpfp3(dst));
10435 ins_pipe(pipe_slow);
10436 %}
10437
10438 // Compare into -1,0,1
10439 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10440 %{
10441 match(Set dst (CmpD3 src1 (LoadD src2)));
10442 effect(KILL cr);
10443
10444 ins_cost(275);
10445 format %{ "ucomisd $src1, $src2\n\t"
10446 "movl $dst, #-1\n\t"
10447 "jp,s done\n\t"
10448 "jb,s done\n\t"
10449 "setne $dst\n\t"
10450 "movzbl $dst, $dst\n"
10451 "done:" %}
10452
10453 opcode(0x66, 0x0F, 0x2E);
10454 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10455 cmpfp3(dst));
10456 ins_pipe(pipe_slow);
10457 %}
10458
10459 // Compare into -1,0,1
10460 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10461 match(Set dst (CmpD3 src con));
10462 effect(KILL cr);
10463
10464 ins_cost(275);
10465 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10466 "movl $dst, #-1\n\t"
10467 "jp,s done\n\t"
10468 "jb,s done\n\t"
10469 "setne $dst\n\t"
10470 "movzbl $dst, $dst\n"
10471 "done:" %}
10472 ins_encode %{
10473 Register Rdst = $dst$$Register;
10474 Label L_done;
10475 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10476 __ movl(Rdst, -1);
10477 __ jcc(Assembler::parity, L_done);
10478 __ jcc(Assembler::below, L_done);
10479 __ setb(Assembler::notEqual, Rdst);
10480 __ movzbl(Rdst, Rdst);
10481 __ bind(L_done);
10482 %}
10483 ins_pipe(pipe_slow);
10484 %}
10485
10486 instruct addF_reg(regF dst, regF src)
10487 %{
10488 match(Set dst (AddF dst src));
10489
10490 format %{ "addss $dst, $src" %}
10491 ins_cost(150); // XXX
10492 opcode(0xF3, 0x0F, 0x58);
10493 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10494 ins_pipe(pipe_slow);
10495 %}
10496
10497 instruct addF_mem(regF dst, memory src)
10498 %{
10499 match(Set dst (AddF dst (LoadF src)));
10500
10501 format %{ "addss $dst, $src" %}
10502 ins_cost(150); // XXX
10503 opcode(0xF3, 0x0F, 0x58);
10504 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10505 ins_pipe(pipe_slow);
10506 %}
10507
10508 instruct addF_imm(regF dst, immF con) %{
10509 match(Set dst (AddF dst con));
10510 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10511 ins_cost(150); // XXX
10512 ins_encode %{
10513 __ addss($dst$$XMMRegister, $constantaddress($con));
10514 %}
10515 ins_pipe(pipe_slow);
10516 %}
10517
10518 instruct addD_reg(regD dst, regD src)
10519 %{
10520 match(Set dst (AddD dst src));
10521
10522 format %{ "addsd $dst, $src" %}
10523 ins_cost(150); // XXX
10524 opcode(0xF2, 0x0F, 0x58);
10525 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10526 ins_pipe(pipe_slow);
10527 %}
10528
10529 instruct addD_mem(regD dst, memory src)
10530 %{
10531 match(Set dst (AddD dst (LoadD src)));
10532
10533 format %{ "addsd $dst, $src" %}
10534 ins_cost(150); // XXX
10535 opcode(0xF2, 0x0F, 0x58);
10536 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10537 ins_pipe(pipe_slow);
10538 %}
10539
10540 instruct addD_imm(regD dst, immD con) %{
10541 match(Set dst (AddD dst con));
10542 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10543 ins_cost(150); // XXX
10544 ins_encode %{
10545 __ addsd($dst$$XMMRegister, $constantaddress($con));
10546 %}
10547 ins_pipe(pipe_slow);
10548 %}
10549
10550 instruct subF_reg(regF dst, regF src)
10551 %{
10552 match(Set dst (SubF dst src));
10553
10554 format %{ "subss $dst, $src" %}
10555 ins_cost(150); // XXX
10556 opcode(0xF3, 0x0F, 0x5C);
10557 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10558 ins_pipe(pipe_slow);
10559 %}
10560
10561 instruct subF_mem(regF dst, memory src)
10562 %{
10563 match(Set dst (SubF dst (LoadF src)));
10564
10565 format %{ "subss $dst, $src" %}
10566 ins_cost(150); // XXX
10567 opcode(0xF3, 0x0F, 0x5C);
10568 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10569 ins_pipe(pipe_slow);
10570 %}
10571
10572 instruct subF_imm(regF dst, immF con) %{
10573 match(Set dst (SubF dst con));
10574 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10575 ins_cost(150); // XXX
10576 ins_encode %{
10577 __ subss($dst$$XMMRegister, $constantaddress($con));
10578 %}
10579 ins_pipe(pipe_slow);
10580 %}
10581
10582 instruct subD_reg(regD dst, regD src)
10583 %{
10584 match(Set dst (SubD dst src));
10585
10586 format %{ "subsd $dst, $src" %}
10587 ins_cost(150); // XXX
10588 opcode(0xF2, 0x0F, 0x5C);
10589 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10590 ins_pipe(pipe_slow);
10591 %}
10592
10593 instruct subD_mem(regD dst, memory src)
10594 %{
10595 match(Set dst (SubD dst (LoadD src)));
10596
10597 format %{ "subsd $dst, $src" %}
10598 ins_cost(150); // XXX
10599 opcode(0xF2, 0x0F, 0x5C);
10600 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10601 ins_pipe(pipe_slow);
10602 %}
10603
10604 instruct subD_imm(regD dst, immD con) %{
10605 match(Set dst (SubD dst con));
10606 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10607 ins_cost(150); // XXX
10608 ins_encode %{
10609 __ subsd($dst$$XMMRegister, $constantaddress($con));
10610 %}
10611 ins_pipe(pipe_slow);
10612 %}
10613
10614 instruct mulF_reg(regF dst, regF src)
10615 %{
10616 match(Set dst (MulF dst src));
10617
10618 format %{ "mulss $dst, $src" %}
10619 ins_cost(150); // XXX
10620 opcode(0xF3, 0x0F, 0x59);
10621 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10622 ins_pipe(pipe_slow);
10623 %}
10624
10625 instruct mulF_mem(regF dst, memory src)
10626 %{
10627 match(Set dst (MulF dst (LoadF src)));
10628
10629 format %{ "mulss $dst, $src" %}
10630 ins_cost(150); // XXX
10631 opcode(0xF3, 0x0F, 0x59);
10632 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10633 ins_pipe(pipe_slow);
10634 %}
10635
10636 instruct mulF_imm(regF dst, immF con) %{
10637 match(Set dst (MulF dst con));
10638 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10639 ins_cost(150); // XXX
10640 ins_encode %{
10641 __ mulss($dst$$XMMRegister, $constantaddress($con));
10642 %}
10643 ins_pipe(pipe_slow);
10644 %}
10645
10646 instruct mulD_reg(regD dst, regD src)
10647 %{
10648 match(Set dst (MulD dst src));
10649
10650 format %{ "mulsd $dst, $src" %}
10651 ins_cost(150); // XXX
10652 opcode(0xF2, 0x0F, 0x59);
10653 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10654 ins_pipe(pipe_slow);
10655 %}
10656
10657 instruct mulD_mem(regD dst, memory src)
10658 %{
10659 match(Set dst (MulD dst (LoadD src)));
10660
10661 format %{ "mulsd $dst, $src" %}
10662 ins_cost(150); // XXX
10663 opcode(0xF2, 0x0F, 0x59);
10664 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10665 ins_pipe(pipe_slow);
10666 %}
10667
10668 instruct mulD_imm(regD dst, immD con) %{
10669 match(Set dst (MulD dst con));
10670 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10671 ins_cost(150); // XXX
10672 ins_encode %{
10673 __ mulsd($dst$$XMMRegister, $constantaddress($con));
10674 %}
10675 ins_pipe(pipe_slow);
10676 %}
10677
10678 instruct divF_reg(regF dst, regF src)
10679 %{
10680 match(Set dst (DivF dst src));
10681
10682 format %{ "divss $dst, $src" %}
10683 ins_cost(150); // XXX
10684 opcode(0xF3, 0x0F, 0x5E);
10685 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10686 ins_pipe(pipe_slow);
10687 %}
10688
10689 instruct divF_mem(regF dst, memory src)
10690 %{
10691 match(Set dst (DivF dst (LoadF src)));
10692
10693 format %{ "divss $dst, $src" %}
10694 ins_cost(150); // XXX
10695 opcode(0xF3, 0x0F, 0x5E);
10696 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10697 ins_pipe(pipe_slow);
10698 %}
10699
10700 instruct divF_imm(regF dst, immF con) %{
10701 match(Set dst (DivF dst con));
10702 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10703 ins_cost(150); // XXX
10704 ins_encode %{
10705 __ divss($dst$$XMMRegister, $constantaddress($con));
10706 %}
10707 ins_pipe(pipe_slow);
10708 %}
10709
10710 instruct divD_reg(regD dst, regD src)
10711 %{
10712 match(Set dst (DivD dst src));
10713
10714 format %{ "divsd $dst, $src" %}
10715 ins_cost(150); // XXX
10716 opcode(0xF2, 0x0F, 0x5E);
10717 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10718 ins_pipe(pipe_slow);
10719 %}
10720
10721 instruct divD_mem(regD dst, memory src)
10722 %{
10723 match(Set dst (DivD dst (LoadD src)));
10724
10725 format %{ "divsd $dst, $src" %}
10726 ins_cost(150); // XXX
10727 opcode(0xF2, 0x0F, 0x5E);
10728 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10729 ins_pipe(pipe_slow);
10730 %}
10731
10732 instruct divD_imm(regD dst, immD con) %{
10733 match(Set dst (DivD dst con));
10734 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10735 ins_cost(150); // XXX
10736 ins_encode %{
10737 __ divsd($dst$$XMMRegister, $constantaddress($con));
10738 %}
10739 ins_pipe(pipe_slow);
10740 %}
10741
10742 instruct sqrtF_reg(regF dst, regF src)
10743 %{
10744 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10745
10746 format %{ "sqrtss $dst, $src" %}
10747 ins_cost(150); // XXX
10748 opcode(0xF3, 0x0F, 0x51);
10749 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10750 ins_pipe(pipe_slow);
10751 %}
10752
10753 instruct sqrtF_mem(regF dst, memory src)
10754 %{
10755 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10756
10757 format %{ "sqrtss $dst, $src" %}
10758 ins_cost(150); // XXX
10759 opcode(0xF3, 0x0F, 0x51);
10760 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10761 ins_pipe(pipe_slow);
10762 %}
10763
10764 instruct sqrtF_imm(regF dst, immF con) %{
10765 match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
10766 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10767 ins_cost(150); // XXX
10768 ins_encode %{
10769 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
10770 %}
10771 ins_pipe(pipe_slow);
10772 %}
10773
10774 instruct sqrtD_reg(regD dst, regD src)
10775 %{
10776 match(Set dst (SqrtD src));
10777
10778 format %{ "sqrtsd $dst, $src" %}
10779 ins_cost(150); // XXX
10780 opcode(0xF2, 0x0F, 0x51);
10781 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10782 ins_pipe(pipe_slow);
10783 %}
10784
10785 instruct sqrtD_mem(regD dst, memory src)
10786 %{
10787 match(Set dst (SqrtD (LoadD src)));
10788
10789 format %{ "sqrtsd $dst, $src" %}
10790 ins_cost(150); // XXX
10791 opcode(0xF2, 0x0F, 0x51);
10792 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10793 ins_pipe(pipe_slow);
10794 %}
10795
10796 instruct sqrtD_imm(regD dst, immD con) %{
10797 match(Set dst (SqrtD con));
10798 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10799 ins_cost(150); // XXX
10800 ins_encode %{
10801 __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
10802 %}
10803 ins_pipe(pipe_slow);
10804 %}
10805
10806 instruct absF_reg(regF dst)
10807 %{
10808 match(Set dst (AbsF dst));
10809
10810 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10811 ins_encode(absF_encoding(dst));
10812 ins_pipe(pipe_slow);
10813 %}
10814
10815 instruct absD_reg(regD dst)
10816 %{
10817 match(Set dst (AbsD dst));
10818
10819 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10820 "# abs double by sign masking" %}
10821 ins_encode(absD_encoding(dst));
10822 ins_pipe(pipe_slow);
10823 %}
10824
10825 instruct negF_reg(regF dst)
10826 %{
10827 match(Set dst (NegF dst));
10828
10829 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
10830 ins_encode(negF_encoding(dst));
10831 ins_pipe(pipe_slow);
10832 %}
10833
10834 instruct negD_reg(regD dst)
10835 %{
10836 match(Set dst (NegD dst));
10837
10838 format %{ "xorpd $dst, [0x8000000000000000]\t"
10839 "# neg double by sign flipping" %}
10840 ins_encode(negD_encoding(dst));
10841 ins_pipe(pipe_slow);
10842 %}
10843
10844 // -----------Trig and Trancendental Instructions------------------------------
10845 instruct cosD_reg(regD dst) %{
10846 match(Set dst (CosD dst));
10847
10848 format %{ "dcos $dst\n\t" %}
10849 opcode(0xD9, 0xFF);
10850 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10851 ins_pipe( pipe_slow );
10852 %}
10853
10854 instruct sinD_reg(regD dst) %{
10855 match(Set dst (SinD dst));
10856
10857 format %{ "dsin $dst\n\t" %}
10858 opcode(0xD9, 0xFE);
10859 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10860 ins_pipe( pipe_slow );
10912
10913 ins_cost(0);
10914 ins_encode();
10915 ins_pipe(empty);
10916 %}
10917
10918 instruct roundDouble_nop(regD dst)
10919 %{
10920 match(Set dst (RoundDouble dst));
10921
10922 ins_cost(0);
10923 ins_encode();
10924 ins_pipe(empty);
10925 %}
10926
10927 instruct convF2D_reg_reg(regD dst, regF src)
10928 %{
10929 match(Set dst (ConvF2D src));
10930
10931 format %{ "cvtss2sd $dst, $src" %}
10932 opcode(0xF3, 0x0F, 0x5A);
10933 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10934 ins_pipe(pipe_slow); // XXX
10935 %}
10936
10937 instruct convF2D_reg_mem(regD dst, memory src)
10938 %{
10939 match(Set dst (ConvF2D (LoadF src)));
10940
10941 format %{ "cvtss2sd $dst, $src" %}
10942 opcode(0xF3, 0x0F, 0x5A);
10943 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10944 ins_pipe(pipe_slow); // XXX
10945 %}
10946
10947 instruct convD2F_reg_reg(regF dst, regD src)
10948 %{
10949 match(Set dst (ConvD2F src));
10950
10951 format %{ "cvtsd2ss $dst, $src" %}
10952 opcode(0xF2, 0x0F, 0x5A);
10953 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10954 ins_pipe(pipe_slow); // XXX
10955 %}
10956
10957 instruct convD2F_reg_mem(regF dst, memory src)
10958 %{
10959 match(Set dst (ConvD2F (LoadD src)));
10960
10961 format %{ "cvtsd2ss $dst, $src" %}
10962 opcode(0xF2, 0x0F, 0x5A);
10963 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10964 ins_pipe(pipe_slow); // XXX
10965 %}
10966
10967 // XXX do mem variants
10968 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10969 %{
10970 match(Set dst (ConvF2I src));
10971 effect(KILL cr);
10972
10973 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
10974 "cmpl $dst, #0x80000000\n\t"
10975 "jne,s done\n\t"
10976 "subq rsp, #8\n\t"
10977 "movss [rsp], $src\n\t"
10978 "call f2i_fixup\n\t"
10979 "popq $dst\n"
10980 "done: "%}
10981 opcode(0xF3, 0x0F, 0x2C);
10982 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
10983 f2i_fixup(dst, src));
10984 ins_pipe(pipe_slow);
10985 %}
10986
10987 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10988 %{
10989 match(Set dst (ConvF2L src));
10990 effect(KILL cr);
10991
10992 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
10993 "cmpq $dst, [0x8000000000000000]\n\t"
10994 "jne,s done\n\t"
10995 "subq rsp, #8\n\t"
10996 "movss [rsp], $src\n\t"
10997 "call f2l_fixup\n\t"
10998 "popq $dst\n"
10999 "done: "%}
11000 opcode(0xF3, 0x0F, 0x2C);
11001 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11002 f2l_fixup(dst, src));
11003 ins_pipe(pipe_slow);
11004 %}
11005
11006 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
11007 %{
11008 match(Set dst (ConvD2I src));
11009 effect(KILL cr);
11010
11011 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
11012 "cmpl $dst, #0x80000000\n\t"
11013 "jne,s done\n\t"
11014 "subq rsp, #8\n\t"
11015 "movsd [rsp], $src\n\t"
11016 "call d2i_fixup\n\t"
11017 "popq $dst\n"
11018 "done: "%}
11019 opcode(0xF2, 0x0F, 0x2C);
11020 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
11021 d2i_fixup(dst, src));
11022 ins_pipe(pipe_slow);
11023 %}
11024
11025 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
11026 %{
11027 match(Set dst (ConvD2L src));
11028 effect(KILL cr);
11029
11030 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
11031 "cmpq $dst, [0x8000000000000000]\n\t"
11032 "jne,s done\n\t"
11033 "subq rsp, #8\n\t"
11034 "movsd [rsp], $src\n\t"
11035 "call d2l_fixup\n\t"
11036 "popq $dst\n"
11037 "done: "%}
11038 opcode(0xF2, 0x0F, 0x2C);
11039 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11040 d2l_fixup(dst, src));
11041 ins_pipe(pipe_slow);
11042 %}
11043
11044 instruct convI2F_reg_reg(regF dst, rRegI src)
11045 %{
11046 predicate(!UseXmmI2F);
11047 match(Set dst (ConvI2F src));
11048
11049 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11050 opcode(0xF3, 0x0F, 0x2A);
11051 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11052 ins_pipe(pipe_slow); // XXX
11053 %}
11054
11055 instruct convI2F_reg_mem(regF dst, memory src)
11056 %{
11057 match(Set dst (ConvI2F (LoadI src)));
11058
11059 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11060 opcode(0xF3, 0x0F, 0x2A);
11061 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11062 ins_pipe(pipe_slow); // XXX
11063 %}
11064
11065 instruct convI2D_reg_reg(regD dst, rRegI src)
11066 %{
11067 predicate(!UseXmmI2D);
11068 match(Set dst (ConvI2D src));
11069
11070 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11071 opcode(0xF2, 0x0F, 0x2A);
11072 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11073 ins_pipe(pipe_slow); // XXX
11074 %}
11075
11076 instruct convI2D_reg_mem(regD dst, memory src)
11077 %{
11078 match(Set dst (ConvI2D (LoadI src)));
11079
11080 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11081 opcode(0xF2, 0x0F, 0x2A);
11082 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11083 ins_pipe(pipe_slow); // XXX
11084 %}
11085
11086 instruct convXI2F_reg(regF dst, rRegI src)
11087 %{
11088 predicate(UseXmmI2F);
11089 match(Set dst (ConvI2F src));
11090
11091 format %{ "movdl $dst, $src\n\t"
11092 "cvtdq2psl $dst, $dst\t# i2f" %}
11093 ins_encode %{
11094 __ movdl($dst$$XMMRegister, $src$$Register);
11095 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
11096 %}
11097 ins_pipe(pipe_slow); // XXX
11098 %}
11099
11100 instruct convXI2D_reg(regD dst, rRegI src)
11101 %{
11102 predicate(UseXmmI2D);
11103 match(Set dst (ConvI2D src));
11104
11105 format %{ "movdl $dst, $src\n\t"
11106 "cvtdq2pdl $dst, $dst\t# i2d" %}
11107 ins_encode %{
11108 __ movdl($dst$$XMMRegister, $src$$Register);
11109 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
11110 %}
11111 ins_pipe(pipe_slow); // XXX
11112 %}
11113
11114 instruct convL2F_reg_reg(regF dst, rRegL src)
11115 %{
11116 match(Set dst (ConvL2F src));
11117
11118 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11119 opcode(0xF3, 0x0F, 0x2A);
11120 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11121 ins_pipe(pipe_slow); // XXX
11122 %}
11123
11124 instruct convL2F_reg_mem(regF dst, memory src)
11125 %{
11126 match(Set dst (ConvL2F (LoadL src)));
11127
11128 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11129 opcode(0xF3, 0x0F, 0x2A);
11130 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11131 ins_pipe(pipe_slow); // XXX
11132 %}
11133
11134 instruct convL2D_reg_reg(regD dst, rRegL src)
11135 %{
11136 match(Set dst (ConvL2D src));
11137
11138 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11139 opcode(0xF2, 0x0F, 0x2A);
11140 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11141 ins_pipe(pipe_slow); // XXX
11142 %}
11143
11144 instruct convL2D_reg_mem(regD dst, memory src)
11145 %{
11146 match(Set dst (ConvL2D (LoadL src)));
11147
11148 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11149 opcode(0xF2, 0x0F, 0x2A);
11150 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11151 ins_pipe(pipe_slow); // XXX
11152 %}
11153
11154 instruct convI2L_reg_reg(rRegL dst, rRegI src)
11155 %{
11156 match(Set dst (ConvI2L src));
11157
11158 ins_cost(125);
11159 format %{ "movslq $dst, $src\t# i2l" %}
11160 ins_encode %{
11161 __ movslq($dst$$Register, $src$$Register);
11162 %}
11163 ins_pipe(ialu_reg_reg);
11164 %}
11165
11166 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
11167 // %{
11168 // match(Set dst (ConvI2L src));
11169 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
11170 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
11171 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
11172 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
11173 // ((const TypeNode*) n)->type()->is_long()->_lo ==
11174 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
11175
11176 // format %{ "movl $dst, $src\t# unsigned i2l" %}
11177 // ins_encode(enc_copy(dst, src));
11178 // // opcode(0x63); // needs REX.W
11179 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
11180 // ins_pipe(ialu_reg_reg);
11181 // %}
11182
11183 // Zero-extend convert int to long
11184 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
11185 %{
11186 match(Set dst (AndL (ConvI2L src) mask));
11187
11188 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11189 ins_encode(enc_copy(dst, src));
11190 ins_pipe(ialu_reg_reg);
11191 %}
11192
11193 // Zero-extend convert int to long
11194 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
11195 %{
11196 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
11197
11198 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11199 opcode(0x8B);
11200 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11201 ins_pipe(ialu_reg_mem);
11202 %}
11203
11204 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
11205 %{
11206 match(Set dst (AndL src mask));
11207
11208 format %{ "movl $dst, $src\t# zero-extend long" %}
11209 ins_encode(enc_copy_always(dst, src));
11210 ins_pipe(ialu_reg_reg);
11211 %}
11212
11213 instruct convL2I_reg_reg(rRegI dst, rRegL src)
11214 %{
11215 match(Set dst (ConvL2I src));
11216
11217 format %{ "movl $dst, $src\t# l2i" %}
11218 ins_encode(enc_copy_always(dst, src));
11219 ins_pipe(ialu_reg_reg);
11220 %}
11221
11222
11223 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11224 match(Set dst (MoveF2I src));
11225 effect(DEF dst, USE src);
11226
11227 ins_cost(125);
11228 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
11229 opcode(0x8B);
11230 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11231 ins_pipe(ialu_reg_mem);
11232 %}
11233
11234 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
11235 match(Set dst (MoveI2F src));
11236 effect(DEF dst, USE src);
11237
11238 ins_cost(125);
11239 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
11240 opcode(0xF3, 0x0F, 0x10);
11241 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11242 ins_pipe(pipe_slow);
11243 %}
11244
11245 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
11246 match(Set dst (MoveD2L src));
11247 effect(DEF dst, USE src);
11248
11249 ins_cost(125);
11250 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
11251 opcode(0x8B);
11252 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
11253 ins_pipe(ialu_reg_mem);
11254 %}
11255
11256 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
11257 predicate(!UseXmmLoadAndClearUpper);
11258 match(Set dst (MoveL2D src));
11259 effect(DEF dst, USE src);
11260
11261 ins_cost(125);
11262 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
11263 opcode(0x66, 0x0F, 0x12);
11264 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11265 ins_pipe(pipe_slow);
11266 %}
11267
11268 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
11269 predicate(UseXmmLoadAndClearUpper);
11270 match(Set dst (MoveL2D src));
11271 effect(DEF dst, USE src);
11272
11273 ins_cost(125);
11274 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
11275 opcode(0xF2, 0x0F, 0x10);
11276 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11277 ins_pipe(pipe_slow);
11278 %}
11279
11280
11281 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
11282 match(Set dst (MoveF2I src));
11283 effect(DEF dst, USE src);
11284
11285 ins_cost(95); // XXX
11286 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
11287 opcode(0xF3, 0x0F, 0x11);
11288 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11289 ins_pipe(pipe_slow);
11290 %}
11291
11292 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
11293 match(Set dst (MoveI2F src));
11294 effect(DEF dst, USE src);
11295
11296 ins_cost(100);
11297 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
11298 opcode(0x89);
11299 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
11300 ins_pipe( ialu_mem_reg );
11301 %}
11302
11303 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
11304 match(Set dst (MoveD2L src));
11305 effect(DEF dst, USE src);
11306
11307 ins_cost(95); // XXX
11308 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
11309 opcode(0xF2, 0x0F, 0x11);
11310 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11311 ins_pipe(pipe_slow);
11312 %}
11313
11314 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
11315 match(Set dst (MoveL2D src));
11316 effect(DEF dst, USE src);
11317
11318 ins_cost(100);
11319 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
11320 opcode(0x89);
11321 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
11322 ins_pipe(ialu_mem_reg);
11323 %}
11324
11325 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
11326 match(Set dst (MoveF2I src));
11327 effect(DEF dst, USE src);
11328 ins_cost(85);
11329 format %{ "movd $dst,$src\t# MoveF2I" %}
11330 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %}
11331 ins_pipe( pipe_slow );
11332 %}
11333
11334 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
11335 match(Set dst (MoveD2L src));
11336 effect(DEF dst, USE src);
11337 ins_cost(85);
11338 format %{ "movd $dst,$src\t# MoveD2L" %}
11339 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %}
11340 ins_pipe( pipe_slow );
11341 %}
11342
11343 // The next instructions have long latency and use Int unit. Set high cost.
11344 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
11345 match(Set dst (MoveI2F src));
11346 effect(DEF dst, USE src);
11347 ins_cost(300);
11348 format %{ "movd $dst,$src\t# MoveI2F" %}
11349 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %}
11350 ins_pipe( pipe_slow );
11351 %}
11352
11353 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
11354 match(Set dst (MoveL2D src));
11355 effect(DEF dst, USE src);
11356 ins_cost(300);
11357 format %{ "movd $dst,$src\t# MoveL2D" %}
11358 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %}
11359 ins_pipe( pipe_slow );
11360 %}
11361
11362 // Replicate scalar to packed byte (1 byte) values in xmm
11363 instruct Repl8B_reg(regD dst, regD src) %{
11364 match(Set dst (Replicate8B src));
11365 format %{ "MOVDQA $dst,$src\n\t"
11366 "PUNPCKLBW $dst,$dst\n\t"
11367 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11368 ins_encode( pshufd_8x8(dst, src));
11369 ins_pipe( pipe_slow );
11370 %}
11371
11372 // Replicate scalar to packed byte (1 byte) values in xmm
11373 instruct Repl8B_rRegI(regD dst, rRegI src) %{
11374 match(Set dst (Replicate8B src));
11375 format %{ "MOVD $dst,$src\n\t"
11376 "PUNPCKLBW $dst,$dst\n\t"
11377 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11378 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst));
11379 ins_pipe( pipe_slow );
11380 %}
11381
11382 // Replicate scalar zero to packed byte (1 byte) values in xmm
11383 instruct Repl8B_immI0(regD dst, immI0 zero) %{
11384 match(Set dst (Replicate8B zero));
11385 format %{ "PXOR $dst,$dst\t! replicate8B" %}
11386 ins_encode( pxor(dst, dst));
11387 ins_pipe( fpu_reg_reg );
11388 %}
11389
11390 // Replicate scalar to packed shore (2 byte) values in xmm
11391 instruct Repl4S_reg(regD dst, regD src) %{
11392 match(Set dst (Replicate4S src));
11393 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
11394 ins_encode( pshufd_4x16(dst, src));
11395 ins_pipe( fpu_reg_reg );
11396 %}
11397
11398 // Replicate scalar to packed shore (2 byte) values in xmm
11399 instruct Repl4S_rRegI(regD dst, rRegI src) %{
11400 match(Set dst (Replicate4S src));
11401 format %{ "MOVD $dst,$src\n\t"
11402 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
11403 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11404 ins_pipe( fpu_reg_reg );
11405 %}
11406
11407 // Replicate scalar zero to packed short (2 byte) values in xmm
11408 instruct Repl4S_immI0(regD dst, immI0 zero) %{
11409 match(Set dst (Replicate4S zero));
11410 format %{ "PXOR $dst,$dst\t! replicate4S" %}
11411 ins_encode( pxor(dst, dst));
11412 ins_pipe( fpu_reg_reg );
11413 %}
11414
11415 // Replicate scalar to packed char (2 byte) values in xmm
11416 instruct Repl4C_reg(regD dst, regD src) %{
11417 match(Set dst (Replicate4C src));
11418 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
11419 ins_encode( pshufd_4x16(dst, src));
11420 ins_pipe( fpu_reg_reg );
11421 %}
11422
11423 // Replicate scalar to packed char (2 byte) values in xmm
11424 instruct Repl4C_rRegI(regD dst, rRegI src) %{
11425 match(Set dst (Replicate4C src));
11426 format %{ "MOVD $dst,$src\n\t"
11427 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
11428 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11429 ins_pipe( fpu_reg_reg );
11430 %}
11431
11432 // Replicate scalar zero to packed char (2 byte) values in xmm
11433 instruct Repl4C_immI0(regD dst, immI0 zero) %{
11434 match(Set dst (Replicate4C zero));
11435 format %{ "PXOR $dst,$dst\t! replicate4C" %}
11436 ins_encode( pxor(dst, dst));
11437 ins_pipe( fpu_reg_reg );
11438 %}
11439
11440 // Replicate scalar to packed integer (4 byte) values in xmm
11441 instruct Repl2I_reg(regD dst, regD src) %{
11442 match(Set dst (Replicate2I src));
11443 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
11444 ins_encode( pshufd(dst, src, 0x00));
11445 ins_pipe( fpu_reg_reg );
11446 %}
11447
11448 // Replicate scalar to packed integer (4 byte) values in xmm
11449 instruct Repl2I_rRegI(regD dst, rRegI src) %{
11450 match(Set dst (Replicate2I src));
11451 format %{ "MOVD $dst,$src\n\t"
11452 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
11453 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00));
11454 ins_pipe( fpu_reg_reg );
11455 %}
11456
11457 // Replicate scalar zero to packed integer (2 byte) values in xmm
11458 instruct Repl2I_immI0(regD dst, immI0 zero) %{
11459 match(Set dst (Replicate2I zero));
11460 format %{ "PXOR $dst,$dst\t! replicate2I" %}
11461 ins_encode( pxor(dst, dst));
11462 ins_pipe( fpu_reg_reg );
11463 %}
11464
11465 // Replicate scalar to packed single precision floating point values in xmm
11466 instruct Repl2F_reg(regD dst, regD src) %{
11467 match(Set dst (Replicate2F src));
11468 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11469 ins_encode( pshufd(dst, src, 0xe0));
11470 ins_pipe( fpu_reg_reg );
11471 %}
11472
11473 // Replicate scalar to packed single precision floating point values in xmm
11474 instruct Repl2F_regF(regD dst, regF src) %{
11475 match(Set dst (Replicate2F src));
11476 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11477 ins_encode( pshufd(dst, src, 0xe0));
11478 ins_pipe( fpu_reg_reg );
11479 %}
11480
11481 // Replicate scalar to packed single precision floating point values in xmm
11482 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11483 match(Set dst (Replicate2F zero));
11484 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11485 ins_encode( pxor(dst, dst));
11486 ins_pipe( fpu_reg_reg );
11487 %}
11488
11489
11490 // =======================================================================
11491 // fast clearing of an array
11492 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
11493 rFlagsReg cr)
11494 %{
11495 match(Set dummy (ClearArray cnt base));
11496 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11497
11498 format %{ "xorl rax, rax\t# ClearArray:\n\t"
11499 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
11500 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
11501 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
11502 ins_pipe(pipe_slow);
11503 %}
11504
11505 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
|
535 XMM9, XMM9_H,
536 XMM10, XMM10_H,
537 XMM11, XMM11_H,
538 XMM12, XMM12_H,
539 XMM13, XMM13_H,
540 XMM14, XMM14_H,
541 XMM15, XMM15_H);
542 %}
543
544
545 //----------SOURCE BLOCK-------------------------------------------------------
546 // This is a block of C++ code which provides values, functions, and
547 // definitions necessary in the rest of the architecture description
548 source %{
549 #define RELOC_IMM64 Assembler::imm_operand
550 #define RELOC_DISP32 Assembler::disp32_operand
551
552 #define __ _masm.
553
554 static int preserve_SP_size() {
555 return 3; // rex.w, op, rm(reg/reg)
556 }
557
558 // !!!!! Special hack to get all types of calls to specify the byte offset
559 // from the start of the call to the point where the return address
560 // will point.
561 int MachCallStaticJavaNode::ret_addr_offset()
562 {
563 int offset = 5; // 5 bytes from start of call to where return address points
564 if (_method_handle_invoke)
565 offset += preserve_SP_size();
566 return offset;
567 }
568
569 int MachCallDynamicJavaNode::ret_addr_offset()
570 {
571 return 15; // 15 bytes from start of call to where return address points
572 }
573
574 // In os_cpu .ad file
575 // int MachCallRuntimeNode::ret_addr_offset()
780 emit_d8(cbuf, disp);
781 } else {
782 // If 32-bit displacement
783 if (base == 0x04 ) {
784 emit_rm(cbuf, 0x2, regenc, 0x4);
785 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
786 } else {
787 emit_rm(cbuf, 0x2, regenc, 0x4);
788 emit_rm(cbuf, scale, indexenc, baseenc); // *
789 }
790 if (disp_is_oop) {
791 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
792 } else {
793 emit_d32(cbuf, disp);
794 }
795 }
796 }
797 }
798 }
799
800 // This could be in MacroAssembler but it's fairly C2 specific
801 void emit_cmpfp_fixup(MacroAssembler& _masm) {
802 Label exit;
803 __ jccb(Assembler::noParity, exit);
804 __ pushf();
805 //
806 // comiss/ucomiss instructions set ZF,PF,CF flags and
807 // zero OF,AF,SF for NaN values.
808 // Fixup flags by zeroing ZF,PF so that compare of NaN
809 // values returns 'less than' result (CF is set).
810 // Leave the rest of flags unchanged.
811 //
812 // 7 6 5 4 3 2 1 0
813 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
814 // 0 0 1 0 1 0 1 1 (0x2B)
815 //
816 __ andq(Address(rsp, 0), 0xffffff2b);
817 __ popf();
818 __ bind(exit);
819 }
820
821 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
822 Label done;
823 __ movl(dst, -1);
824 __ jcc(Assembler::parity, done);
825 __ jcc(Assembler::below, done);
826 __ setb(Assembler::notEqual, dst);
827 __ movzbl(dst, dst);
828 __ bind(done);
829 }
830
831
832 //=============================================================================
833 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
834
835 int Compile::ConstantTable::calculate_table_base_offset() const {
836 return 0; // absolute addressing, no offset
837 }
838
839 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
840 // Empty encoding
841 }
842
843 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
844 return 0;
845 }
846
847 #ifndef PRODUCT
848 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
849 st->print("# MachConstantBaseNode (empty encoding)");
850 }
851 #endif
1244 #ifndef PRODUCT
1245 } else if (!do_size) {
1246 st->print("movl %s, [rsp + #%d]\t# spill",
1247 Matcher::regName[dst_first],
1248 offset);
1249 #endif
1250 }
1251 return
1252 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1253 ((Matcher::_regEncode[dst_first] < 8)
1254 ? 3
1255 : 4); // REX
1256 }
1257 } else if (dst_first_rc == rc_float) {
1258 // mem-> xmm
1259 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1260 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1261 // 64-bit
1262 int offset = ra_->reg2offset(src_first);
1263 if (cbuf) {
1264 MacroAssembler _masm(cbuf);
1265 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1266 #ifndef PRODUCT
1267 } else if (!do_size) {
1268 st->print("%s %s, [rsp + #%d]\t# spill",
1269 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1270 Matcher::regName[dst_first],
1271 offset);
1272 #endif
1273 }
1274 return
1275 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1276 ((Matcher::_regEncode[dst_first] >= 8)
1277 ? 6
1278 : (5 + ((UseAVX>0)?1:0))); // REX
1279 } else {
1280 // 32-bit
1281 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1282 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1283 int offset = ra_->reg2offset(src_first);
1284 if (cbuf) {
1285 MacroAssembler _masm(cbuf);
1286 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1287 #ifndef PRODUCT
1288 } else if (!do_size) {
1289 st->print("movss %s, [rsp + #%d]\t# spill",
1290 Matcher::regName[dst_first],
1291 offset);
1292 #endif
1293 }
1294 return
1295 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1296 ((Matcher::_regEncode[dst_first] >= 8)
1297 ? 6
1298 : (5 + ((UseAVX>0)?1:0))); // REX
1299 }
1300 }
1301 } else if (src_first_rc == rc_int) {
1302 // gpr ->
1303 if (dst_first_rc == rc_stack) {
1304 // gpr -> mem
1305 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1306 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1307 // 64-bit
1308 int offset = ra_->reg2offset(dst_first);
1309 if (cbuf) {
1310 if (Matcher::_regEncode[src_first] < 8) {
1311 emit_opcode(*cbuf, Assembler::REX_W);
1312 } else {
1313 emit_opcode(*cbuf, Assembler::REX_WR);
1314 }
1315 emit_opcode(*cbuf, 0x89);
1316 encode_RegMem(*cbuf,
1317 Matcher::_regEncode[src_first],
1318 RSP_enc, 0x4, 0, offset,
1404 Matcher::_regEncode[dst_first] & 7,
1405 Matcher::_regEncode[src_first] & 7);
1406 #ifndef PRODUCT
1407 } else if (!do_size) {
1408 st->print("movl %s, %s\t# spill",
1409 Matcher::regName[dst_first],
1410 Matcher::regName[src_first]);
1411 #endif
1412 }
1413 return
1414 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1415 ? 2
1416 : 3; // REX
1417 }
1418 } else if (dst_first_rc == rc_float) {
1419 // gpr -> xmm
1420 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1421 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1422 // 64-bit
1423 if (cbuf) {
1424 MacroAssembler _masm(cbuf);
1425 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1426 #ifndef PRODUCT
1427 } else if (!do_size) {
1428 st->print("movdq %s, %s\t# spill",
1429 Matcher::regName[dst_first],
1430 Matcher::regName[src_first]);
1431 #endif
1432 }
1433 return 5; // REX
1434 } else {
1435 // 32-bit
1436 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1437 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1438 if (cbuf) {
1439 MacroAssembler _masm(cbuf);
1440 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1441 #ifndef PRODUCT
1442 } else if (!do_size) {
1443 st->print("movdl %s, %s\t# spill",
1444 Matcher::regName[dst_first],
1445 Matcher::regName[src_first]);
1446 #endif
1447 }
1448 return
1449 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1450 ? 5
1451 : (4 + ((UseAVX>0)?1:0)); // REX
1452 }
1453 }
1454 } else if (src_first_rc == rc_float) {
1455 // xmm ->
1456 if (dst_first_rc == rc_stack) {
1457 // xmm -> mem
1458 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1459 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1460 // 64-bit
1461 int offset = ra_->reg2offset(dst_first);
1462 if (cbuf) {
1463 MacroAssembler _masm(cbuf);
1464 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1465 #ifndef PRODUCT
1466 } else if (!do_size) {
1467 st->print("movsd [rsp + #%d], %s\t# spill",
1468 offset,
1469 Matcher::regName[src_first]);
1470 #endif
1471 }
1472 return
1473 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1474 ((Matcher::_regEncode[src_first] >= 8)
1475 ? 6
1476 : (5 + ((UseAVX>0)?1:0))); // REX
1477 } else {
1478 // 32-bit
1479 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1480 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1481 int offset = ra_->reg2offset(dst_first);
1482 if (cbuf) {
1483 MacroAssembler _masm(cbuf);
1484 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1485 #ifndef PRODUCT
1486 } else if (!do_size) {
1487 st->print("movss [rsp + #%d], %s\t# spill",
1488 offset,
1489 Matcher::regName[src_first]);
1490 #endif
1491 }
1492 return
1493 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1494 ((Matcher::_regEncode[src_first] >=8)
1495 ? 6
1496 : (5 + ((UseAVX>0)?1:0))); // REX
1497 }
1498 } else if (dst_first_rc == rc_int) {
1499 // xmm -> gpr
1500 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1501 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1502 // 64-bit
1503 if (cbuf) {
1504 MacroAssembler _masm(cbuf);
1505 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1506 #ifndef PRODUCT
1507 } else if (!do_size) {
1508 st->print("movdq %s, %s\t# spill",
1509 Matcher::regName[dst_first],
1510 Matcher::regName[src_first]);
1511 #endif
1512 }
1513 return 5; // REX
1514 } else {
1515 // 32-bit
1516 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1517 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1518 if (cbuf) {
1519 MacroAssembler _masm(cbuf);
1520 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1521 #ifndef PRODUCT
1522 } else if (!do_size) {
1523 st->print("movdl %s, %s\t# spill",
1524 Matcher::regName[dst_first],
1525 Matcher::regName[src_first]);
1526 #endif
1527 }
1528 return
1529 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1530 ? 5
1531 : (4 + ((UseAVX>0)?1:0)); // REX
1532 }
1533 } else if (dst_first_rc == rc_float) {
1534 // xmm -> xmm
1535 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1536 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1537 // 64-bit
1538 if (cbuf) {
1539 MacroAssembler _masm(cbuf);
1540 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1541 #ifndef PRODUCT
1542 } else if (!do_size) {
1543 st->print("%s %s, %s\t# spill",
1544 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1545 Matcher::regName[dst_first],
1546 Matcher::regName[src_first]);
1547 #endif
1548 }
1549 return
1550 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1551 ? 5
1552 : (4 + ((UseAVX>0)?1:0)); // REX
1553 } else {
1554 // 32-bit
1555 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1556 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1557 if (cbuf) {
1558 MacroAssembler _masm(cbuf);
1559 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1560 #ifndef PRODUCT
1561 } else if (!do_size) {
1562 st->print("%s %s, %s\t# spill",
1563 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1564 Matcher::regName[dst_first],
1565 Matcher::regName[src_first]);
1566 #endif
1567 }
1568 return ((UseAVX>0) ? 5:
1569 ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1570 ? (UseXmmRegToRegMoveAll ? 4 : 5)
1571 : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX
1572 }
1573 }
1574 }
1575
1576 assert(0," foo ");
1577 Unimplemented();
1578
1579 return 0;
1580 }
1581
1582 #ifndef PRODUCT
1583 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
1584 {
1585 implementation(NULL, ra_, false, st);
1586 }
1587 #endif
1588
1589 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
1590 {
1591 implementation(&cbuf, ra_, false, NULL);
2048 %{
2049 emit_opcode(cbuf, 0x66);
2050 %}
2051
2052 enc_class reg(rRegI reg)
2053 %{
2054 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
2055 %}
2056
2057 enc_class reg_reg(rRegI dst, rRegI src)
2058 %{
2059 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2060 %}
2061
2062 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
2063 %{
2064 emit_opcode(cbuf, $opcode$$constant);
2065 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2066 %}
2067
2068 enc_class cdql_enc(no_rax_rdx_RegI div)
2069 %{
2070 // Full implementation of Java idiv and irem; checks for
2071 // special case as described in JVM spec., p.243 & p.271.
2072 //
2073 // normal case special case
2074 //
2075 // input : rax: dividend min_int
2076 // reg: divisor -1
2077 //
2078 // output: rax: quotient (= rax idiv reg) min_int
2079 // rdx: remainder (= rax irem reg) 0
2080 //
2081 // Code sequnce:
2082 //
2083 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
2084 // 5: 75 07/08 jne e <normal>
2085 // 7: 33 d2 xor %edx,%edx
2086 // [div >= 8 -> offset + 1]
2087 // [REX_B]
2274
2275 enc_class opc3_reg(rRegI dst)
2276 %{
2277 // BSWAP
2278 emit_cc(cbuf, $tertiary, $dst$$reg);
2279 %}
2280
2281 enc_class reg_opc(rRegI div)
2282 %{
2283 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2284 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2285 %}
2286
2287 enc_class enc_cmov(cmpOp cop)
2288 %{
2289 // CMOV
2290 $$$emit8$primary;
2291 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2292 %}
2293
2294 enc_class enc_PartialSubtypeCheck()
2295 %{
2296 Register Rrdi = as_Register(RDI_enc); // result register
2297 Register Rrax = as_Register(RAX_enc); // super class
2298 Register Rrcx = as_Register(RCX_enc); // killed
2299 Register Rrsi = as_Register(RSI_enc); // sub class
2300 Label miss;
2301 const bool set_cond_codes = true;
2302
2303 MacroAssembler _masm(&cbuf);
2304 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2305 NULL, &miss,
2306 /*set_cond_codes:*/ true);
2307 if ($primary) {
2308 __ xorptr(Rrdi, Rrdi);
2309 }
2310 __ bind(miss);
2311 %}
2312
2313 enc_class Java_To_Interpreter(method meth)
2504 %}
2505
2506 enc_class load_immP(rRegP dst, immP src)
2507 %{
2508 int dstenc = $dst$$reg;
2509 if (dstenc < 8) {
2510 emit_opcode(cbuf, Assembler::REX_W);
2511 } else {
2512 emit_opcode(cbuf, Assembler::REX_WB);
2513 dstenc -= 8;
2514 }
2515 emit_opcode(cbuf, 0xB8 | dstenc);
2516 // This next line should be generated from ADLC
2517 if ($src->constant_is_oop()) {
2518 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2519 } else {
2520 emit_d64(cbuf, $src$$constant);
2521 }
2522 %}
2523
2524 enc_class Con32(immI src)
2525 %{
2526 // Output immediate
2527 $$$emit32$src$$constant;
2528 %}
2529
2530 enc_class Con64(immL src)
2531 %{
2532 // Output immediate
2533 emit_d64($src$$constant);
2534 %}
2535
2536 enc_class Con32F_as_bits(immF src)
2537 %{
2538 // Output Float immediate bits
2539 jfloat jf = $src$$constant;
2540 jint jf_as_bits = jint_cast(jf);
2541 emit_d32(cbuf, jf_as_bits);
2542 %}
2543
2903 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2904
2905 // setne $dst
2906 if (dstenc >= 4) {
2907 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2908 }
2909 emit_opcode(cbuf, 0x0F);
2910 emit_opcode(cbuf, 0x95);
2911 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2912
2913 // movzbl $dst, $dst
2914 if (dstenc >= 4) {
2915 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2916 }
2917 emit_opcode(cbuf, 0x0F);
2918 emit_opcode(cbuf, 0xB6);
2919 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2920 %}
2921
2922 enc_class Push_ResultXD(regD dst) %{
2923 MacroAssembler _masm(&cbuf);
2924 __ fstp_d(Address(rsp, 0));
2925 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2926 __ addptr(rsp, 8);
2927 %}
2928
2929 enc_class Push_SrcXD(regD src) %{
2930 MacroAssembler _masm(&cbuf);
2931 __ subptr(rsp, 8);
2932 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2933 __ fld_d(Address(rsp, 0));
2934 %}
2935
2936
2937 // obj: object to lock
2938 // box: box address (header location) -- killed
2939 // tmp: rax -- killed
2940 // scr: rbx -- killed
2941 //
2942 // What follows is a direct transliteration of fast_lock() and fast_unlock()
2943 // from i486.ad. See that file for comments.
2944 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
2945 // use the shorter encoding. (Movl clears the high-order 32-bits).
2946
2947
2948 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
2949 %{
2950 Register objReg = as_Register((int)$obj$$reg);
2951 Register boxReg = as_Register((int)$box$$reg);
2952 Register tmpReg = as_Register($tmp$$reg);
2953 Register scrReg = as_Register($scr$$reg);
2954 MacroAssembler masm(&cbuf);
2955
2956 // Verify uniqueness of register assignments -- necessary but not sufficient
3152 masm.bind (CheckSucc) ;
3153 }
3154 masm.bind(DONE_LABEL);
3155 if (EmitSync & 32768) {
3156 masm.nop(); // avoid branch to branch
3157 }
3158 }
3159 %}
3160
3161
3162 enc_class enc_rethrow()
3163 %{
3164 cbuf.set_insts_mark();
3165 emit_opcode(cbuf, 0xE9); // jmp entry
3166 emit_d32_reloc(cbuf,
3167 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
3168 runtime_call_Relocation::spec(),
3169 RELOC_DISP32);
3170 %}
3171
3172 %}
3173
3174
3175
3176 //----------FRAME--------------------------------------------------------------
3177 // Definition of frame structure and management information.
3178 //
3179 // S T A C K L A Y O U T Allocators stack-slot number
3180 // | (to get allocators register number
3181 // G Owned by | | v add OptoReg::stack0())
3182 // r CALLER | |
3183 // o | +--------+ pad to even-align allocators stack-slot
3184 // w V | pad0 | numbers; owned by CALLER
3185 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3186 // h ^ | in | 5
3187 // | | args | 4 Holes in incoming args owned by SELF
3188 // | | | | 3
3189 // | | +--------+
3190 // V | | old out| Empty on Intel, window on Sparc
3191 // | old |preserve| Must be even aligned.
5477 // Load narrow Klass Pointer
5478 instruct loadNKlass(rRegN dst, memory mem)
5479 %{
5480 match(Set dst (LoadNKlass mem));
5481
5482 ins_cost(125); // XXX
5483 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5484 ins_encode %{
5485 __ movl($dst$$Register, $mem$$Address);
5486 %}
5487 ins_pipe(ialu_reg_mem); // XXX
5488 %}
5489
5490 // Load Float
5491 instruct loadF(regF dst, memory mem)
5492 %{
5493 match(Set dst (LoadF mem));
5494
5495 ins_cost(145); // XXX
5496 format %{ "movss $dst, $mem\t# float" %}
5497 ins_encode %{
5498 __ movflt($dst$$XMMRegister, $mem$$Address);
5499 %}
5500 ins_pipe(pipe_slow); // XXX
5501 %}
5502
5503 // Load Double
5504 instruct loadD_partial(regD dst, memory mem)
5505 %{
5506 predicate(!UseXmmLoadAndClearUpper);
5507 match(Set dst (LoadD mem));
5508
5509 ins_cost(145); // XXX
5510 format %{ "movlpd $dst, $mem\t# double" %}
5511 ins_encode %{
5512 __ movdbl($dst$$XMMRegister, $mem$$Address);
5513 %}
5514 ins_pipe(pipe_slow); // XXX
5515 %}
5516
5517 instruct loadD(regD dst, memory mem)
5518 %{
5519 predicate(UseXmmLoadAndClearUpper);
5520 match(Set dst (LoadD mem));
5521
5522 ins_cost(145); // XXX
5523 format %{ "movsd $dst, $mem\t# double" %}
5524 ins_encode %{
5525 __ movdbl($dst$$XMMRegister, $mem$$Address);
5526 %}
5527 ins_pipe(pipe_slow); // XXX
5528 %}
5529
5530 // Load Aligned Packed Byte to XMM register
5531 instruct loadA8B(regD dst, memory mem) %{
5532 match(Set dst (Load8B mem));
5533 ins_cost(125);
5534 format %{ "MOVQ $dst,$mem\t! packed8B" %}
5535 ins_encode %{
5536 __ movq($dst$$XMMRegister, $mem$$Address);
5537 %}
5538 ins_pipe( pipe_slow );
5539 %}
5540
5541 // Load Aligned Packed Short to XMM register
5542 instruct loadA4S(regD dst, memory mem) %{
5543 match(Set dst (Load4S mem));
5544 ins_cost(125);
5545 format %{ "MOVQ $dst,$mem\t! packed4S" %}
5546 ins_encode %{
5547 __ movq($dst$$XMMRegister, $mem$$Address);
5548 %}
5549 ins_pipe( pipe_slow );
5550 %}
5551
5552 // Load Aligned Packed Char to XMM register
5553 instruct loadA4C(regD dst, memory mem) %{
5554 match(Set dst (Load4C mem));
5555 ins_cost(125);
5556 format %{ "MOVQ $dst,$mem\t! packed4C" %}
5557 ins_encode %{
5558 __ movq($dst$$XMMRegister, $mem$$Address);
5559 %}
5560 ins_pipe( pipe_slow );
5561 %}
5562
5563 // Load Aligned Packed Integer to XMM register
5564 instruct load2IU(regD dst, memory mem) %{
5565 match(Set dst (Load2I mem));
5566 ins_cost(125);
5567 format %{ "MOVQ $dst,$mem\t! packed2I" %}
5568 ins_encode %{
5569 __ movq($dst$$XMMRegister, $mem$$Address);
5570 %}
5571 ins_pipe( pipe_slow );
5572 %}
5573
5574 // Load Aligned Packed Single to XMM
5575 instruct loadA2F(regD dst, memory mem) %{
5576 match(Set dst (Load2F mem));
5577 ins_cost(125);
5578 format %{ "MOVQ $dst,$mem\t! packed2F" %}
5579 ins_encode %{
5580 __ movq($dst$$XMMRegister, $mem$$Address);
5581 %}
5582 ins_pipe( pipe_slow );
5583 %}
5584
5585 // Load Effective Address
5586 instruct leaP8(rRegP dst, indOffset8 mem)
5587 %{
5588 match(Set dst mem);
5589
5590 ins_cost(110); // XXX
5591 format %{ "leaq $dst, $mem\t# ptr 8" %}
5592 opcode(0x8D);
5593 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5594 ins_pipe(ialu_reg_reg_fat);
5595 %}
5596
5597 instruct leaP32(rRegP dst, indOffset32 mem)
5598 %{
5599 match(Set dst mem);
5600
5601 ins_cost(110);
5874
5875 ins_cost(125);
5876 format %{ "movl $dst, $src\t# compressed ptr" %}
5877 ins_encode %{
5878 address con = (address)$src$$constant;
5879 if (con == NULL) {
5880 ShouldNotReachHere();
5881 } else {
5882 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5883 }
5884 %}
5885 ins_pipe(ialu_reg_fat); // XXX
5886 %}
5887
5888 instruct loadConF0(regF dst, immF0 src)
5889 %{
5890 match(Set dst src);
5891 ins_cost(100);
5892
5893 format %{ "xorps $dst, $dst\t# float 0.0" %}
5894 ins_encode %{
5895 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5896 %}
5897 ins_pipe(pipe_slow);
5898 %}
5899
5900 // Use the same format since predicate() can not be used here.
5901 instruct loadConD(regD dst, immD con) %{
5902 match(Set dst con);
5903 ins_cost(125);
5904 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5905 ins_encode %{
5906 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5907 %}
5908 ins_pipe(pipe_slow);
5909 %}
5910
5911 instruct loadConD0(regD dst, immD0 src)
5912 %{
5913 match(Set dst src);
5914 ins_cost(100);
5915
5916 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5917 ins_encode %{
5918 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5919 %}
5920 ins_pipe(pipe_slow);
5921 %}
5922
5923 instruct loadSSI(rRegI dst, stackSlotI src)
5924 %{
5925 match(Set dst src);
5926
5927 ins_cost(125);
5928 format %{ "movl $dst, $src\t# int stk" %}
5929 opcode(0x8B);
5930 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5931 ins_pipe(ialu_reg_mem);
5932 %}
5933
5934 instruct loadSSL(rRegL dst, stackSlotL src)
5935 %{
5936 match(Set dst src);
5937
5938 ins_cost(125);
5939 format %{ "movq $dst, $src\t# long stk" %}
5942 ins_pipe(ialu_reg_mem);
5943 %}
5944
5945 instruct loadSSP(rRegP dst, stackSlotP src)
5946 %{
5947 match(Set dst src);
5948
5949 ins_cost(125);
5950 format %{ "movq $dst, $src\t# ptr stk" %}
5951 opcode(0x8B);
5952 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5953 ins_pipe(ialu_reg_mem);
5954 %}
5955
5956 instruct loadSSF(regF dst, stackSlotF src)
5957 %{
5958 match(Set dst src);
5959
5960 ins_cost(125);
5961 format %{ "movss $dst, $src\t# float stk" %}
5962 ins_encode %{
5963 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5964 %}
5965 ins_pipe(pipe_slow); // XXX
5966 %}
5967
5968 // Use the same format since predicate() can not be used here.
5969 instruct loadSSD(regD dst, stackSlotD src)
5970 %{
5971 match(Set dst src);
5972
5973 ins_cost(125);
5974 format %{ "movsd $dst, $src\t# double stk" %}
5975 ins_encode %{
5976 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5977 %}
5978 ins_pipe(pipe_slow); // XXX
5979 %}
5980
5981 // Prefetch instructions.
5982 // Must be safe to execute with invalid address (cannot fault).
5983
5984 instruct prefetchr( memory mem ) %{
6309 %}
6310 ins_pipe(ialu_mem_reg);
6311 %}
6312
6313 instruct storeImmB(memory mem, immI8 src)
6314 %{
6315 match(Set mem (StoreB mem src));
6316
6317 ins_cost(150); // XXX
6318 format %{ "movb $mem, $src\t# byte" %}
6319 opcode(0xC6); /* C6 /0 */
6320 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6321 ins_pipe(ialu_mem_imm);
6322 %}
6323
6324 // Store Aligned Packed Byte XMM register to memory
6325 instruct storeA8B(memory mem, regD src) %{
6326 match(Set mem (Store8B mem src));
6327 ins_cost(145);
6328 format %{ "MOVQ $mem,$src\t! packed8B" %}
6329 ins_encode %{
6330 __ movq($mem$$Address, $src$$XMMRegister);
6331 %}
6332 ins_pipe( pipe_slow );
6333 %}
6334
6335 // Store Aligned Packed Char/Short XMM register to memory
6336 instruct storeA4C(memory mem, regD src) %{
6337 match(Set mem (Store4C mem src));
6338 ins_cost(145);
6339 format %{ "MOVQ $mem,$src\t! packed4C" %}
6340 ins_encode %{
6341 __ movq($mem$$Address, $src$$XMMRegister);
6342 %}
6343 ins_pipe( pipe_slow );
6344 %}
6345
6346 // Store Aligned Packed Integer XMM register to memory
6347 instruct storeA2I(memory mem, regD src) %{
6348 match(Set mem (Store2I mem src));
6349 ins_cost(145);
6350 format %{ "MOVQ $mem,$src\t! packed2I" %}
6351 ins_encode %{
6352 __ movq($mem$$Address, $src$$XMMRegister);
6353 %}
6354 ins_pipe( pipe_slow );
6355 %}
6356
6357 // Store CMS card-mark Immediate
6358 instruct storeImmCM0_reg(memory mem, immI0 zero)
6359 %{
6360 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6361 match(Set mem (StoreCM mem zero));
6362
6363 ins_cost(125); // XXX
6364 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6365 ins_encode %{
6366 __ movb($mem$$Address, r12);
6367 %}
6368 ins_pipe(ialu_mem_reg);
6369 %}
6370
6371 instruct storeImmCM0(memory mem, immI0 src)
6372 %{
6373 match(Set mem (StoreCM mem src));
6374
6375 ins_cost(150); // XXX
6376 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
6377 opcode(0xC6); /* C6 /0 */
6378 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6379 ins_pipe(ialu_mem_imm);
6380 %}
6381
6382 // Store Aligned Packed Single Float XMM register to memory
6383 instruct storeA2F(memory mem, regD src) %{
6384 match(Set mem (Store2F mem src));
6385 ins_cost(145);
6386 format %{ "MOVQ $mem,$src\t! packed2F" %}
6387 ins_encode %{
6388 __ movq($mem$$Address, $src$$XMMRegister);
6389 %}
6390 ins_pipe( pipe_slow );
6391 %}
6392
6393 // Store Float
6394 instruct storeF(memory mem, regF src)
6395 %{
6396 match(Set mem (StoreF mem src));
6397
6398 ins_cost(95); // XXX
6399 format %{ "movss $mem, $src\t# float" %}
6400 ins_encode %{
6401 __ movflt($mem$$Address, $src$$XMMRegister);
6402 %}
6403 ins_pipe(pipe_slow); // XXX
6404 %}
6405
6406 // Store immediate Float value (it is faster than store from XMM register)
6407 instruct storeF0(memory mem, immF0 zero)
6408 %{
6409 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6410 match(Set mem (StoreF mem zero));
6411
6412 ins_cost(25); // XXX
6413 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6414 ins_encode %{
6415 __ movl($mem$$Address, r12);
6416 %}
6417 ins_pipe(ialu_mem_reg);
6418 %}
6419
6420 instruct storeF_imm(memory mem, immF src)
6421 %{
6422 match(Set mem (StoreF mem src));
6423
6424 ins_cost(50);
6425 format %{ "movl $mem, $src\t# float" %}
6426 opcode(0xC7); /* C7 /0 */
6427 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6428 ins_pipe(ialu_mem_imm);
6429 %}
6430
6431 // Store Double
6432 instruct storeD(memory mem, regD src)
6433 %{
6434 match(Set mem (StoreD mem src));
6435
6436 ins_cost(95); // XXX
6437 format %{ "movsd $mem, $src\t# double" %}
6438 ins_encode %{
6439 __ movdbl($mem$$Address, $src$$XMMRegister);
6440 %}
6441 ins_pipe(pipe_slow); // XXX
6442 %}
6443
6444 // Store immediate double 0.0 (it is faster than store from XMM register)
6445 instruct storeD0_imm(memory mem, immD0 src)
6446 %{
6447 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
6448 match(Set mem (StoreD mem src));
6449
6450 ins_cost(50);
6451 format %{ "movq $mem, $src\t# double 0." %}
6452 opcode(0xC7); /* C7 /0 */
6453 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6454 ins_pipe(ialu_mem_imm);
6455 %}
6456
6457 instruct storeD0(memory mem, immD0 zero)
6458 %{
6459 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6460 match(Set mem (StoreD mem zero));
6489 ins_pipe(ialu_mem_reg);
6490 %}
6491
6492 instruct storeSSP(stackSlotP dst, rRegP src)
6493 %{
6494 match(Set dst src);
6495
6496 ins_cost(100);
6497 format %{ "movq $dst, $src\t# ptr stk" %}
6498 opcode(0x89);
6499 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6500 ins_pipe(ialu_mem_reg);
6501 %}
6502
6503 instruct storeSSF(stackSlotF dst, regF src)
6504 %{
6505 match(Set dst src);
6506
6507 ins_cost(95); // XXX
6508 format %{ "movss $dst, $src\t# float stk" %}
6509 ins_encode %{
6510 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6511 %}
6512 ins_pipe(pipe_slow); // XXX
6513 %}
6514
6515 instruct storeSSD(stackSlotD dst, regD src)
6516 %{
6517 match(Set dst src);
6518
6519 ins_cost(95); // XXX
6520 format %{ "movsd $dst, $src\t# double stk" %}
6521 ins_encode %{
6522 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6523 %}
6524 ins_pipe(pipe_slow); // XXX
6525 %}
6526
6527 //----------BSWAP Instructions-------------------------------------------------
6528 instruct bytes_reverse_int(rRegI dst) %{
6529 match(Set dst (ReverseBytesI dst));
6530
6531 format %{ "bswapl $dst" %}
6532 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
6533 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
6534 ins_pipe( ialu_reg );
6535 %}
6536
6537 instruct bytes_reverse_long(rRegL dst) %{
6538 match(Set dst (ReverseBytesL dst));
6539
6540 format %{ "bswapq $dst" %}
6541
6542 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
6543 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
6800
6801 instruct unnecessary_membar_volatile()
6802 %{
6803 match(MemBarVolatile);
6804 predicate(Matcher::post_store_load_barrier(n));
6805 ins_cost(0);
6806
6807 size(0);
6808 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6809 ins_encode();
6810 ins_pipe(empty);
6811 %}
6812
6813 //----------Move Instructions--------------------------------------------------
6814
6815 instruct castX2P(rRegP dst, rRegL src)
6816 %{
6817 match(Set dst (CastX2P src));
6818
6819 format %{ "movq $dst, $src\t# long->ptr" %}
6820 ins_encode %{
6821 __ movptr($dst$$Register, $src$$Register);
6822 %}
6823 ins_pipe(ialu_reg_reg); // XXX
6824 %}
6825
6826 instruct castP2X(rRegL dst, rRegP src)
6827 %{
6828 match(Set dst (CastP2X src));
6829
6830 format %{ "movq $dst, $src\t# ptr -> long" %}
6831 ins_encode %{
6832 __ movptr($dst$$Register, $src$$Register);
6833 %}
6834 ins_pipe(ialu_reg_reg); // XXX
6835 %}
6836
6837
6838 // Convert oop pointer into compressed form
6839 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6840 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6841 match(Set dst (EncodeP src));
6842 effect(KILL cr);
6843 format %{ "encode_heap_oop $dst,$src" %}
6844 ins_encode %{
6845 Register s = $src$$Register;
6846 Register d = $dst$$Register;
6847 if (s != d) {
6848 __ movq(d, s);
6849 }
6850 __ encode_heap_oop(d);
6851 %}
6852 ins_pipe(ialu_reg_long);
6853 %}
7166 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7167 ins_pipe(pipe_cmov_mem); // XXX
7168 %}
7169
7170 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7171 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7172 ins_cost(200);
7173 expand %{
7174 cmovL_memU(cop, cr, dst, src);
7175 %}
7176 %}
7177
7178 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7179 %{
7180 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7181
7182 ins_cost(200); // XXX
7183 format %{ "jn$cop skip\t# signed cmove float\n\t"
7184 "movss $dst, $src\n"
7185 "skip:" %}
7186 ins_encode %{
7187 Label Lskip;
7188 // Invert sense of branch from sense of CMOV
7189 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7190 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7191 __ bind(Lskip);
7192 %}
7193 ins_pipe(pipe_slow);
7194 %}
7195
7196 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7197 // %{
7198 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7199
7200 // ins_cost(200); // XXX
7201 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7202 // "movss $dst, $src\n"
7203 // "skip:" %}
7204 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7205 // ins_pipe(pipe_slow);
7206 // %}
7207
7208 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7209 %{
7210 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7211
7212 ins_cost(200); // XXX
7213 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7214 "movss $dst, $src\n"
7215 "skip:" %}
7216 ins_encode %{
7217 Label Lskip;
7218 // Invert sense of branch from sense of CMOV
7219 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7220 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7221 __ bind(Lskip);
7222 %}
7223 ins_pipe(pipe_slow);
7224 %}
7225
7226 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7227 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7228 ins_cost(200);
7229 expand %{
7230 cmovF_regU(cop, cr, dst, src);
7231 %}
7232 %}
7233
7234 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7235 %{
7236 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7237
7238 ins_cost(200); // XXX
7239 format %{ "jn$cop skip\t# signed cmove double\n\t"
7240 "movsd $dst, $src\n"
7241 "skip:" %}
7242 ins_encode %{
7243 Label Lskip;
7244 // Invert sense of branch from sense of CMOV
7245 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7246 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7247 __ bind(Lskip);
7248 %}
7249 ins_pipe(pipe_slow);
7250 %}
7251
7252 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7253 %{
7254 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7255
7256 ins_cost(200); // XXX
7257 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7258 "movsd $dst, $src\n"
7259 "skip:" %}
7260 ins_encode %{
7261 Label Lskip;
7262 // Invert sense of branch from sense of CMOV
7263 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7264 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7265 __ bind(Lskip);
7266 %}
7267 ins_pipe(pipe_slow);
7268 %}
7269
7270 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7271 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7272 ins_cost(200);
7273 expand %{
7274 cmovD_regU(cop, cr, dst, src);
7275 %}
7276 %}
7277
7278 //----------Arithmetic Instructions--------------------------------------------
7279 //----------Addition Instructions----------------------------------------------
7280
7281 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7282 %{
7283 match(Set dst (AddI dst src));
7284 effect(KILL cr);
7285
7286 format %{ "addl $dst, $src\t# int" %}
9568 __ subl(Rp, Rq);
9569 __ sbbl(Rt, Rt);
9570 __ andl(Rt, Ry);
9571 __ addl(Rp, Rt);
9572 %}
9573 ins_pipe(pipe_cmplt);
9574 %}
9575
9576 //---------- FP Instructions------------------------------------------------
9577
9578 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
9579 %{
9580 match(Set cr (CmpF src1 src2));
9581
9582 ins_cost(145);
9583 format %{ "ucomiss $src1, $src2\n\t"
9584 "jnp,s exit\n\t"
9585 "pushfq\t# saw NaN, set CF\n\t"
9586 "andq [rsp], #0xffffff2b\n\t"
9587 "popfq\n"
9588 "exit:" %}
9589 ins_encode %{
9590 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9591 emit_cmpfp_fixup(_masm);
9592 %}
9593 ins_pipe(pipe_slow);
9594 %}
9595
9596 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9597 match(Set cr (CmpF src1 src2));
9598
9599 ins_cost(100);
9600 format %{ "ucomiss $src1, $src2" %}
9601 ins_encode %{
9602 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9603 %}
9604 ins_pipe(pipe_slow);
9605 %}
9606
9607 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9608 %{
9609 match(Set cr (CmpF src1 (LoadF src2)));
9610
9611 ins_cost(145);
9612 format %{ "ucomiss $src1, $src2\n\t"
9613 "jnp,s exit\n\t"
9614 "pushfq\t# saw NaN, set CF\n\t"
9615 "andq [rsp], #0xffffff2b\n\t"
9616 "popfq\n"
9617 "exit:" %}
9618 ins_encode %{
9619 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9620 emit_cmpfp_fixup(_masm);
9621 %}
9622 ins_pipe(pipe_slow);
9623 %}
9624
9625 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9626 match(Set cr (CmpF src1 (LoadF src2)));
9627
9628 ins_cost(100);
9629 format %{ "ucomiss $src1, $src2" %}
9630 ins_encode %{
9631 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9632 %}
9633 ins_pipe(pipe_slow);
9634 %}
9635
9636 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
9637 match(Set cr (CmpF src con));
9638
9639 ins_cost(145);
9640 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9641 "jnp,s exit\n\t"
9642 "pushfq\t# saw NaN, set CF\n\t"
9643 "andq [rsp], #0xffffff2b\n\t"
9644 "popfq\n"
9645 "exit:" %}
9646 ins_encode %{
9647 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9648 emit_cmpfp_fixup(_masm);
9649 %}
9650 ins_pipe(pipe_slow);
9651 %}
9652
9653 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
9654 match(Set cr (CmpF src con));
9655 ins_cost(100);
9656 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
9657 ins_encode %{
9658 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9659 %}
9660 ins_pipe(pipe_slow);
9661 %}
9662
9663 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9664 %{
9665 match(Set cr (CmpD src1 src2));
9666
9667 ins_cost(145);
9668 format %{ "ucomisd $src1, $src2\n\t"
9669 "jnp,s exit\n\t"
9670 "pushfq\t# saw NaN, set CF\n\t"
9671 "andq [rsp], #0xffffff2b\n\t"
9672 "popfq\n"
9673 "exit:" %}
9674 ins_encode %{
9675 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9676 emit_cmpfp_fixup(_masm);
9677 %}
9678 ins_pipe(pipe_slow);
9679 %}
9680
9681 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9682 match(Set cr (CmpD src1 src2));
9683
9684 ins_cost(100);
9685 format %{ "ucomisd $src1, $src2 test" %}
9686 ins_encode %{
9687 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9688 %}
9689 ins_pipe(pipe_slow);
9690 %}
9691
9692 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9693 %{
9694 match(Set cr (CmpD src1 (LoadD src2)));
9695
9696 ins_cost(145);
9697 format %{ "ucomisd $src1, $src2\n\t"
9698 "jnp,s exit\n\t"
9699 "pushfq\t# saw NaN, set CF\n\t"
9700 "andq [rsp], #0xffffff2b\n\t"
9701 "popfq\n"
9702 "exit:" %}
9703 ins_encode %{
9704 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9705 emit_cmpfp_fixup(_masm);
9706 %}
9707 ins_pipe(pipe_slow);
9708 %}
9709
9710 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9711 match(Set cr (CmpD src1 (LoadD src2)));
9712
9713 ins_cost(100);
9714 format %{ "ucomisd $src1, $src2" %}
9715 ins_encode %{
9716 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9717 %}
9718 ins_pipe(pipe_slow);
9719 %}
9720
9721 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
9722 match(Set cr (CmpD src con));
9723
9724 ins_cost(145);
9725 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9726 "jnp,s exit\n\t"
9727 "pushfq\t# saw NaN, set CF\n\t"
9728 "andq [rsp], #0xffffff2b\n\t"
9729 "popfq\n"
9730 "exit:" %}
9731 ins_encode %{
9732 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9733 emit_cmpfp_fixup(_masm);
9734 %}
9735 ins_pipe(pipe_slow);
9736 %}
9737
9738 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
9739 match(Set cr (CmpD src con));
9740 ins_cost(100);
9741 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
9742 ins_encode %{
9743 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9744 %}
9745 ins_pipe(pipe_slow);
9746 %}
9747
9748 // Compare into -1,0,1
9749 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
9750 %{
9751 match(Set dst (CmpF3 src1 src2));
9752 effect(KILL cr);
9753
9754 ins_cost(275);
9755 format %{ "ucomiss $src1, $src2\n\t"
9756 "movl $dst, #-1\n\t"
9757 "jp,s done\n\t"
9758 "jb,s done\n\t"
9759 "setne $dst\n\t"
9760 "movzbl $dst, $dst\n"
9761 "done:" %}
9762 ins_encode %{
9763 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9764 emit_cmpfp3(_masm, $dst$$Register);
9765 %}
9766 ins_pipe(pipe_slow);
9767 %}
9768
9769 // Compare into -1,0,1
9770 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
9771 %{
9772 match(Set dst (CmpF3 src1 (LoadF src2)));
9773 effect(KILL cr);
9774
9775 ins_cost(275);
9776 format %{ "ucomiss $src1, $src2\n\t"
9777 "movl $dst, #-1\n\t"
9778 "jp,s done\n\t"
9779 "jb,s done\n\t"
9780 "setne $dst\n\t"
9781 "movzbl $dst, $dst\n"
9782 "done:" %}
9783 ins_encode %{
9784 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9785 emit_cmpfp3(_masm, $dst$$Register);
9786 %}
9787 ins_pipe(pipe_slow);
9788 %}
9789
9790 // Compare into -1,0,1
9791 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
9792 match(Set dst (CmpF3 src con));
9793 effect(KILL cr);
9794
9795 ins_cost(275);
9796 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9797 "movl $dst, #-1\n\t"
9798 "jp,s done\n\t"
9799 "jb,s done\n\t"
9800 "setne $dst\n\t"
9801 "movzbl $dst, $dst\n"
9802 "done:" %}
9803 ins_encode %{
9804 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9805 emit_cmpfp3(_masm, $dst$$Register);
9806 %}
9807 ins_pipe(pipe_slow);
9808 %}
9809
9810 // Compare into -1,0,1
9811 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
9812 %{
9813 match(Set dst (CmpD3 src1 src2));
9814 effect(KILL cr);
9815
9816 ins_cost(275);
9817 format %{ "ucomisd $src1, $src2\n\t"
9818 "movl $dst, #-1\n\t"
9819 "jp,s done\n\t"
9820 "jb,s done\n\t"
9821 "setne $dst\n\t"
9822 "movzbl $dst, $dst\n"
9823 "done:" %}
9824 ins_encode %{
9825 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9826 emit_cmpfp3(_masm, $dst$$Register);
9827 %}
9828 ins_pipe(pipe_slow);
9829 %}
9830
9831 // Compare into -1,0,1
9832 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
9833 %{
9834 match(Set dst (CmpD3 src1 (LoadD src2)));
9835 effect(KILL cr);
9836
9837 ins_cost(275);
9838 format %{ "ucomisd $src1, $src2\n\t"
9839 "movl $dst, #-1\n\t"
9840 "jp,s done\n\t"
9841 "jb,s done\n\t"
9842 "setne $dst\n\t"
9843 "movzbl $dst, $dst\n"
9844 "done:" %}
9845 ins_encode %{
9846 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9847 emit_cmpfp3(_masm, $dst$$Register);
9848 %}
9849 ins_pipe(pipe_slow);
9850 %}
9851
9852 // Compare into -1,0,1
9853 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
9854 match(Set dst (CmpD3 src con));
9855 effect(KILL cr);
9856
9857 ins_cost(275);
9858 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9859 "movl $dst, #-1\n\t"
9860 "jp,s done\n\t"
9861 "jb,s done\n\t"
9862 "setne $dst\n\t"
9863 "movzbl $dst, $dst\n"
9864 "done:" %}
9865 ins_encode %{
9866 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9867 emit_cmpfp3(_masm, $dst$$Register);
9868 %}
9869 ins_pipe(pipe_slow);
9870 %}
9871
9872 instruct addF_reg(regF dst, regF src)
9873 %{
9874 match(Set dst (AddF dst src));
9875
9876 format %{ "addss $dst, $src" %}
9877 ins_cost(150); // XXX
9878 ins_encode %{
9879 __ addss($dst$$XMMRegister, $src$$XMMRegister);
9880 %}
9881 ins_pipe(pipe_slow);
9882 %}
9883
9884 instruct addF_mem(regF dst, memory src)
9885 %{
9886 match(Set dst (AddF dst (LoadF src)));
9887
9888 format %{ "addss $dst, $src" %}
9889 ins_cost(150); // XXX
9890 ins_encode %{
9891 __ addss($dst$$XMMRegister, $src$$Address);
9892 %}
9893 ins_pipe(pipe_slow);
9894 %}
9895
9896 instruct addF_imm(regF dst, immF con) %{
9897 match(Set dst (AddF dst con));
9898 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
9899 ins_cost(150); // XXX
9900 ins_encode %{
9901 __ addss($dst$$XMMRegister, $constantaddress($con));
9902 %}
9903 ins_pipe(pipe_slow);
9904 %}
9905
9906 instruct addD_reg(regD dst, regD src)
9907 %{
9908 match(Set dst (AddD dst src));
9909
9910 format %{ "addsd $dst, $src" %}
9911 ins_cost(150); // XXX
9912 ins_encode %{
9913 __ addsd($dst$$XMMRegister, $src$$XMMRegister);
9914 %}
9915 ins_pipe(pipe_slow);
9916 %}
9917
9918 instruct addD_mem(regD dst, memory src)
9919 %{
9920 match(Set dst (AddD dst (LoadD src)));
9921
9922 format %{ "addsd $dst, $src" %}
9923 ins_cost(150); // XXX
9924 ins_encode %{
9925 __ addsd($dst$$XMMRegister, $src$$Address);
9926 %}
9927 ins_pipe(pipe_slow);
9928 %}
9929
9930 instruct addD_imm(regD dst, immD con) %{
9931 match(Set dst (AddD dst con));
9932 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
9933 ins_cost(150); // XXX
9934 ins_encode %{
9935 __ addsd($dst$$XMMRegister, $constantaddress($con));
9936 %}
9937 ins_pipe(pipe_slow);
9938 %}
9939
9940 instruct subF_reg(regF dst, regF src)
9941 %{
9942 match(Set dst (SubF dst src));
9943
9944 format %{ "subss $dst, $src" %}
9945 ins_cost(150); // XXX
9946 ins_encode %{
9947 __ subss($dst$$XMMRegister, $src$$XMMRegister);
9948 %}
9949 ins_pipe(pipe_slow);
9950 %}
9951
9952 instruct subF_mem(regF dst, memory src)
9953 %{
9954 match(Set dst (SubF dst (LoadF src)));
9955
9956 format %{ "subss $dst, $src" %}
9957 ins_cost(150); // XXX
9958 ins_encode %{
9959 __ subss($dst$$XMMRegister, $src$$Address);
9960 %}
9961 ins_pipe(pipe_slow);
9962 %}
9963
9964 instruct subF_imm(regF dst, immF con) %{
9965 match(Set dst (SubF dst con));
9966 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
9967 ins_cost(150); // XXX
9968 ins_encode %{
9969 __ subss($dst$$XMMRegister, $constantaddress($con));
9970 %}
9971 ins_pipe(pipe_slow);
9972 %}
9973
9974 instruct subD_reg(regD dst, regD src)
9975 %{
9976 match(Set dst (SubD dst src));
9977
9978 format %{ "subsd $dst, $src" %}
9979 ins_cost(150); // XXX
9980 ins_encode %{
9981 __ subsd($dst$$XMMRegister, $src$$XMMRegister);
9982 %}
9983 ins_pipe(pipe_slow);
9984 %}
9985
9986 instruct subD_mem(regD dst, memory src)
9987 %{
9988 match(Set dst (SubD dst (LoadD src)));
9989
9990 format %{ "subsd $dst, $src" %}
9991 ins_cost(150); // XXX
9992 ins_encode %{
9993 __ subsd($dst$$XMMRegister, $src$$Address);
9994 %}
9995 ins_pipe(pipe_slow);
9996 %}
9997
9998 instruct subD_imm(regD dst, immD con) %{
9999 match(Set dst (SubD dst con));
10000 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10001 ins_cost(150); // XXX
10002 ins_encode %{
10003 __ subsd($dst$$XMMRegister, $constantaddress($con));
10004 %}
10005 ins_pipe(pipe_slow);
10006 %}
10007
10008 instruct mulF_reg(regF dst, regF src)
10009 %{
10010 match(Set dst (MulF dst src));
10011
10012 format %{ "mulss $dst, $src" %}
10013 ins_cost(150); // XXX
10014 ins_encode %{
10015 __ mulss($dst$$XMMRegister, $src$$XMMRegister);
10016 %}
10017 ins_pipe(pipe_slow);
10018 %}
10019
10020 instruct mulF_mem(regF dst, memory src)
10021 %{
10022 match(Set dst (MulF dst (LoadF src)));
10023
10024 format %{ "mulss $dst, $src" %}
10025 ins_cost(150); // XXX
10026 ins_encode %{
10027 __ mulss($dst$$XMMRegister, $src$$Address);
10028 %}
10029 ins_pipe(pipe_slow);
10030 %}
10031
10032 instruct mulF_imm(regF dst, immF con) %{
10033 match(Set dst (MulF dst con));
10034 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10035 ins_cost(150); // XXX
10036 ins_encode %{
10037 __ mulss($dst$$XMMRegister, $constantaddress($con));
10038 %}
10039 ins_pipe(pipe_slow);
10040 %}
10041
10042 instruct mulD_reg(regD dst, regD src)
10043 %{
10044 match(Set dst (MulD dst src));
10045
10046 format %{ "mulsd $dst, $src" %}
10047 ins_cost(150); // XXX
10048 ins_encode %{
10049 __ mulsd($dst$$XMMRegister, $src$$XMMRegister);
10050 %}
10051 ins_pipe(pipe_slow);
10052 %}
10053
10054 instruct mulD_mem(regD dst, memory src)
10055 %{
10056 match(Set dst (MulD dst (LoadD src)));
10057
10058 format %{ "mulsd $dst, $src" %}
10059 ins_cost(150); // XXX
10060 ins_encode %{
10061 __ mulsd($dst$$XMMRegister, $src$$Address);
10062 %}
10063 ins_pipe(pipe_slow);
10064 %}
10065
10066 instruct mulD_imm(regD dst, immD con) %{
10067 match(Set dst (MulD dst con));
10068 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10069 ins_cost(150); // XXX
10070 ins_encode %{
10071 __ mulsd($dst$$XMMRegister, $constantaddress($con));
10072 %}
10073 ins_pipe(pipe_slow);
10074 %}
10075
10076 instruct divF_reg(regF dst, regF src)
10077 %{
10078 match(Set dst (DivF dst src));
10079
10080 format %{ "divss $dst, $src" %}
10081 ins_cost(150); // XXX
10082 ins_encode %{
10083 __ divss($dst$$XMMRegister, $src$$XMMRegister);
10084 %}
10085 ins_pipe(pipe_slow);
10086 %}
10087
10088 instruct divF_mem(regF dst, memory src)
10089 %{
10090 match(Set dst (DivF dst (LoadF src)));
10091
10092 format %{ "divss $dst, $src" %}
10093 ins_cost(150); // XXX
10094 ins_encode %{
10095 __ divss($dst$$XMMRegister, $src$$Address);
10096 %}
10097 ins_pipe(pipe_slow);
10098 %}
10099
10100 instruct divF_imm(regF dst, immF con) %{
10101 match(Set dst (DivF dst con));
10102 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10103 ins_cost(150); // XXX
10104 ins_encode %{
10105 __ divss($dst$$XMMRegister, $constantaddress($con));
10106 %}
10107 ins_pipe(pipe_slow);
10108 %}
10109
10110 instruct divD_reg(regD dst, regD src)
10111 %{
10112 match(Set dst (DivD dst src));
10113
10114 format %{ "divsd $dst, $src" %}
10115 ins_cost(150); // XXX
10116 ins_encode %{
10117 __ divsd($dst$$XMMRegister, $src$$XMMRegister);
10118 %}
10119 ins_pipe(pipe_slow);
10120 %}
10121
10122 instruct divD_mem(regD dst, memory src)
10123 %{
10124 match(Set dst (DivD dst (LoadD src)));
10125
10126 format %{ "divsd $dst, $src" %}
10127 ins_cost(150); // XXX
10128 ins_encode %{
10129 __ divsd($dst$$XMMRegister, $src$$Address);
10130 %}
10131 ins_pipe(pipe_slow);
10132 %}
10133
10134 instruct divD_imm(regD dst, immD con) %{
10135 match(Set dst (DivD dst con));
10136 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10137 ins_cost(150); // XXX
10138 ins_encode %{
10139 __ divsd($dst$$XMMRegister, $constantaddress($con));
10140 %}
10141 ins_pipe(pipe_slow);
10142 %}
10143
10144 instruct sqrtF_reg(regF dst, regF src)
10145 %{
10146 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10147
10148 format %{ "sqrtss $dst, $src" %}
10149 ins_cost(150); // XXX
10150 ins_encode %{
10151 __ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
10152 %}
10153 ins_pipe(pipe_slow);
10154 %}
10155
10156 instruct sqrtF_mem(regF dst, memory src)
10157 %{
10158 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10159
10160 format %{ "sqrtss $dst, $src" %}
10161 ins_cost(150); // XXX
10162 ins_encode %{
10163 __ sqrtss($dst$$XMMRegister, $src$$Address);
10164 %}
10165 ins_pipe(pipe_slow);
10166 %}
10167
10168 instruct sqrtF_imm(regF dst, immF con) %{
10169 match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
10170 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10171 ins_cost(150); // XXX
10172 ins_encode %{
10173 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
10174 %}
10175 ins_pipe(pipe_slow);
10176 %}
10177
10178 instruct sqrtD_reg(regD dst, regD src)
10179 %{
10180 match(Set dst (SqrtD src));
10181
10182 format %{ "sqrtsd $dst, $src" %}
10183 ins_cost(150); // XXX
10184 ins_encode %{
10185 __ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
10186 %}
10187 ins_pipe(pipe_slow);
10188 %}
10189
10190 instruct sqrtD_mem(regD dst, memory src)
10191 %{
10192 match(Set dst (SqrtD (LoadD src)));
10193
10194 format %{ "sqrtsd $dst, $src" %}
10195 ins_cost(150); // XXX
10196 ins_encode %{
10197 __ sqrtsd($dst$$XMMRegister, $src$$Address);
10198 %}
10199 ins_pipe(pipe_slow);
10200 %}
10201
10202 instruct sqrtD_imm(regD dst, immD con) %{
10203 match(Set dst (SqrtD con));
10204 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10205 ins_cost(150); // XXX
10206 ins_encode %{
10207 __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
10208 %}
10209 ins_pipe(pipe_slow);
10210 %}
10211
10212 instruct absF_reg(regF dst)
10213 %{
10214 match(Set dst (AbsF dst));
10215 ins_cost(150); // XXX
10216 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10217 ins_encode %{
10218 __ andps($dst$$XMMRegister,
10219 ExternalAddress((address) StubRoutines::x86::float_sign_mask()));
10220 %}
10221 ins_pipe(pipe_slow);
10222 %}
10223
10224 instruct absD_reg(regD dst)
10225 %{
10226 match(Set dst (AbsD dst));
10227 ins_cost(150); // XXX
10228 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10229 "# abs double by sign masking" %}
10230 ins_encode %{
10231 __ andpd($dst$$XMMRegister,
10232 ExternalAddress((address) StubRoutines::x86::double_sign_mask()));
10233 %}
10234 ins_pipe(pipe_slow);
10235 %}
10236
10237 instruct negF_reg(regF dst)
10238 %{
10239 match(Set dst (NegF dst));
10240 ins_cost(150); // XXX
10241 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
10242 ins_encode %{
10243 __ xorps($dst$$XMMRegister,
10244 ExternalAddress((address) StubRoutines::x86::float_sign_flip()));
10245 %}
10246 ins_pipe(pipe_slow);
10247 %}
10248
10249 instruct negD_reg(regD dst)
10250 %{
10251 match(Set dst (NegD dst));
10252 ins_cost(150); // XXX
10253 format %{ "xorpd $dst, [0x8000000000000000]\t"
10254 "# neg double by sign flipping" %}
10255 ins_encode %{
10256 __ xorpd($dst$$XMMRegister,
10257 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10258 %}
10259 ins_pipe(pipe_slow);
10260 %}
10261
10262 // -----------Trig and Trancendental Instructions------------------------------
10263 instruct cosD_reg(regD dst) %{
10264 match(Set dst (CosD dst));
10265
10266 format %{ "dcos $dst\n\t" %}
10267 opcode(0xD9, 0xFF);
10268 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10269 ins_pipe( pipe_slow );
10270 %}
10271
10272 instruct sinD_reg(regD dst) %{
10273 match(Set dst (SinD dst));
10274
10275 format %{ "dsin $dst\n\t" %}
10276 opcode(0xD9, 0xFE);
10277 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10278 ins_pipe( pipe_slow );
10330
10331 ins_cost(0);
10332 ins_encode();
10333 ins_pipe(empty);
10334 %}
10335
10336 instruct roundDouble_nop(regD dst)
10337 %{
10338 match(Set dst (RoundDouble dst));
10339
10340 ins_cost(0);
10341 ins_encode();
10342 ins_pipe(empty);
10343 %}
10344
10345 instruct convF2D_reg_reg(regD dst, regF src)
10346 %{
10347 match(Set dst (ConvF2D src));
10348
10349 format %{ "cvtss2sd $dst, $src" %}
10350 ins_encode %{
10351 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
10352 %}
10353 ins_pipe(pipe_slow); // XXX
10354 %}
10355
10356 instruct convF2D_reg_mem(regD dst, memory src)
10357 %{
10358 match(Set dst (ConvF2D (LoadF src)));
10359
10360 format %{ "cvtss2sd $dst, $src" %}
10361 ins_encode %{
10362 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
10363 %}
10364 ins_pipe(pipe_slow); // XXX
10365 %}
10366
10367 instruct convD2F_reg_reg(regF dst, regD src)
10368 %{
10369 match(Set dst (ConvD2F src));
10370
10371 format %{ "cvtsd2ss $dst, $src" %}
10372 ins_encode %{
10373 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
10374 %}
10375 ins_pipe(pipe_slow); // XXX
10376 %}
10377
10378 instruct convD2F_reg_mem(regF dst, memory src)
10379 %{
10380 match(Set dst (ConvD2F (LoadD src)));
10381
10382 format %{ "cvtsd2ss $dst, $src" %}
10383 ins_encode %{
10384 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
10385 %}
10386 ins_pipe(pipe_slow); // XXX
10387 %}
10388
10389 // XXX do mem variants
10390 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10391 %{
10392 match(Set dst (ConvF2I src));
10393 effect(KILL cr);
10394
10395 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
10396 "cmpl $dst, #0x80000000\n\t"
10397 "jne,s done\n\t"
10398 "subq rsp, #8\n\t"
10399 "movss [rsp], $src\n\t"
10400 "call f2i_fixup\n\t"
10401 "popq $dst\n"
10402 "done: "%}
10403 ins_encode %{
10404 Label done;
10405 __ cvttss2sil($dst$$Register, $src$$XMMRegister);
10406 __ cmpl($dst$$Register, 0x80000000);
10407 __ jccb(Assembler::notEqual, done);
10408 __ subptr(rsp, 8);
10409 __ movflt(Address(rsp, 0), $src$$XMMRegister);
10410 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
10411 __ pop($dst$$Register);
10412 __ bind(done);
10413 %}
10414 ins_pipe(pipe_slow);
10415 %}
10416
10417 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10418 %{
10419 match(Set dst (ConvF2L src));
10420 effect(KILL cr);
10421
10422 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
10423 "cmpq $dst, [0x8000000000000000]\n\t"
10424 "jne,s done\n\t"
10425 "subq rsp, #8\n\t"
10426 "movss [rsp], $src\n\t"
10427 "call f2l_fixup\n\t"
10428 "popq $dst\n"
10429 "done: "%}
10430 ins_encode %{
10431 Label done;
10432 __ cvttss2siq($dst$$Register, $src$$XMMRegister);
10433 __ cmp64($dst$$Register,
10434 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10435 __ jccb(Assembler::notEqual, done);
10436 __ subptr(rsp, 8);
10437 __ movflt(Address(rsp, 0), $src$$XMMRegister);
10438 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
10439 __ pop($dst$$Register);
10440 __ bind(done);
10441 %}
10442 ins_pipe(pipe_slow);
10443 %}
10444
10445 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
10446 %{
10447 match(Set dst (ConvD2I src));
10448 effect(KILL cr);
10449
10450 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
10451 "cmpl $dst, #0x80000000\n\t"
10452 "jne,s done\n\t"
10453 "subq rsp, #8\n\t"
10454 "movsd [rsp], $src\n\t"
10455 "call d2i_fixup\n\t"
10456 "popq $dst\n"
10457 "done: "%}
10458 ins_encode %{
10459 Label done;
10460 __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
10461 __ cmpl($dst$$Register, 0x80000000);
10462 __ jccb(Assembler::notEqual, done);
10463 __ subptr(rsp, 8);
10464 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10465 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
10466 __ pop($dst$$Register);
10467 __ bind(done);
10468 %}
10469 ins_pipe(pipe_slow);
10470 %}
10471
10472 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
10473 %{
10474 match(Set dst (ConvD2L src));
10475 effect(KILL cr);
10476
10477 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
10478 "cmpq $dst, [0x8000000000000000]\n\t"
10479 "jne,s done\n\t"
10480 "subq rsp, #8\n\t"
10481 "movsd [rsp], $src\n\t"
10482 "call d2l_fixup\n\t"
10483 "popq $dst\n"
10484 "done: "%}
10485 ins_encode %{
10486 Label done;
10487 __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10488 __ cmp64($dst$$Register,
10489 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10490 __ jccb(Assembler::notEqual, done);
10491 __ subptr(rsp, 8);
10492 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10493 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10494 __ pop($dst$$Register);
10495 __ bind(done);
10496 %}
10497 ins_pipe(pipe_slow);
10498 %}
10499
10500 instruct convI2F_reg_reg(regF dst, rRegI src)
10501 %{
10502 predicate(!UseXmmI2F);
10503 match(Set dst (ConvI2F src));
10504
10505 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10506 ins_encode %{
10507 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10508 %}
10509 ins_pipe(pipe_slow); // XXX
10510 %}
10511
10512 instruct convI2F_reg_mem(regF dst, memory src)
10513 %{
10514 match(Set dst (ConvI2F (LoadI src)));
10515
10516 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10517 ins_encode %{
10518 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10519 %}
10520 ins_pipe(pipe_slow); // XXX
10521 %}
10522
10523 instruct convI2D_reg_reg(regD dst, rRegI src)
10524 %{
10525 predicate(!UseXmmI2D);
10526 match(Set dst (ConvI2D src));
10527
10528 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10529 ins_encode %{
10530 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10531 %}
10532 ins_pipe(pipe_slow); // XXX
10533 %}
10534
10535 instruct convI2D_reg_mem(regD dst, memory src)
10536 %{
10537 match(Set dst (ConvI2D (LoadI src)));
10538
10539 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10540 ins_encode %{
10541 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10542 %}
10543 ins_pipe(pipe_slow); // XXX
10544 %}
10545
10546 instruct convXI2F_reg(regF dst, rRegI src)
10547 %{
10548 predicate(UseXmmI2F);
10549 match(Set dst (ConvI2F src));
10550
10551 format %{ "movdl $dst, $src\n\t"
10552 "cvtdq2psl $dst, $dst\t# i2f" %}
10553 ins_encode %{
10554 __ movdl($dst$$XMMRegister, $src$$Register);
10555 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10556 %}
10557 ins_pipe(pipe_slow); // XXX
10558 %}
10559
10560 instruct convXI2D_reg(regD dst, rRegI src)
10561 %{
10562 predicate(UseXmmI2D);
10563 match(Set dst (ConvI2D src));
10564
10565 format %{ "movdl $dst, $src\n\t"
10566 "cvtdq2pdl $dst, $dst\t# i2d" %}
10567 ins_encode %{
10568 __ movdl($dst$$XMMRegister, $src$$Register);
10569 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10570 %}
10571 ins_pipe(pipe_slow); // XXX
10572 %}
10573
10574 instruct convL2F_reg_reg(regF dst, rRegL src)
10575 %{
10576 match(Set dst (ConvL2F src));
10577
10578 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10579 ins_encode %{
10580 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10581 %}
10582 ins_pipe(pipe_slow); // XXX
10583 %}
10584
10585 instruct convL2F_reg_mem(regF dst, memory src)
10586 %{
10587 match(Set dst (ConvL2F (LoadL src)));
10588
10589 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10590 ins_encode %{
10591 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10592 %}
10593 ins_pipe(pipe_slow); // XXX
10594 %}
10595
10596 instruct convL2D_reg_reg(regD dst, rRegL src)
10597 %{
10598 match(Set dst (ConvL2D src));
10599
10600 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10601 ins_encode %{
10602 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10603 %}
10604 ins_pipe(pipe_slow); // XXX
10605 %}
10606
10607 instruct convL2D_reg_mem(regD dst, memory src)
10608 %{
10609 match(Set dst (ConvL2D (LoadL src)));
10610
10611 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10612 ins_encode %{
10613 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10614 %}
10615 ins_pipe(pipe_slow); // XXX
10616 %}
10617
10618 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10619 %{
10620 match(Set dst (ConvI2L src));
10621
10622 ins_cost(125);
10623 format %{ "movslq $dst, $src\t# i2l" %}
10624 ins_encode %{
10625 __ movslq($dst$$Register, $src$$Register);
10626 %}
10627 ins_pipe(ialu_reg_reg);
10628 %}
10629
10630 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10631 // %{
10632 // match(Set dst (ConvI2L src));
10633 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10634 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10635 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10636 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10637 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10638 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10639
10640 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10641 // ins_encode(enc_copy(dst, src));
10642 // // opcode(0x63); // needs REX.W
10643 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10644 // ins_pipe(ialu_reg_reg);
10645 // %}
10646
10647 // Zero-extend convert int to long
10648 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10649 %{
10650 match(Set dst (AndL (ConvI2L src) mask));
10651
10652 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10653 ins_encode %{
10654 if ($dst$$reg != $src$$reg) {
10655 __ movl($dst$$Register, $src$$Register);
10656 }
10657 %}
10658 ins_pipe(ialu_reg_reg);
10659 %}
10660
10661 // Zero-extend convert int to long
10662 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10663 %{
10664 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10665
10666 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10667 ins_encode %{
10668 __ movl($dst$$Register, $src$$Address);
10669 %}
10670 ins_pipe(ialu_reg_mem);
10671 %}
10672
10673 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10674 %{
10675 match(Set dst (AndL src mask));
10676
10677 format %{ "movl $dst, $src\t# zero-extend long" %}
10678 ins_encode %{
10679 __ movl($dst$$Register, $src$$Register);
10680 %}
10681 ins_pipe(ialu_reg_reg);
10682 %}
10683
10684 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10685 %{
10686 match(Set dst (ConvL2I src));
10687
10688 format %{ "movl $dst, $src\t# l2i" %}
10689 ins_encode %{
10690 __ movl($dst$$Register, $src$$Register);
10691 %}
10692 ins_pipe(ialu_reg_reg);
10693 %}
10694
10695
10696 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10697 match(Set dst (MoveF2I src));
10698 effect(DEF dst, USE src);
10699
10700 ins_cost(125);
10701 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10702 ins_encode %{
10703 __ movl($dst$$Register, Address(rsp, $src$$disp));
10704 %}
10705 ins_pipe(ialu_reg_mem);
10706 %}
10707
10708 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10709 match(Set dst (MoveI2F src));
10710 effect(DEF dst, USE src);
10711
10712 ins_cost(125);
10713 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10714 ins_encode %{
10715 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10716 %}
10717 ins_pipe(pipe_slow);
10718 %}
10719
10720 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10721 match(Set dst (MoveD2L src));
10722 effect(DEF dst, USE src);
10723
10724 ins_cost(125);
10725 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10726 ins_encode %{
10727 __ movq($dst$$Register, Address(rsp, $src$$disp));
10728 %}
10729 ins_pipe(ialu_reg_mem);
10730 %}
10731
10732 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10733 predicate(!UseXmmLoadAndClearUpper);
10734 match(Set dst (MoveL2D src));
10735 effect(DEF dst, USE src);
10736
10737 ins_cost(125);
10738 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10739 ins_encode %{
10740 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10741 %}
10742 ins_pipe(pipe_slow);
10743 %}
10744
10745 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10746 predicate(UseXmmLoadAndClearUpper);
10747 match(Set dst (MoveL2D src));
10748 effect(DEF dst, USE src);
10749
10750 ins_cost(125);
10751 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10752 ins_encode %{
10753 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10754 %}
10755 ins_pipe(pipe_slow);
10756 %}
10757
10758
10759 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10760 match(Set dst (MoveF2I src));
10761 effect(DEF dst, USE src);
10762
10763 ins_cost(95); // XXX
10764 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10765 ins_encode %{
10766 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10767 %}
10768 ins_pipe(pipe_slow);
10769 %}
10770
10771 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10772 match(Set dst (MoveI2F src));
10773 effect(DEF dst, USE src);
10774
10775 ins_cost(100);
10776 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10777 ins_encode %{
10778 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10779 %}
10780 ins_pipe( ialu_mem_reg );
10781 %}
10782
10783 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10784 match(Set dst (MoveD2L src));
10785 effect(DEF dst, USE src);
10786
10787 ins_cost(95); // XXX
10788 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10789 ins_encode %{
10790 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10791 %}
10792 ins_pipe(pipe_slow);
10793 %}
10794
10795 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10796 match(Set dst (MoveL2D src));
10797 effect(DEF dst, USE src);
10798
10799 ins_cost(100);
10800 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10801 ins_encode %{
10802 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10803 %}
10804 ins_pipe(ialu_mem_reg);
10805 %}
10806
10807 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10808 match(Set dst (MoveF2I src));
10809 effect(DEF dst, USE src);
10810 ins_cost(85);
10811 format %{ "movd $dst,$src\t# MoveF2I" %}
10812 ins_encode %{
10813 __ movdl($dst$$Register, $src$$XMMRegister);
10814 %}
10815 ins_pipe( pipe_slow );
10816 %}
10817
10818 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10819 match(Set dst (MoveD2L src));
10820 effect(DEF dst, USE src);
10821 ins_cost(85);
10822 format %{ "movd $dst,$src\t# MoveD2L" %}
10823 ins_encode %{
10824 __ movdq($dst$$Register, $src$$XMMRegister);
10825 %}
10826 ins_pipe( pipe_slow );
10827 %}
10828
10829 // The next instructions have long latency and use Int unit. Set high cost.
10830 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10831 match(Set dst (MoveI2F src));
10832 effect(DEF dst, USE src);
10833 ins_cost(300);
10834 format %{ "movd $dst,$src\t# MoveI2F" %}
10835 ins_encode %{
10836 __ movdl($dst$$XMMRegister, $src$$Register);
10837 %}
10838 ins_pipe( pipe_slow );
10839 %}
10840
10841 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10842 match(Set dst (MoveL2D src));
10843 effect(DEF dst, USE src);
10844 ins_cost(300);
10845 format %{ "movd $dst,$src\t# MoveL2D" %}
10846 ins_encode %{
10847 __ movdq($dst$$XMMRegister, $src$$Register);
10848 %}
10849 ins_pipe( pipe_slow );
10850 %}
10851
10852 // Replicate scalar to packed byte (1 byte) values in xmm
10853 instruct Repl8B_reg(regD dst, regD src) %{
10854 match(Set dst (Replicate8B src));
10855 format %{ "MOVDQA $dst,$src\n\t"
10856 "PUNPCKLBW $dst,$dst\n\t"
10857 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
10858 ins_encode %{
10859 if ($dst$$reg != $src$$reg) {
10860 __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
10861 }
10862 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10863 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10864 %}
10865 ins_pipe( pipe_slow );
10866 %}
10867
10868 // Replicate scalar to packed byte (1 byte) values in xmm
10869 instruct Repl8B_rRegI(regD dst, rRegI src) %{
10870 match(Set dst (Replicate8B src));
10871 format %{ "MOVD $dst,$src\n\t"
10872 "PUNPCKLBW $dst,$dst\n\t"
10873 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
10874 ins_encode %{
10875 __ movdl($dst$$XMMRegister, $src$$Register);
10876 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10877 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10878 %}
10879 ins_pipe( pipe_slow );
10880 %}
10881
10882 // Replicate scalar zero to packed byte (1 byte) values in xmm
10883 instruct Repl8B_immI0(regD dst, immI0 zero) %{
10884 match(Set dst (Replicate8B zero));
10885 format %{ "PXOR $dst,$dst\t! replicate8B" %}
10886 ins_encode %{
10887 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10888 %}
10889 ins_pipe( fpu_reg_reg );
10890 %}
10891
10892 // Replicate scalar to packed shore (2 byte) values in xmm
10893 instruct Repl4S_reg(regD dst, regD src) %{
10894 match(Set dst (Replicate4S src));
10895 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
10896 ins_encode %{
10897 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10898 %}
10899 ins_pipe( fpu_reg_reg );
10900 %}
10901
10902 // Replicate scalar to packed shore (2 byte) values in xmm
10903 instruct Repl4S_rRegI(regD dst, rRegI src) %{
10904 match(Set dst (Replicate4S src));
10905 format %{ "MOVD $dst,$src\n\t"
10906 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
10907 ins_encode %{
10908 __ movdl($dst$$XMMRegister, $src$$Register);
10909 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10910 %}
10911 ins_pipe( fpu_reg_reg );
10912 %}
10913
10914 // Replicate scalar zero to packed short (2 byte) values in xmm
10915 instruct Repl4S_immI0(regD dst, immI0 zero) %{
10916 match(Set dst (Replicate4S zero));
10917 format %{ "PXOR $dst,$dst\t! replicate4S" %}
10918 ins_encode %{
10919 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10920 %}
10921 ins_pipe( fpu_reg_reg );
10922 %}
10923
10924 // Replicate scalar to packed char (2 byte) values in xmm
10925 instruct Repl4C_reg(regD dst, regD src) %{
10926 match(Set dst (Replicate4C src));
10927 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
10928 ins_encode %{
10929 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10930 %}
10931 ins_pipe( fpu_reg_reg );
10932 %}
10933
10934 // Replicate scalar to packed char (2 byte) values in xmm
10935 instruct Repl4C_rRegI(regD dst, rRegI src) %{
10936 match(Set dst (Replicate4C src));
10937 format %{ "MOVD $dst,$src\n\t"
10938 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
10939 ins_encode %{
10940 __ movdl($dst$$XMMRegister, $src$$Register);
10941 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10942 %}
10943 ins_pipe( fpu_reg_reg );
10944 %}
10945
10946 // Replicate scalar zero to packed char (2 byte) values in xmm
10947 instruct Repl4C_immI0(regD dst, immI0 zero) %{
10948 match(Set dst (Replicate4C zero));
10949 format %{ "PXOR $dst,$dst\t! replicate4C" %}
10950 ins_encode %{
10951 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10952 %}
10953 ins_pipe( fpu_reg_reg );
10954 %}
10955
10956 // Replicate scalar to packed integer (4 byte) values in xmm
10957 instruct Repl2I_reg(regD dst, regD src) %{
10958 match(Set dst (Replicate2I src));
10959 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
10960 ins_encode %{
10961 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10962 %}
10963 ins_pipe( fpu_reg_reg );
10964 %}
10965
10966 // Replicate scalar to packed integer (4 byte) values in xmm
10967 instruct Repl2I_rRegI(regD dst, rRegI src) %{
10968 match(Set dst (Replicate2I src));
10969 format %{ "MOVD $dst,$src\n\t"
10970 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
10971 ins_encode %{
10972 __ movdl($dst$$XMMRegister, $src$$Register);
10973 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10974 %}
10975 ins_pipe( fpu_reg_reg );
10976 %}
10977
10978 // Replicate scalar zero to packed integer (2 byte) values in xmm
10979 instruct Repl2I_immI0(regD dst, immI0 zero) %{
10980 match(Set dst (Replicate2I zero));
10981 format %{ "PXOR $dst,$dst\t! replicate2I" %}
10982 ins_encode %{
10983 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10984 %}
10985 ins_pipe( fpu_reg_reg );
10986 %}
10987
10988 // Replicate scalar to packed single precision floating point values in xmm
10989 instruct Repl2F_reg(regD dst, regD src) %{
10990 match(Set dst (Replicate2F src));
10991 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
10992 ins_encode %{
10993 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
10994 %}
10995 ins_pipe( fpu_reg_reg );
10996 %}
10997
10998 // Replicate scalar to packed single precision floating point values in xmm
10999 instruct Repl2F_regF(regD dst, regF src) %{
11000 match(Set dst (Replicate2F src));
11001 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11002 ins_encode %{
11003 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
11004 %}
11005 ins_pipe( fpu_reg_reg );
11006 %}
11007
11008 // Replicate scalar to packed single precision floating point values in xmm
11009 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11010 match(Set dst (Replicate2F zero));
11011 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11012 ins_encode %{
11013 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11014 %}
11015 ins_pipe( fpu_reg_reg );
11016 %}
11017
11018
11019 // =======================================================================
11020 // fast clearing of an array
11021 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
11022 rFlagsReg cr)
11023 %{
11024 match(Set dummy (ClearArray cnt base));
11025 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11026
11027 format %{ "xorl rax, rax\t# ClearArray:\n\t"
11028 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
11029 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
11030 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
11031 ins_pipe(pipe_slow);
11032 %}
11033
11034 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
|