comparison src/cpu/x86/vm/x86_64.ad @ 4970:33df1aeaebbf

Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 27 Feb 2012 13:10:13 +0100
parents 9b8ce46870df
children 61b82be3b1ff
comparison
equal deleted inserted replaced
4703:2cfb7fb2dce7 4970:33df1aeaebbf
1 // 1 //
2 // Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 // 4 //
5 // This code is free software; you can redistribute it and/or modify it 5 // This code is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License version 2 only, as 6 // under the terms of the GNU General Public License version 2 only, as
7 // published by the Free Software Foundation. 7 // published by the Free Software Foundation.
550 #define RELOC_DISP32 Assembler::disp32_operand 550 #define RELOC_DISP32 Assembler::disp32_operand
551 551
552 #define __ _masm. 552 #define __ _masm.
553 553
554 static int preserve_SP_size() { 554 static int preserve_SP_size() {
555 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) 555 return 3; // rex.w, op, rm(reg/reg)
556 } 556 }
557 557
558 // !!!!! Special hack to get all types of calls to specify the byte offset 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 559 // from the start of the call to the point where the return address
560 // will point. 560 // will point.
607 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 607 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
608 { 608 {
609 current_offset += 11; // skip movq instruction + call opcode byte 609 current_offset += 11; // skip movq instruction + call opcode byte
610 return round_to(current_offset, alignment_required()) - current_offset; 610 return round_to(current_offset, alignment_required()) - current_offset;
611 } 611 }
612
613 #ifndef PRODUCT
614 void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
615 {
616 st->print("INT3");
617 }
618 #endif
619 612
620 // EMIT_RM() 613 // EMIT_RM()
621 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 614 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
622 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 615 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
623 cbuf.insts()->emit_int8(c); 616 cbuf.insts()->emit_int8(c);
795 } 788 }
796 } 789 }
797 } 790 }
798 } 791 }
799 792
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 793 // This could be in MacroAssembler but it's fairly C2 specific
834 void emit_cmpfp_fixup(MacroAssembler& _masm) { 794 void emit_cmpfp_fixup(MacroAssembler& _masm) {
835 Label exit; 795 Label exit;
836 __ jccb(Assembler::noParity, exit); 796 __ jccb(Assembler::noParity, exit);
837 __ pushf(); 797 __ pushf();
798 //
799 // comiss/ucomiss instructions set ZF,PF,CF flags and
800 // zero OF,AF,SF for NaN values.
801 // Fixup flags by zeroing ZF,PF so that compare of NaN
802 // values returns 'less than' result (CF is set).
803 // Leave the rest of flags unchanged.
804 //
805 // 7 6 5 4 3 2 1 0
806 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
807 // 0 0 1 0 1 0 1 1 (0x2B)
808 //
838 __ andq(Address(rsp, 0), 0xffffff2b); 809 __ andq(Address(rsp, 0), 0xffffff2b);
839 __ popf(); 810 __ popf();
840 __ bind(exit); 811 __ bind(exit);
841 __ nop(); // (target for branch to avoid branch to branch) 812 }
813
814 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
815 Label done;
816 __ movl(dst, -1);
817 __ jcc(Assembler::parity, done);
818 __ jcc(Assembler::below, done);
819 __ setb(Assembler::notEqual, dst);
820 __ movzbl(dst, dst);
821 __ bind(done);
842 } 822 }
843 823
844 824
845 //============================================================================= 825 //=============================================================================
846 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 826 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
864 #endif 844 #endif
865 845
866 846
867 //============================================================================= 847 //=============================================================================
868 #ifndef PRODUCT 848 #ifndef PRODUCT
869 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 849 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
870 {
871 Compile* C = ra_->C; 850 Compile* C = ra_->C;
872 851
873 int framesize = C->frame_slots() << LogBytesPerInt; 852 int framesize = C->frame_slots() << LogBytesPerInt;
874 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 853 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
875 // Remove wordSize for return adr already pushed 854 // Remove wordSize for return addr which is already pushed.
876 // and another for the RBP we are going to save 855 framesize -= wordSize;
877 framesize -= 2*wordSize; 856
878 bool need_nop = true;
879
880 // Calls to C2R adapters often do not accept exceptional returns.
881 // We require that their callers must bang for them. But be
882 // careful, because some VM calls (such as call site linkage) can
883 // use several kilobytes of stack. But the stack safety zone should
884 // account for that. See bugs 4446381, 4468289, 4497237.
885 if (C->need_stack_bang(framesize)) { 857 if (C->need_stack_bang(framesize)) {
886 st->print_cr("# stack bang"); st->print("\t"); 858 framesize -= wordSize;
887 need_nop = false; 859 st->print("# stack bang");
860 st->print("\n\t");
861 st->print("pushq rbp\t# Save rbp");
862 if (framesize) {
863 st->print("\n\t");
864 st->print("subq rsp, #%d\t# Create frame",framesize);
865 }
866 } else {
867 st->print("subq rsp, #%d\t# Create frame",framesize);
868 st->print("\n\t");
869 framesize -= wordSize;
870 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
888 } 871 }
889 st->print_cr("pushq rbp"); st->print("\t");
890 872
891 if (VerifyStackAtCalls) { 873 if (VerifyStackAtCalls) {
892 // Majik cookie to verify stack depth 874 st->print("\n\t");
893 st->print_cr("pushq 0xffffffffbadb100d" 875 framesize -= wordSize;
894 "\t# Majik cookie for stack depth check"); 876 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
895 st->print("\t"); 877 #ifdef ASSERT
896 framesize -= wordSize; // Remove 2 for cookie 878 st->print("\n\t");
897 need_nop = false; 879 st->print("# stack alignment check");
880 #endif
898 } 881 }
899 882 st->cr();
900 if (framesize) {
901 st->print("subq rsp, #%d\t# Create frame", framesize);
902 if (framesize < 0x80 && need_nop) {
903 st->print("\n\tnop\t# nop for patch_verified_entry");
904 }
905 }
906 } 883 }
907 #endif 884 #endif
908 885
909 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 886 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
910 {
911 Compile* C = ra_->C; 887 Compile* C = ra_->C;
912 888 MacroAssembler _masm(&cbuf);
913 // WARNING: Initial instruction MUST be 5 bytes or longer so that
914 // NativeJump::patch_verified_entry will be able to patch out the entry
915 // code safely. The fldcw is ok at 6 bytes, the push to verify stack
916 // depth is ok at 5 bytes, the frame allocation can be either 3 or
917 // 6 bytes. So if we don't do the fldcw or the push then we must
918 // use the 6 byte frame allocation even if we have no frame. :-(
919 // If method sets FPU control word do it now
920 889
921 int framesize = C->frame_slots() << LogBytesPerInt; 890 int framesize = C->frame_slots() << LogBytesPerInt;
922 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 891
923 // Remove wordSize for return adr already pushed 892 __ verified_entry(framesize, C->need_stack_bang(framesize), false);
924 // and another for the RBP we are going to save
925 framesize -= 2*wordSize;
926 bool need_nop = true;
927
928 // Calls to C2R adapters often do not accept exceptional returns.
929 // We require that their callers must bang for them. But be
930 // careful, because some VM calls (such as call site linkage) can
931 // use several kilobytes of stack. But the stack safety zone should
932 // account for that. See bugs 4446381, 4468289, 4497237.
933 if (C->need_stack_bang(framesize)) {
934 MacroAssembler masm(&cbuf);
935 masm.generate_stack_overflow_check(framesize);
936 need_nop = false;
937 }
938
939 // We always push rbp so that on return to interpreter rbp will be
940 // restored correctly and we can correct the stack.
941 emit_opcode(cbuf, 0x50 | RBP_enc);
942
943 if (VerifyStackAtCalls) {
944 // Majik cookie to verify stack depth
945 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d
946 emit_d32(cbuf, 0xbadb100d);
947 framesize -= wordSize; // Remove 2 for cookie
948 need_nop = false;
949 }
950
951 if (framesize) {
952 emit_opcode(cbuf, Assembler::REX_W);
953 if (framesize < 0x80) {
954 emit_opcode(cbuf, 0x83); // sub SP,#framesize
955 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
956 emit_d8(cbuf, framesize);
957 if (need_nop) {
958 emit_opcode(cbuf, 0x90); // nop
959 }
960 } else {
961 emit_opcode(cbuf, 0x81); // sub SP,#framesize
962 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
963 emit_d32(cbuf, framesize);
964 }
965 }
966 893
967 C->set_frame_complete(cbuf.insts_size()); 894 C->set_frame_complete(cbuf.insts_size());
968
969 #ifdef ASSERT
970 if (VerifyStackAtCalls) {
971 Label L;
972 MacroAssembler masm(&cbuf);
973 masm.push(rax);
974 masm.mov(rax, rsp);
975 masm.andptr(rax, StackAlignmentInBytes-1);
976 masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
977 masm.pop(rax);
978 masm.jcc(Assembler::equal, L);
979 masm.stop("Stack is not properly aligned!");
980 masm.bind(L);
981 }
982 #endif
983 895
984 if (C->has_mach_constant_base_node()) { 896 if (C->has_mach_constant_base_node()) {
985 // NOTE: We set the table base offset here because users might be 897 // NOTE: We set the table base offset here because users might be
986 // emitted before MachConstantBaseNode. 898 // emitted before MachConstantBaseNode.
987 Compile::ConstantTable& constant_table = C->constant_table(); 899 Compile::ConstantTable& constant_table = C->constant_table();
1272 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1184 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1273 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1185 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1274 // 64-bit 1186 // 64-bit
1275 int offset = ra_->reg2offset(src_first); 1187 int offset = ra_->reg2offset(src_first);
1276 if (cbuf) { 1188 if (cbuf) {
1277 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 1189 MacroAssembler _masm(cbuf);
1278 if (Matcher::_regEncode[dst_first] >= 8) { 1190 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
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 1191 #ifndef PRODUCT
1288 } else if (!do_size) { 1192 } else if (!do_size) {
1289 st->print("%s %s, [rsp + #%d]\t# spill", 1193 st->print("%s %s, [rsp + #%d]\t# spill",
1290 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1194 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1291 Matcher::regName[dst_first], 1195 Matcher::regName[dst_first],
1292 offset); 1196 offset);
1293 #endif 1197 #endif
1294 } 1198 }
1295 return 1199 return
1296 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1200 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1297 ((Matcher::_regEncode[dst_first] < 8) 1201 ((Matcher::_regEncode[dst_first] >= 8)
1298 ? 5 1202 ? 6
1299 : 6); // REX 1203 : (5 + ((UseAVX>0)?1:0))); // REX
1300 } else { 1204 } else {
1301 // 32-bit 1205 // 32-bit
1302 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1206 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"); 1207 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1304 int offset = ra_->reg2offset(src_first); 1208 int offset = ra_->reg2offset(src_first);
1305 if (cbuf) { 1209 if (cbuf) {
1306 emit_opcode(*cbuf, 0xF3); 1210 MacroAssembler _masm(cbuf);
1307 if (Matcher::_regEncode[dst_first] >= 8) { 1211 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
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 1212 #ifndef PRODUCT
1317 } else if (!do_size) { 1213 } else if (!do_size) {
1318 st->print("movss %s, [rsp + #%d]\t# spill", 1214 st->print("movss %s, [rsp + #%d]\t# spill",
1319 Matcher::regName[dst_first], 1215 Matcher::regName[dst_first],
1320 offset); 1216 offset);
1321 #endif 1217 #endif
1322 } 1218 }
1323 return 1219 return
1324 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1220 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1325 ((Matcher::_regEncode[dst_first] < 8) 1221 ((Matcher::_regEncode[dst_first] >= 8)
1326 ? 5 1222 ? 6
1327 : 6); // REX 1223 : (5 + ((UseAVX>0)?1:0))); // REX
1328 } 1224 }
1329 } 1225 }
1330 } else if (src_first_rc == rc_int) { 1226 } else if (src_first_rc == rc_int) {
1331 // gpr -> 1227 // gpr ->
1332 if (dst_first_rc == rc_stack) { 1228 if (dst_first_rc == rc_stack) {
1448 // gpr -> xmm 1344 // gpr -> xmm
1449 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1345 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1450 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1346 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1451 // 64-bit 1347 // 64-bit
1452 if (cbuf) { 1348 if (cbuf) {
1453 emit_opcode(*cbuf, 0x66); 1349 MacroAssembler _masm(cbuf);
1454 if (Matcher::_regEncode[dst_first] < 8) { 1350 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
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 1351 #ifndef PRODUCT
1473 } else if (!do_size) { 1352 } else if (!do_size) {
1474 st->print("movdq %s, %s\t# spill", 1353 st->print("movdq %s, %s\t# spill",
1475 Matcher::regName[dst_first], 1354 Matcher::regName[dst_first],
1476 Matcher::regName[src_first]); 1355 Matcher::regName[src_first]);
1480 } else { 1359 } else {
1481 // 32-bit 1360 // 32-bit
1482 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1361 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"); 1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1484 if (cbuf) { 1363 if (cbuf) {
1485 emit_opcode(*cbuf, 0x66); 1364 MacroAssembler _masm(cbuf);
1486 if (Matcher::_regEncode[dst_first] < 8) { 1365 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
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 1366 #ifndef PRODUCT
1503 } else if (!do_size) { 1367 } else if (!do_size) {
1504 st->print("movdl %s, %s\t# spill", 1368 st->print("movdl %s, %s\t# spill",
1505 Matcher::regName[dst_first], 1369 Matcher::regName[dst_first],
1506 Matcher::regName[src_first]); 1370 Matcher::regName[src_first]);
1507 #endif 1371 #endif
1508 } 1372 }
1509 return 1373 return
1510 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1374 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1511 ? 4 1375 ? 5
1512 : 5; // REX 1376 : (4 + ((UseAVX>0)?1:0)); // REX
1513 } 1377 }
1514 } 1378 }
1515 } else if (src_first_rc == rc_float) { 1379 } else if (src_first_rc == rc_float) {
1516 // xmm -> 1380 // xmm ->
1517 if (dst_first_rc == rc_stack) { 1381 if (dst_first_rc == rc_stack) {
1519 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1383 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1520 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1384 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1521 // 64-bit 1385 // 64-bit
1522 int offset = ra_->reg2offset(dst_first); 1386 int offset = ra_->reg2offset(dst_first);
1523 if (cbuf) { 1387 if (cbuf) {
1524 emit_opcode(*cbuf, 0xF2); 1388 MacroAssembler _masm(cbuf);
1525 if (Matcher::_regEncode[src_first] >= 8) { 1389 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1390 #ifndef PRODUCT
1535 } else if (!do_size) { 1391 } else if (!do_size) {
1536 st->print("movsd [rsp + #%d], %s\t# spill", 1392 st->print("movsd [rsp + #%d], %s\t# spill",
1537 offset, 1393 offset,
1538 Matcher::regName[src_first]); 1394 Matcher::regName[src_first]);
1539 #endif 1395 #endif
1540 } 1396 }
1541 return 1397 return
1542 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1398 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1543 ((Matcher::_regEncode[src_first] < 8) 1399 ((Matcher::_regEncode[src_first] >= 8)
1544 ? 5 1400 ? 6
1545 : 6); // REX 1401 : (5 + ((UseAVX>0)?1:0))); // REX
1546 } else { 1402 } else {
1547 // 32-bit 1403 // 32-bit
1548 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1404 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"); 1405 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1550 int offset = ra_->reg2offset(dst_first); 1406 int offset = ra_->reg2offset(dst_first);
1551 if (cbuf) { 1407 if (cbuf) {
1552 emit_opcode(*cbuf, 0xF3); 1408 MacroAssembler _masm(cbuf);
1553 if (Matcher::_regEncode[src_first] >= 8) { 1409 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1410 #ifndef PRODUCT
1563 } else if (!do_size) { 1411 } else if (!do_size) {
1564 st->print("movss [rsp + #%d], %s\t# spill", 1412 st->print("movss [rsp + #%d], %s\t# spill",
1565 offset, 1413 offset,
1566 Matcher::regName[src_first]); 1414 Matcher::regName[src_first]);
1567 #endif 1415 #endif
1568 } 1416 }
1569 return 1417 return
1570 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1418 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1571 ((Matcher::_regEncode[src_first] < 8) 1419 ((Matcher::_regEncode[src_first] >=8)
1572 ? 5 1420 ? 6
1573 : 6); // REX 1421 : (5 + ((UseAVX>0)?1:0))); // REX
1574 } 1422 }
1575 } else if (dst_first_rc == rc_int) { 1423 } else if (dst_first_rc == rc_int) {
1576 // xmm -> gpr 1424 // xmm -> gpr
1577 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1425 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1578 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1426 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1579 // 64-bit 1427 // 64-bit
1580 if (cbuf) { 1428 if (cbuf) {
1581 emit_opcode(*cbuf, 0x66); 1429 MacroAssembler _masm(cbuf);
1582 if (Matcher::_regEncode[dst_first] < 8) { 1430 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1431 #ifndef PRODUCT
1601 } else if (!do_size) { 1432 } else if (!do_size) {
1602 st->print("movdq %s, %s\t# spill", 1433 st->print("movdq %s, %s\t# spill",
1603 Matcher::regName[dst_first], 1434 Matcher::regName[dst_first],
1604 Matcher::regName[src_first]); 1435 Matcher::regName[src_first]);
1608 } else { 1439 } else {
1609 // 32-bit 1440 // 32-bit
1610 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1441 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"); 1442 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1612 if (cbuf) { 1443 if (cbuf) {
1613 emit_opcode(*cbuf, 0x66); 1444 MacroAssembler _masm(cbuf);
1614 if (Matcher::_regEncode[dst_first] < 8) { 1445 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1446 #ifndef PRODUCT
1631 } else if (!do_size) { 1447 } else if (!do_size) {
1632 st->print("movdl %s, %s\t# spill", 1448 st->print("movdl %s, %s\t# spill",
1633 Matcher::regName[dst_first], 1449 Matcher::regName[dst_first],
1634 Matcher::regName[src_first]); 1450 Matcher::regName[src_first]);
1635 #endif 1451 #endif
1636 } 1452 }
1637 return 1453 return
1638 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1454 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1639 ? 4 1455 ? 5
1640 : 5; // REX 1456 : (4 + ((UseAVX>0)?1:0)); // REX
1641 } 1457 }
1642 } else if (dst_first_rc == rc_float) { 1458 } else if (dst_first_rc == rc_float) {
1643 // xmm -> xmm 1459 // xmm -> xmm
1644 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1460 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1645 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1461 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1646 // 64-bit 1462 // 64-bit
1647 if (cbuf) { 1463 if (cbuf) {
1648 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 1464 MacroAssembler _masm(cbuf);
1649 if (Matcher::_regEncode[dst_first] < 8) { 1465 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1466 #ifndef PRODUCT
1666 } else if (!do_size) { 1467 } else if (!do_size) {
1667 st->print("%s %s, %s\t# spill", 1468 st->print("%s %s, %s\t# spill",
1668 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1469 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1669 Matcher::regName[dst_first], 1470 Matcher::regName[dst_first],
1670 Matcher::regName[src_first]); 1471 Matcher::regName[src_first]);
1671 #endif 1472 #endif
1672 } 1473 }
1673 return 1474 return
1674 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1475 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1675 ? 4 1476 ? 5
1676 : 5; // REX 1477 : (4 + ((UseAVX>0)?1:0)); // REX
1677 } else { 1478 } else {
1678 // 32-bit 1479 // 32-bit
1679 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1480 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"); 1481 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1681 if (cbuf) { 1482 if (cbuf) {
1682 if (!UseXmmRegToRegMoveAll) 1483 MacroAssembler _masm(cbuf);
1683 emit_opcode(*cbuf, 0xF3); 1484 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
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 1485 #ifndef PRODUCT
1701 } else if (!do_size) { 1486 } else if (!do_size) {
1702 st->print("%s %s, %s\t# spill", 1487 st->print("%s %s, %s\t# spill",
1703 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1488 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1704 Matcher::regName[dst_first], 1489 Matcher::regName[dst_first],
1705 Matcher::regName[src_first]); 1490 Matcher::regName[src_first]);
1706 #endif 1491 #endif
1707 } 1492 }
1708 return 1493 return ((UseAVX>0) ? 5:
1709 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1494 ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1710 ? (UseXmmRegToRegMoveAll ? 3 : 4) 1495 ? (UseXmmRegToRegMoveAll ? 4 : 5)
1711 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX 1496 : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX
1712 } 1497 }
1713 } 1498 }
1714 } 1499 }
1715 1500
1716 assert(0," foo "); 1501 assert(0," foo ");
1733 1518
1734 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1519 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
1735 { 1520 {
1736 return implementation(NULL, ra_, true, NULL); 1521 return implementation(NULL, ra_, true, NULL);
1737 } 1522 }
1738
1739 //=============================================================================
1740 #ifndef PRODUCT
1741 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const
1742 {
1743 st->print("nop \t# %d bytes pad for loops and calls", _count);
1744 }
1745 #endif
1746
1747 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const
1748 {
1749 MacroAssembler _masm(&cbuf);
1750 __ nop(_count);
1751 }
1752
1753 uint MachNopNode::size(PhaseRegAlloc*) const
1754 {
1755 return _count;
1756 }
1757
1758 1523
1759 //============================================================================= 1524 //=============================================================================
1760 #ifndef PRODUCT 1525 #ifndef PRODUCT
1761 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1526 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1762 { 1527 {
2203 %{ 1968 %{
2204 emit_opcode(cbuf, $opcode$$constant); 1969 emit_opcode(cbuf, $opcode$$constant);
2205 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1970 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2206 %} 1971 %}
2207 1972
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) 1973 enc_class cdql_enc(no_rax_rdx_RegI div)
2250 %{ 1974 %{
2251 // Full implementation of Java idiv and irem; checks for 1975 // Full implementation of Java idiv and irem; checks for
2252 // special case as described in JVM spec., p.243 & p.271. 1976 // special case as described in JVM spec., p.243 & p.271.
2253 // 1977 //
2470 // CMOV 2194 // CMOV
2471 $$$emit8$primary; 2195 $$$emit8$primary;
2472 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2196 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2473 %} 2197 %}
2474 2198
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() 2199 enc_class enc_PartialSubtypeCheck()
2525 %{ 2200 %{
2526 Register Rrdi = as_Register(RDI_enc); // result register 2201 Register Rrdi = as_Register(RDI_enc); // result register
2527 Register Rrax = as_Register(RAX_enc); // super class 2202 Register Rrax = as_Register(RAX_enc); // super class
2528 Register Rrcx = as_Register(RCX_enc); // killed 2203 Register Rrcx = as_Register(RCX_enc); // killed
2549 // CALL directly to the runtime 2224 // CALL directly to the runtime
2550 emit_d32_reloc(cbuf, 2225 emit_d32_reloc(cbuf,
2551 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2226 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2552 runtime_call_Relocation::spec(), 2227 runtime_call_Relocation::spec(),
2553 RELOC_DISP32); 2228 RELOC_DISP32);
2554 %}
2555
2556 enc_class preserve_SP %{
2557 debug_only(int off0 = cbuf.insts_size());
2558 MacroAssembler _masm(&cbuf);
2559 // RBP is preserved across all calls, even compiled calls.
2560 // Use it to preserve RSP in places where the callee might change the SP.
2561 __ movptr(rbp_mh_SP_save, rsp);
2562 debug_only(int off1 = cbuf.insts_size());
2563 assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
2564 %}
2565
2566 enc_class restore_SP %{
2567 MacroAssembler _masm(&cbuf);
2568 __ movptr(rsp, rbp_mh_SP_save);
2569 %} 2229 %}
2570 2230
2571 enc_class Java_Static_Call(method meth) 2231 enc_class Java_Static_Call(method meth)
2572 %{ 2232 %{
2573 // JAVA STATIC CALL 2233 // JAVA STATIC CALL
2746 // This next line should be generated from ADLC 2406 // This next line should be generated from ADLC
2747 if ($src->constant_is_oop()) { 2407 if ($src->constant_is_oop()) {
2748 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2408 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2749 } else { 2409 } else {
2750 emit_d64(cbuf, $src$$constant); 2410 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 } 2411 }
2814 %} 2412 %}
2815 2413
2816 enc_class Con32(immI src) 2414 enc_class Con32(immI src)
2817 %{ 2415 %{
3210 emit_opcode(cbuf, 0xB6); 2808 emit_opcode(cbuf, 0xB6);
3211 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2809 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
3212 %} 2810 %}
3213 2811
3214 enc_class Push_ResultXD(regD dst) %{ 2812 enc_class Push_ResultXD(regD dst) %{
3215 int dstenc = $dst$$reg; 2813 MacroAssembler _masm(&cbuf);
3216 2814 __ fstp_d(Address(rsp, 0));
3217 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP] 2815 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
3218 2816 __ addptr(rsp, 8);
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 %} 2817 %}
3234 2818
3235 enc_class Push_SrcXD(regD src) %{ 2819 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); 2820 MacroAssembler _masm(&cbuf);
3262 __ movq($dst$$XMMRegister, $mem$$Address); 2821 __ subptr(rsp, 8);
3263 %} 2822 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
3264 2823 __ fld_d(Address(rsp, 0));
3265 enc_class movq_st(memory mem, regD src) %{ 2824 %}
3266 MacroAssembler _masm(&cbuf); 2825
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 2826
3302 // obj: object to lock 2827 // obj: object to lock
3303 // box: box address (header location) -- killed 2828 // box: box address (header location) -- killed
3304 // tmp: rax -- killed 2829 // tmp: rax -- killed
3305 // scr: rbx -- killed 2830 // scr: rbx -- killed
3532 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 3057 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
3533 runtime_call_Relocation::spec(), 3058 runtime_call_Relocation::spec(),
3534 RELOC_DISP32); 3059 RELOC_DISP32);
3535 %} 3060 %}
3536 3061
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 %} 3062 %}
3835 3063
3836 3064
3837 3065
3838 //----------FRAME-------------------------------------------------------------- 3066 //----------FRAME--------------------------------------------------------------
3936 // representing the register number (i.e. - use a register name) or 3164 // representing the register number (i.e. - use a register name) or
3937 // stack slot. 3165 // stack slot.
3938 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3166 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3939 // Otherwise, it is above the locks and verification slot and alignment word 3167 // Otherwise, it is above the locks and verification slot and alignment word
3940 return_addr(STACK - 2 + 3168 return_addr(STACK - 2 +
3941 round_to(2 + 2 * VerifyStackAtCalls + 3169 round_to((Compile::current()->in_preserve_stack_slots() +
3942 Compile::current()->fixed_slots(), 3170 Compile::current()->fixed_slots()),
3943 WordsPerLong * 2)); 3171 stack_alignment_in_slots()));
3944 3172
3945 // Body of function which returns an integer array locating 3173 // Body of function which returns an integer array locating
3946 // arguments either in registers or in stack slots. Passed an array 3174 // arguments either in registers or in stack slots. Passed an array
3947 // of ideal registers called "sig" and a "length" count. Stack-slot 3175 // of ideal registers called "sig" and a "length" count. Stack-slot
3948 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3176 // offsets are based on outgoing arguments, i.e. a CALLER setting up
6154 %{ 5382 %{
6155 match(Set dst (LoadF mem)); 5383 match(Set dst (LoadF mem));
6156 5384
6157 ins_cost(145); // XXX 5385 ins_cost(145); // XXX
6158 format %{ "movss $dst, $mem\t# float" %} 5386 format %{ "movss $dst, $mem\t# float" %}
6159 opcode(0xF3, 0x0F, 0x10); 5387 ins_encode %{
6160 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 5388 __ movflt($dst$$XMMRegister, $mem$$Address);
5389 %}
6161 ins_pipe(pipe_slow); // XXX 5390 ins_pipe(pipe_slow); // XXX
6162 %} 5391 %}
6163 5392
6164 // Load Double 5393 // Load Double
6165 instruct loadD_partial(regD dst, memory mem) 5394 instruct loadD_partial(regD dst, memory mem)
6167 predicate(!UseXmmLoadAndClearUpper); 5396 predicate(!UseXmmLoadAndClearUpper);
6168 match(Set dst (LoadD mem)); 5397 match(Set dst (LoadD mem));
6169 5398
6170 ins_cost(145); // XXX 5399 ins_cost(145); // XXX
6171 format %{ "movlpd $dst, $mem\t# double" %} 5400 format %{ "movlpd $dst, $mem\t# double" %}
6172 opcode(0x66, 0x0F, 0x12); 5401 ins_encode %{
6173 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 5402 __ movdbl($dst$$XMMRegister, $mem$$Address);
5403 %}
6174 ins_pipe(pipe_slow); // XXX 5404 ins_pipe(pipe_slow); // XXX
6175 %} 5405 %}
6176 5406
6177 instruct loadD(regD dst, memory mem) 5407 instruct loadD(regD dst, memory mem)
6178 %{ 5408 %{
6179 predicate(UseXmmLoadAndClearUpper); 5409 predicate(UseXmmLoadAndClearUpper);
6180 match(Set dst (LoadD mem)); 5410 match(Set dst (LoadD mem));
6181 5411
6182 ins_cost(145); // XXX 5412 ins_cost(145); // XXX
6183 format %{ "movsd $dst, $mem\t# double" %} 5413 format %{ "movsd $dst, $mem\t# double" %}
6184 opcode(0xF2, 0x0F, 0x10); 5414 ins_encode %{
6185 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 5415 __ movdbl($dst$$XMMRegister, $mem$$Address);
5416 %}
6186 ins_pipe(pipe_slow); // XXX 5417 ins_pipe(pipe_slow); // XXX
6187 %} 5418 %}
6188 5419
6189 // Load Aligned Packed Byte to XMM register 5420 // Load Aligned Packed Byte to XMM register
6190 instruct loadA8B(regD dst, memory mem) %{ 5421 instruct loadA8B(regD dst, memory mem) %{
6191 match(Set dst (Load8B mem)); 5422 match(Set dst (Load8B mem));
6192 ins_cost(125); 5423 ins_cost(125);
6193 format %{ "MOVQ $dst,$mem\t! packed8B" %} 5424 format %{ "MOVQ $dst,$mem\t! packed8B" %}
6194 ins_encode( movq_ld(dst, mem)); 5425 ins_encode %{
5426 __ movq($dst$$XMMRegister, $mem$$Address);
5427 %}
6195 ins_pipe( pipe_slow ); 5428 ins_pipe( pipe_slow );
6196 %} 5429 %}
6197 5430
6198 // Load Aligned Packed Short to XMM register 5431 // Load Aligned Packed Short to XMM register
6199 instruct loadA4S(regD dst, memory mem) %{ 5432 instruct loadA4S(regD dst, memory mem) %{
6200 match(Set dst (Load4S mem)); 5433 match(Set dst (Load4S mem));
6201 ins_cost(125); 5434 ins_cost(125);
6202 format %{ "MOVQ $dst,$mem\t! packed4S" %} 5435 format %{ "MOVQ $dst,$mem\t! packed4S" %}
6203 ins_encode( movq_ld(dst, mem)); 5436 ins_encode %{
5437 __ movq($dst$$XMMRegister, $mem$$Address);
5438 %}
6204 ins_pipe( pipe_slow ); 5439 ins_pipe( pipe_slow );
6205 %} 5440 %}
6206 5441
6207 // Load Aligned Packed Char to XMM register 5442 // Load Aligned Packed Char to XMM register
6208 instruct loadA4C(regD dst, memory mem) %{ 5443 instruct loadA4C(regD dst, memory mem) %{
6209 match(Set dst (Load4C mem)); 5444 match(Set dst (Load4C mem));
6210 ins_cost(125); 5445 ins_cost(125);
6211 format %{ "MOVQ $dst,$mem\t! packed4C" %} 5446 format %{ "MOVQ $dst,$mem\t! packed4C" %}
6212 ins_encode( movq_ld(dst, mem)); 5447 ins_encode %{
5448 __ movq($dst$$XMMRegister, $mem$$Address);
5449 %}
6213 ins_pipe( pipe_slow ); 5450 ins_pipe( pipe_slow );
6214 %} 5451 %}
6215 5452
6216 // Load Aligned Packed Integer to XMM register 5453 // Load Aligned Packed Integer to XMM register
6217 instruct load2IU(regD dst, memory mem) %{ 5454 instruct load2IU(regD dst, memory mem) %{
6218 match(Set dst (Load2I mem)); 5455 match(Set dst (Load2I mem));
6219 ins_cost(125); 5456 ins_cost(125);
6220 format %{ "MOVQ $dst,$mem\t! packed2I" %} 5457 format %{ "MOVQ $dst,$mem\t! packed2I" %}
6221 ins_encode( movq_ld(dst, mem)); 5458 ins_encode %{
5459 __ movq($dst$$XMMRegister, $mem$$Address);
5460 %}
6222 ins_pipe( pipe_slow ); 5461 ins_pipe( pipe_slow );
6223 %} 5462 %}
6224 5463
6225 // Load Aligned Packed Single to XMM 5464 // Load Aligned Packed Single to XMM
6226 instruct loadA2F(regD dst, memory mem) %{ 5465 instruct loadA2F(regD dst, memory mem) %{
6227 match(Set dst (Load2F mem)); 5466 match(Set dst (Load2F mem));
6228 ins_cost(145); 5467 ins_cost(125);
6229 format %{ "MOVQ $dst,$mem\t! packed2F" %} 5468 format %{ "MOVQ $dst,$mem\t! packed2F" %}
6230 ins_encode( movq_ld(dst, mem)); 5469 ins_encode %{
5470 __ movq($dst$$XMMRegister, $mem$$Address);
5471 %}
6231 ins_pipe( pipe_slow ); 5472 ins_pipe( pipe_slow );
6232 %} 5473 %}
6233 5474
6234 // Load Effective Address 5475 // Load Effective Address
6235 instruct leaP8(rRegP dst, indOffset8 mem) 5476 instruct leaP8(rRegP dst, indOffset8 mem)
6538 %{ 5779 %{
6539 match(Set dst src); 5780 match(Set dst src);
6540 ins_cost(100); 5781 ins_cost(100);
6541 5782
6542 format %{ "xorps $dst, $dst\t# float 0.0" %} 5783 format %{ "xorps $dst, $dst\t# float 0.0" %}
6543 opcode(0x0F, 0x57); 5784 ins_encode %{
6544 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 5785 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5786 %}
6545 ins_pipe(pipe_slow); 5787 ins_pipe(pipe_slow);
6546 %} 5788 %}
6547 5789
6548 // Use the same format since predicate() can not be used here. 5790 // Use the same format since predicate() can not be used here.
6549 instruct loadConD(regD dst, immD con) %{ 5791 instruct loadConD(regD dst, immD con) %{
6560 %{ 5802 %{
6561 match(Set dst src); 5803 match(Set dst src);
6562 ins_cost(100); 5804 ins_cost(100);
6563 5805
6564 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5806 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6565 opcode(0x66, 0x0F, 0x57); 5807 ins_encode %{
6566 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst)); 5808 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5809 %}
6567 ins_pipe(pipe_slow); 5810 ins_pipe(pipe_slow);
6568 %} 5811 %}
6569 5812
6570 instruct loadSSI(rRegI dst, stackSlotI src) 5813 instruct loadSSI(rRegI dst, stackSlotI src)
6571 %{ 5814 %{
6604 %{ 5847 %{
6605 match(Set dst src); 5848 match(Set dst src);
6606 5849
6607 ins_cost(125); 5850 ins_cost(125);
6608 format %{ "movss $dst, $src\t# float stk" %} 5851 format %{ "movss $dst, $src\t# float stk" %}
6609 opcode(0xF3, 0x0F, 0x10); 5852 ins_encode %{
6610 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 5853 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5854 %}
6611 ins_pipe(pipe_slow); // XXX 5855 ins_pipe(pipe_slow); // XXX
6612 %} 5856 %}
6613 5857
6614 // Use the same format since predicate() can not be used here. 5858 // Use the same format since predicate() can not be used here.
6615 instruct loadSSD(regD dst, stackSlotD src) 5859 instruct loadSSD(regD dst, stackSlotD src)
6970 // Store Aligned Packed Byte XMM register to memory 6214 // Store Aligned Packed Byte XMM register to memory
6971 instruct storeA8B(memory mem, regD src) %{ 6215 instruct storeA8B(memory mem, regD src) %{
6972 match(Set mem (Store8B mem src)); 6216 match(Set mem (Store8B mem src));
6973 ins_cost(145); 6217 ins_cost(145);
6974 format %{ "MOVQ $mem,$src\t! packed8B" %} 6218 format %{ "MOVQ $mem,$src\t! packed8B" %}
6975 ins_encode( movq_st(mem, src)); 6219 ins_encode %{
6220 __ movq($mem$$Address, $src$$XMMRegister);
6221 %}
6976 ins_pipe( pipe_slow ); 6222 ins_pipe( pipe_slow );
6977 %} 6223 %}
6978 6224
6979 // Store Aligned Packed Char/Short XMM register to memory 6225 // Store Aligned Packed Char/Short XMM register to memory
6980 instruct storeA4C(memory mem, regD src) %{ 6226 instruct storeA4C(memory mem, regD src) %{
6981 match(Set mem (Store4C mem src)); 6227 match(Set mem (Store4C mem src));
6982 ins_cost(145); 6228 ins_cost(145);
6983 format %{ "MOVQ $mem,$src\t! packed4C" %} 6229 format %{ "MOVQ $mem,$src\t! packed4C" %}
6984 ins_encode( movq_st(mem, src)); 6230 ins_encode %{
6231 __ movq($mem$$Address, $src$$XMMRegister);
6232 %}
6985 ins_pipe( pipe_slow ); 6233 ins_pipe( pipe_slow );
6986 %} 6234 %}
6987 6235
6988 // Store Aligned Packed Integer XMM register to memory 6236 // Store Aligned Packed Integer XMM register to memory
6989 instruct storeA2I(memory mem, regD src) %{ 6237 instruct storeA2I(memory mem, regD src) %{
6990 match(Set mem (Store2I mem src)); 6238 match(Set mem (Store2I mem src));
6991 ins_cost(145); 6239 ins_cost(145);
6992 format %{ "MOVQ $mem,$src\t! packed2I" %} 6240 format %{ "MOVQ $mem,$src\t! packed2I" %}
6993 ins_encode( movq_st(mem, src)); 6241 ins_encode %{
6242 __ movq($mem$$Address, $src$$XMMRegister);
6243 %}
6994 ins_pipe( pipe_slow ); 6244 ins_pipe( pipe_slow );
6995 %} 6245 %}
6996 6246
6997 // Store CMS card-mark Immediate 6247 // Store CMS card-mark Immediate
6998 instruct storeImmCM0_reg(memory mem, immI0 zero) 6248 instruct storeImmCM0_reg(memory mem, immI0 zero)
7022 // Store Aligned Packed Single Float XMM register to memory 6272 // Store Aligned Packed Single Float XMM register to memory
7023 instruct storeA2F(memory mem, regD src) %{ 6273 instruct storeA2F(memory mem, regD src) %{
7024 match(Set mem (Store2F mem src)); 6274 match(Set mem (Store2F mem src));
7025 ins_cost(145); 6275 ins_cost(145);
7026 format %{ "MOVQ $mem,$src\t! packed2F" %} 6276 format %{ "MOVQ $mem,$src\t! packed2F" %}
7027 ins_encode( movq_st(mem, src)); 6277 ins_encode %{
6278 __ movq($mem$$Address, $src$$XMMRegister);
6279 %}
7028 ins_pipe( pipe_slow ); 6280 ins_pipe( pipe_slow );
7029 %} 6281 %}
7030 6282
7031 // Store Float 6283 // Store Float
7032 instruct storeF(memory mem, regF src) 6284 instruct storeF(memory mem, regF src)
7033 %{ 6285 %{
7034 match(Set mem (StoreF mem src)); 6286 match(Set mem (StoreF mem src));
7035 6287
7036 ins_cost(95); // XXX 6288 ins_cost(95); // XXX
7037 format %{ "movss $mem, $src\t# float" %} 6289 format %{ "movss $mem, $src\t# float" %}
7038 opcode(0xF3, 0x0F, 0x11); 6290 ins_encode %{
7039 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 6291 __ movflt($mem$$Address, $src$$XMMRegister);
6292 %}
7040 ins_pipe(pipe_slow); // XXX 6293 ins_pipe(pipe_slow); // XXX
7041 %} 6294 %}
7042 6295
7043 // Store immediate Float value (it is faster than store from XMM register) 6296 // Store immediate Float value (it is faster than store from XMM register)
7044 instruct storeF0(memory mem, immF0 zero) 6297 instruct storeF0(memory mem, immF0 zero)
7070 %{ 6323 %{
7071 match(Set mem (StoreD mem src)); 6324 match(Set mem (StoreD mem src));
7072 6325
7073 ins_cost(95); // XXX 6326 ins_cost(95); // XXX
7074 format %{ "movsd $mem, $src\t# double" %} 6327 format %{ "movsd $mem, $src\t# double" %}
7075 opcode(0xF2, 0x0F, 0x11); 6328 ins_encode %{
7076 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 6329 __ movdbl($mem$$Address, $src$$XMMRegister);
6330 %}
7077 ins_pipe(pipe_slow); // XXX 6331 ins_pipe(pipe_slow); // XXX
7078 %} 6332 %}
7079 6333
7080 // Store immediate double 0.0 (it is faster than store from XMM register) 6334 // Store immediate double 0.0 (it is faster than store from XMM register)
7081 instruct storeD0_imm(memory mem, immD0 src) 6335 instruct storeD0_imm(memory mem, immD0 src)
7140 %{ 6394 %{
7141 match(Set dst src); 6395 match(Set dst src);
7142 6396
7143 ins_cost(95); // XXX 6397 ins_cost(95); // XXX
7144 format %{ "movss $dst, $src\t# float stk" %} 6398 format %{ "movss $dst, $src\t# float stk" %}
7145 opcode(0xF3, 0x0F, 0x11); 6399 ins_encode %{
7146 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 6400 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6401 %}
7147 ins_pipe(pipe_slow); // XXX 6402 ins_pipe(pipe_slow); // XXX
7148 %} 6403 %}
7149 6404
7150 instruct storeSSD(stackSlotD dst, regD src) 6405 instruct storeSSD(stackSlotD dst, regD src)
7151 %{ 6406 %{
7152 match(Set dst src); 6407 match(Set dst src);
7153 6408
7154 ins_cost(95); // XXX 6409 ins_cost(95); // XXX
7155 format %{ "movsd $dst, $src\t# double stk" %} 6410 format %{ "movsd $dst, $src\t# double stk" %}
7156 opcode(0xF2, 0x0F, 0x11); 6411 ins_encode %{
7157 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 6412 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6413 %}
7158 ins_pipe(pipe_slow); // XXX 6414 ins_pipe(pipe_slow); // XXX
7159 %} 6415 %}
7160 6416
7161 //----------BSWAP Instructions------------------------------------------------- 6417 //----------BSWAP Instructions-------------------------------------------------
7162 instruct bytes_reverse_int(rRegI dst) %{ 6418 instruct bytes_reverse_int(rRegI dst) %{
7442 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6698 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
7443 ins_encode(); 6699 ins_encode();
7444 ins_pipe(empty); 6700 ins_pipe(empty);
7445 %} 6701 %}
7446 6702
6703 instruct membar_storestore() %{
6704 match(MemBarStoreStore);
6705 ins_cost(0);
6706
6707 size(0);
6708 format %{ "MEMBAR-storestore (empty encoding)" %}
6709 ins_encode( );
6710 ins_pipe(empty);
6711 %}
6712
7447 //----------Move Instructions-------------------------------------------------- 6713 //----------Move Instructions--------------------------------------------------
7448 6714
7449 instruct castX2P(rRegP dst, rRegL src) 6715 instruct castX2P(rRegP dst, rRegL src)
7450 %{ 6716 %{
7451 match(Set dst (CastX2P src)); 6717 match(Set dst (CastX2P src));
7452 6718
7453 format %{ "movq $dst, $src\t# long->ptr" %} 6719 format %{ "movq $dst, $src\t# long->ptr" %}
7454 ins_encode(enc_copy_wide(dst, src)); 6720 ins_encode %{
6721 if ($dst$$reg != $src$$reg) {
6722 __ movptr($dst$$Register, $src$$Register);
6723 }
6724 %}
7455 ins_pipe(ialu_reg_reg); // XXX 6725 ins_pipe(ialu_reg_reg); // XXX
7456 %} 6726 %}
7457 6727
7458 instruct castP2X(rRegL dst, rRegP src) 6728 instruct castP2X(rRegL dst, rRegP src)
7459 %{ 6729 %{
7460 match(Set dst (CastP2X src)); 6730 match(Set dst (CastP2X src));
7461 6731
7462 format %{ "movq $dst, $src\t# ptr -> long" %} 6732 format %{ "movq $dst, $src\t# ptr -> long" %}
7463 ins_encode(enc_copy_wide(dst, src)); 6733 ins_encode %{
6734 if ($dst$$reg != $src$$reg) {
6735 __ movptr($dst$$Register, $src$$Register);
6736 }
6737 %}
7464 ins_pipe(ialu_reg_reg); // XXX 6738 ins_pipe(ialu_reg_reg); // XXX
7465 %} 6739 %}
7466 6740
7467 6741
7468 // Convert oop pointer into compressed form 6742 // Convert oop pointer into compressed form
7811 7085
7812 ins_cost(200); // XXX 7086 ins_cost(200); // XXX
7813 format %{ "jn$cop skip\t# signed cmove float\n\t" 7087 format %{ "jn$cop skip\t# signed cmove float\n\t"
7814 "movss $dst, $src\n" 7088 "movss $dst, $src\n"
7815 "skip:" %} 7089 "skip:" %}
7816 ins_encode(enc_cmovf_branch(cop, dst, src)); 7090 ins_encode %{
7091 Label Lskip;
7092 // Invert sense of branch from sense of CMOV
7093 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7094 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7095 __ bind(Lskip);
7096 %}
7817 ins_pipe(pipe_slow); 7097 ins_pipe(pipe_slow);
7818 %} 7098 %}
7819 7099
7820 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7100 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7821 // %{ 7101 // %{
7835 7115
7836 ins_cost(200); // XXX 7116 ins_cost(200); // XXX
7837 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7117 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7838 "movss $dst, $src\n" 7118 "movss $dst, $src\n"
7839 "skip:" %} 7119 "skip:" %}
7840 ins_encode(enc_cmovf_branch(cop, dst, src)); 7120 ins_encode %{
7121 Label Lskip;
7122 // Invert sense of branch from sense of CMOV
7123 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7124 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7125 __ bind(Lskip);
7126 %}
7841 ins_pipe(pipe_slow); 7127 ins_pipe(pipe_slow);
7842 %} 7128 %}
7843 7129
7844 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7130 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7845 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7131 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7855 7141
7856 ins_cost(200); // XXX 7142 ins_cost(200); // XXX
7857 format %{ "jn$cop skip\t# signed cmove double\n\t" 7143 format %{ "jn$cop skip\t# signed cmove double\n\t"
7858 "movsd $dst, $src\n" 7144 "movsd $dst, $src\n"
7859 "skip:" %} 7145 "skip:" %}
7860 ins_encode(enc_cmovd_branch(cop, dst, src)); 7146 ins_encode %{
7147 Label Lskip;
7148 // Invert sense of branch from sense of CMOV
7149 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7150 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7151 __ bind(Lskip);
7152 %}
7861 ins_pipe(pipe_slow); 7153 ins_pipe(pipe_slow);
7862 %} 7154 %}
7863 7155
7864 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7156 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7865 %{ 7157 %{
7867 7159
7868 ins_cost(200); // XXX 7160 ins_cost(200); // XXX
7869 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7161 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7870 "movsd $dst, $src\n" 7162 "movsd $dst, $src\n"
7871 "skip:" %} 7163 "skip:" %}
7872 ins_encode(enc_cmovd_branch(cop, dst, src)); 7164 ins_encode %{
7165 Label Lskip;
7166 // Invert sense of branch from sense of CMOV
7167 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7168 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7169 __ bind(Lskip);
7170 %}
7873 ins_pipe(pipe_slow); 7171 ins_pipe(pipe_slow);
7874 %} 7172 %}
7875 7173
7876 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7174 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7877 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7175 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
10189 format %{ "ucomiss $src1, $src2\n\t" 9487 format %{ "ucomiss $src1, $src2\n\t"
10190 "jnp,s exit\n\t" 9488 "jnp,s exit\n\t"
10191 "pushfq\t# saw NaN, set CF\n\t" 9489 "pushfq\t# saw NaN, set CF\n\t"
10192 "andq [rsp], #0xffffff2b\n\t" 9490 "andq [rsp], #0xffffff2b\n\t"
10193 "popfq\n" 9491 "popfq\n"
10194 "exit: nop\t# avoid branch to branch" %} 9492 "exit:" %}
10195 opcode(0x0F, 0x2E); 9493 ins_encode %{
10196 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 9494 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10197 cmpfp_fixup); 9495 emit_cmpfp_fixup(_masm);
9496 %}
10198 ins_pipe(pipe_slow); 9497 ins_pipe(pipe_slow);
10199 %} 9498 %}
10200 9499
10201 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9500 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10202 match(Set cr (CmpF src1 src2)); 9501 match(Set cr (CmpF src1 src2));
10203 9502
10204 ins_cost(145); 9503 ins_cost(100);
10205 format %{ "ucomiss $src1, $src2" %} 9504 format %{ "ucomiss $src1, $src2" %}
10206 ins_encode %{ 9505 ins_encode %{
10207 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9506 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10208 %} 9507 %}
10209 ins_pipe(pipe_slow); 9508 ins_pipe(pipe_slow);
10217 format %{ "ucomiss $src1, $src2\n\t" 9516 format %{ "ucomiss $src1, $src2\n\t"
10218 "jnp,s exit\n\t" 9517 "jnp,s exit\n\t"
10219 "pushfq\t# saw NaN, set CF\n\t" 9518 "pushfq\t# saw NaN, set CF\n\t"
10220 "andq [rsp], #0xffffff2b\n\t" 9519 "andq [rsp], #0xffffff2b\n\t"
10221 "popfq\n" 9520 "popfq\n"
10222 "exit: nop\t# avoid branch to branch" %} 9521 "exit:" %}
10223 opcode(0x0F, 0x2E); 9522 ins_encode %{
10224 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 9523 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10225 cmpfp_fixup); 9524 emit_cmpfp_fixup(_masm);
9525 %}
10226 ins_pipe(pipe_slow); 9526 ins_pipe(pipe_slow);
10227 %} 9527 %}
10228 9528
10229 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9529 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10230 match(Set cr (CmpF src1 (LoadF src2))); 9530 match(Set cr (CmpF src1 (LoadF src2)));
10231 9531
10232 ins_cost(100); 9532 ins_cost(100);
10233 format %{ "ucomiss $src1, $src2" %} 9533 format %{ "ucomiss $src1, $src2" %}
10234 opcode(0x0F, 0x2E); 9534 ins_encode %{
10235 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2)); 9535 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9536 %}
10236 ins_pipe(pipe_slow); 9537 ins_pipe(pipe_slow);
10237 %} 9538 %}
10238 9539
10239 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9540 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10240 match(Set cr (CmpF src con)); 9541 match(Set cr (CmpF src con));
10243 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9544 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10244 "jnp,s exit\n\t" 9545 "jnp,s exit\n\t"
10245 "pushfq\t# saw NaN, set CF\n\t" 9546 "pushfq\t# saw NaN, set CF\n\t"
10246 "andq [rsp], #0xffffff2b\n\t" 9547 "andq [rsp], #0xffffff2b\n\t"
10247 "popfq\n" 9548 "popfq\n"
10248 "exit: nop\t# avoid branch to branch" %} 9549 "exit:" %}
10249 ins_encode %{ 9550 ins_encode %{
10250 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9551 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10251 emit_cmpfp_fixup(_masm); 9552 emit_cmpfp_fixup(_masm);
10252 %} 9553 %}
10253 ins_pipe(pipe_slow); 9554 ins_pipe(pipe_slow);
10271 format %{ "ucomisd $src1, $src2\n\t" 9572 format %{ "ucomisd $src1, $src2\n\t"
10272 "jnp,s exit\n\t" 9573 "jnp,s exit\n\t"
10273 "pushfq\t# saw NaN, set CF\n\t" 9574 "pushfq\t# saw NaN, set CF\n\t"
10274 "andq [rsp], #0xffffff2b\n\t" 9575 "andq [rsp], #0xffffff2b\n\t"
10275 "popfq\n" 9576 "popfq\n"
10276 "exit: nop\t# avoid branch to branch" %} 9577 "exit:" %}
10277 opcode(0x66, 0x0F, 0x2E); 9578 ins_encode %{
10278 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 9579 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10279 cmpfp_fixup); 9580 emit_cmpfp_fixup(_masm);
9581 %}
10280 ins_pipe(pipe_slow); 9582 ins_pipe(pipe_slow);
10281 %} 9583 %}
10282 9584
10283 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9585 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10284 match(Set cr (CmpD src1 src2)); 9586 match(Set cr (CmpD src1 src2));
10299 format %{ "ucomisd $src1, $src2\n\t" 9601 format %{ "ucomisd $src1, $src2\n\t"
10300 "jnp,s exit\n\t" 9602 "jnp,s exit\n\t"
10301 "pushfq\t# saw NaN, set CF\n\t" 9603 "pushfq\t# saw NaN, set CF\n\t"
10302 "andq [rsp], #0xffffff2b\n\t" 9604 "andq [rsp], #0xffffff2b\n\t"
10303 "popfq\n" 9605 "popfq\n"
10304 "exit: nop\t# avoid branch to branch" %} 9606 "exit:" %}
10305 opcode(0x66, 0x0F, 0x2E); 9607 ins_encode %{
10306 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 9608 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10307 cmpfp_fixup); 9609 emit_cmpfp_fixup(_masm);
9610 %}
10308 ins_pipe(pipe_slow); 9611 ins_pipe(pipe_slow);
10309 %} 9612 %}
10310 9613
10311 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9614 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10312 match(Set cr (CmpD src1 (LoadD src2))); 9615 match(Set cr (CmpD src1 (LoadD src2)));
10313 9616
10314 ins_cost(100); 9617 ins_cost(100);
10315 format %{ "ucomisd $src1, $src2" %} 9618 format %{ "ucomisd $src1, $src2" %}
10316 opcode(0x66, 0x0F, 0x2E); 9619 ins_encode %{
10317 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2)); 9620 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9621 %}
10318 ins_pipe(pipe_slow); 9622 ins_pipe(pipe_slow);
10319 %} 9623 %}
10320 9624
10321 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9625 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10322 match(Set cr (CmpD src con)); 9626 match(Set cr (CmpD src con));
10325 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9629 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10326 "jnp,s exit\n\t" 9630 "jnp,s exit\n\t"
10327 "pushfq\t# saw NaN, set CF\n\t" 9631 "pushfq\t# saw NaN, set CF\n\t"
10328 "andq [rsp], #0xffffff2b\n\t" 9632 "andq [rsp], #0xffffff2b\n\t"
10329 "popfq\n" 9633 "popfq\n"
10330 "exit: nop\t# avoid branch to branch" %} 9634 "exit:" %}
10331 ins_encode %{ 9635 ins_encode %{
10332 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9636 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10333 emit_cmpfp_fixup(_masm); 9637 emit_cmpfp_fixup(_masm);
10334 %} 9638 %}
10335 ins_pipe(pipe_slow); 9639 ins_pipe(pipe_slow);
10357 "jp,s done\n\t" 9661 "jp,s done\n\t"
10358 "jb,s done\n\t" 9662 "jb,s done\n\t"
10359 "setne $dst\n\t" 9663 "setne $dst\n\t"
10360 "movzbl $dst, $dst\n" 9664 "movzbl $dst, $dst\n"
10361 "done:" %} 9665 "done:" %}
10362 9666 ins_encode %{
10363 opcode(0x0F, 0x2E); 9667 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10364 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 9668 emit_cmpfp3(_masm, $dst$$Register);
10365 cmpfp3(dst)); 9669 %}
10366 ins_pipe(pipe_slow); 9670 ins_pipe(pipe_slow);
10367 %} 9671 %}
10368 9672
10369 // Compare into -1,0,1 9673 // Compare into -1,0,1
10370 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9674 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10378 "jp,s done\n\t" 9682 "jp,s done\n\t"
10379 "jb,s done\n\t" 9683 "jb,s done\n\t"
10380 "setne $dst\n\t" 9684 "setne $dst\n\t"
10381 "movzbl $dst, $dst\n" 9685 "movzbl $dst, $dst\n"
10382 "done:" %} 9686 "done:" %}
10383 9687 ins_encode %{
10384 opcode(0x0F, 0x2E); 9688 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10385 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 9689 emit_cmpfp3(_masm, $dst$$Register);
10386 cmpfp3(dst)); 9690 %}
10387 ins_pipe(pipe_slow); 9691 ins_pipe(pipe_slow);
10388 %} 9692 %}
10389 9693
10390 // Compare into -1,0,1 9694 // Compare into -1,0,1
10391 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9695 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10399 "jb,s done\n\t" 9703 "jb,s done\n\t"
10400 "setne $dst\n\t" 9704 "setne $dst\n\t"
10401 "movzbl $dst, $dst\n" 9705 "movzbl $dst, $dst\n"
10402 "done:" %} 9706 "done:" %}
10403 ins_encode %{ 9707 ins_encode %{
10404 Label L_done;
10405 Register Rdst = $dst$$Register;
10406 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9708 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10407 __ movl(Rdst, -1); 9709 emit_cmpfp3(_masm, $dst$$Register);
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 %} 9710 %}
10414 ins_pipe(pipe_slow); 9711 ins_pipe(pipe_slow);
10415 %} 9712 %}
10416 9713
10417 // Compare into -1,0,1 9714 // Compare into -1,0,1
10426 "jp,s done\n\t" 9723 "jp,s done\n\t"
10427 "jb,s done\n\t" 9724 "jb,s done\n\t"
10428 "setne $dst\n\t" 9725 "setne $dst\n\t"
10429 "movzbl $dst, $dst\n" 9726 "movzbl $dst, $dst\n"
10430 "done:" %} 9727 "done:" %}
10431 9728 ins_encode %{
10432 opcode(0x66, 0x0F, 0x2E); 9729 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10433 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 9730 emit_cmpfp3(_masm, $dst$$Register);
10434 cmpfp3(dst)); 9731 %}
10435 ins_pipe(pipe_slow); 9732 ins_pipe(pipe_slow);
10436 %} 9733 %}
10437 9734
10438 // Compare into -1,0,1 9735 // Compare into -1,0,1
10439 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9736 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10447 "jp,s done\n\t" 9744 "jp,s done\n\t"
10448 "jb,s done\n\t" 9745 "jb,s done\n\t"
10449 "setne $dst\n\t" 9746 "setne $dst\n\t"
10450 "movzbl $dst, $dst\n" 9747 "movzbl $dst, $dst\n"
10451 "done:" %} 9748 "done:" %}
10452 9749 ins_encode %{
10453 opcode(0x66, 0x0F, 0x2E); 9750 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10454 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 9751 emit_cmpfp3(_masm, $dst$$Register);
10455 cmpfp3(dst)); 9752 %}
10456 ins_pipe(pipe_slow); 9753 ins_pipe(pipe_slow);
10457 %} 9754 %}
10458 9755
10459 // Compare into -1,0,1 9756 // Compare into -1,0,1
10460 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9757 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10468 "jb,s done\n\t" 9765 "jb,s done\n\t"
10469 "setne $dst\n\t" 9766 "setne $dst\n\t"
10470 "movzbl $dst, $dst\n" 9767 "movzbl $dst, $dst\n"
10471 "done:" %} 9768 "done:" %}
10472 ins_encode %{ 9769 ins_encode %{
10473 Register Rdst = $dst$$Register;
10474 Label L_done;
10475 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9770 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10476 __ movl(Rdst, -1); 9771 emit_cmpfp3(_masm, $dst$$Register);
10477 __ jcc(Assembler::parity, L_done); 9772 %}
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); 9773 ins_pipe(pipe_slow);
10842 %} 9774 %}
10843 9775
10844 // -----------Trig and Trancendental Instructions------------------------------ 9776 // -----------Trig and Trancendental Instructions------------------------------
10845 instruct cosD_reg(regD dst) %{ 9777 instruct cosD_reg(regD dst) %{
10927 instruct convF2D_reg_reg(regD dst, regF src) 9859 instruct convF2D_reg_reg(regD dst, regF src)
10928 %{ 9860 %{
10929 match(Set dst (ConvF2D src)); 9861 match(Set dst (ConvF2D src));
10930 9862
10931 format %{ "cvtss2sd $dst, $src" %} 9863 format %{ "cvtss2sd $dst, $src" %}
10932 opcode(0xF3, 0x0F, 0x5A); 9864 ins_encode %{
10933 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 9865 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
9866 %}
10934 ins_pipe(pipe_slow); // XXX 9867 ins_pipe(pipe_slow); // XXX
10935 %} 9868 %}
10936 9869
10937 instruct convF2D_reg_mem(regD dst, memory src) 9870 instruct convF2D_reg_mem(regD dst, memory src)
10938 %{ 9871 %{
10939 match(Set dst (ConvF2D (LoadF src))); 9872 match(Set dst (ConvF2D (LoadF src)));
10940 9873
10941 format %{ "cvtss2sd $dst, $src" %} 9874 format %{ "cvtss2sd $dst, $src" %}
10942 opcode(0xF3, 0x0F, 0x5A); 9875 ins_encode %{
10943 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 9876 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
9877 %}
10944 ins_pipe(pipe_slow); // XXX 9878 ins_pipe(pipe_slow); // XXX
10945 %} 9879 %}
10946 9880
10947 instruct convD2F_reg_reg(regF dst, regD src) 9881 instruct convD2F_reg_reg(regF dst, regD src)
10948 %{ 9882 %{
10949 match(Set dst (ConvD2F src)); 9883 match(Set dst (ConvD2F src));
10950 9884
10951 format %{ "cvtsd2ss $dst, $src" %} 9885 format %{ "cvtsd2ss $dst, $src" %}
10952 opcode(0xF2, 0x0F, 0x5A); 9886 ins_encode %{
10953 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 9887 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
9888 %}
10954 ins_pipe(pipe_slow); // XXX 9889 ins_pipe(pipe_slow); // XXX
10955 %} 9890 %}
10956 9891
10957 instruct convD2F_reg_mem(regF dst, memory src) 9892 instruct convD2F_reg_mem(regF dst, memory src)
10958 %{ 9893 %{
10959 match(Set dst (ConvD2F (LoadD src))); 9894 match(Set dst (ConvD2F (LoadD src)));
10960 9895
10961 format %{ "cvtsd2ss $dst, $src" %} 9896 format %{ "cvtsd2ss $dst, $src" %}
10962 opcode(0xF2, 0x0F, 0x5A); 9897 ins_encode %{
10963 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 9898 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
9899 %}
10964 ins_pipe(pipe_slow); // XXX 9900 ins_pipe(pipe_slow); // XXX
10965 %} 9901 %}
10966 9902
10967 // XXX do mem variants 9903 // XXX do mem variants
10968 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9904 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10976 "subq rsp, #8\n\t" 9912 "subq rsp, #8\n\t"
10977 "movss [rsp], $src\n\t" 9913 "movss [rsp], $src\n\t"
10978 "call f2i_fixup\n\t" 9914 "call f2i_fixup\n\t"
10979 "popq $dst\n" 9915 "popq $dst\n"
10980 "done: "%} 9916 "done: "%}
10981 opcode(0xF3, 0x0F, 0x2C); 9917 ins_encode %{
10982 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 9918 Label done;
10983 f2i_fixup(dst, src)); 9919 __ cvttss2sil($dst$$Register, $src$$XMMRegister);
9920 __ cmpl($dst$$Register, 0x80000000);
9921 __ jccb(Assembler::notEqual, done);
9922 __ subptr(rsp, 8);
9923 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9924 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
9925 __ pop($dst$$Register);
9926 __ bind(done);
9927 %}
10984 ins_pipe(pipe_slow); 9928 ins_pipe(pipe_slow);
10985 %} 9929 %}
10986 9930
10987 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9931 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10988 %{ 9932 %{
10995 "subq rsp, #8\n\t" 9939 "subq rsp, #8\n\t"
10996 "movss [rsp], $src\n\t" 9940 "movss [rsp], $src\n\t"
10997 "call f2l_fixup\n\t" 9941 "call f2l_fixup\n\t"
10998 "popq $dst\n" 9942 "popq $dst\n"
10999 "done: "%} 9943 "done: "%}
11000 opcode(0xF3, 0x0F, 0x2C); 9944 ins_encode %{
11001 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 9945 Label done;
11002 f2l_fixup(dst, src)); 9946 __ cvttss2siq($dst$$Register, $src$$XMMRegister);
9947 __ cmp64($dst$$Register,
9948 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
9949 __ jccb(Assembler::notEqual, done);
9950 __ subptr(rsp, 8);
9951 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9952 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
9953 __ pop($dst$$Register);
9954 __ bind(done);
9955 %}
11003 ins_pipe(pipe_slow); 9956 ins_pipe(pipe_slow);
11004 %} 9957 %}
11005 9958
11006 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9959 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
11007 %{ 9960 %{
11014 "subq rsp, #8\n\t" 9967 "subq rsp, #8\n\t"
11015 "movsd [rsp], $src\n\t" 9968 "movsd [rsp], $src\n\t"
11016 "call d2i_fixup\n\t" 9969 "call d2i_fixup\n\t"
11017 "popq $dst\n" 9970 "popq $dst\n"
11018 "done: "%} 9971 "done: "%}
11019 opcode(0xF2, 0x0F, 0x2C); 9972 ins_encode %{
11020 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 9973 Label done;
11021 d2i_fixup(dst, src)); 9974 __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
9975 __ cmpl($dst$$Register, 0x80000000);
9976 __ jccb(Assembler::notEqual, done);
9977 __ subptr(rsp, 8);
9978 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9979 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
9980 __ pop($dst$$Register);
9981 __ bind(done);
9982 %}
11022 ins_pipe(pipe_slow); 9983 ins_pipe(pipe_slow);
11023 %} 9984 %}
11024 9985
11025 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9986 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
11026 %{ 9987 %{
11033 "subq rsp, #8\n\t" 9994 "subq rsp, #8\n\t"
11034 "movsd [rsp], $src\n\t" 9995 "movsd [rsp], $src\n\t"
11035 "call d2l_fixup\n\t" 9996 "call d2l_fixup\n\t"
11036 "popq $dst\n" 9997 "popq $dst\n"
11037 "done: "%} 9998 "done: "%}
11038 opcode(0xF2, 0x0F, 0x2C); 9999 ins_encode %{
11039 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 10000 Label done;
11040 d2l_fixup(dst, src)); 10001 __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10002 __ cmp64($dst$$Register,
10003 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10004 __ jccb(Assembler::notEqual, done);
10005 __ subptr(rsp, 8);
10006 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10007 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10008 __ pop($dst$$Register);
10009 __ bind(done);
10010 %}
11041 ins_pipe(pipe_slow); 10011 ins_pipe(pipe_slow);
11042 %} 10012 %}
11043 10013
11044 instruct convI2F_reg_reg(regF dst, rRegI src) 10014 instruct convI2F_reg_reg(regF dst, rRegI src)
11045 %{ 10015 %{
11046 predicate(!UseXmmI2F); 10016 predicate(!UseXmmI2F);
11047 match(Set dst (ConvI2F src)); 10017 match(Set dst (ConvI2F src));
11048 10018
11049 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10019 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11050 opcode(0xF3, 0x0F, 0x2A); 10020 ins_encode %{
11051 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10021 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10022 %}
11052 ins_pipe(pipe_slow); // XXX 10023 ins_pipe(pipe_slow); // XXX
11053 %} 10024 %}
11054 10025
11055 instruct convI2F_reg_mem(regF dst, memory src) 10026 instruct convI2F_reg_mem(regF dst, memory src)
11056 %{ 10027 %{
11057 match(Set dst (ConvI2F (LoadI src))); 10028 match(Set dst (ConvI2F (LoadI src)));
11058 10029
11059 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10030 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11060 opcode(0xF3, 0x0F, 0x2A); 10031 ins_encode %{
11061 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10032 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10033 %}
11062 ins_pipe(pipe_slow); // XXX 10034 ins_pipe(pipe_slow); // XXX
11063 %} 10035 %}
11064 10036
11065 instruct convI2D_reg_reg(regD dst, rRegI src) 10037 instruct convI2D_reg_reg(regD dst, rRegI src)
11066 %{ 10038 %{
11067 predicate(!UseXmmI2D); 10039 predicate(!UseXmmI2D);
11068 match(Set dst (ConvI2D src)); 10040 match(Set dst (ConvI2D src));
11069 10041
11070 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10042 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11071 opcode(0xF2, 0x0F, 0x2A); 10043 ins_encode %{
11072 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10044 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10045 %}
11073 ins_pipe(pipe_slow); // XXX 10046 ins_pipe(pipe_slow); // XXX
11074 %} 10047 %}
11075 10048
11076 instruct convI2D_reg_mem(regD dst, memory src) 10049 instruct convI2D_reg_mem(regD dst, memory src)
11077 %{ 10050 %{
11078 match(Set dst (ConvI2D (LoadI src))); 10051 match(Set dst (ConvI2D (LoadI src)));
11079 10052
11080 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10053 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11081 opcode(0xF2, 0x0F, 0x2A); 10054 ins_encode %{
11082 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10055 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10056 %}
11083 ins_pipe(pipe_slow); // XXX 10057 ins_pipe(pipe_slow); // XXX
11084 %} 10058 %}
11085 10059
11086 instruct convXI2F_reg(regF dst, rRegI src) 10060 instruct convXI2F_reg(regF dst, rRegI src)
11087 %{ 10061 %{
11114 instruct convL2F_reg_reg(regF dst, rRegL src) 10088 instruct convL2F_reg_reg(regF dst, rRegL src)
11115 %{ 10089 %{
11116 match(Set dst (ConvL2F src)); 10090 match(Set dst (ConvL2F src));
11117 10091
11118 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10092 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11119 opcode(0xF3, 0x0F, 0x2A); 10093 ins_encode %{
11120 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10094 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10095 %}
11121 ins_pipe(pipe_slow); // XXX 10096 ins_pipe(pipe_slow); // XXX
11122 %} 10097 %}
11123 10098
11124 instruct convL2F_reg_mem(regF dst, memory src) 10099 instruct convL2F_reg_mem(regF dst, memory src)
11125 %{ 10100 %{
11126 match(Set dst (ConvL2F (LoadL src))); 10101 match(Set dst (ConvL2F (LoadL src)));
11127 10102
11128 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10103 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11129 opcode(0xF3, 0x0F, 0x2A); 10104 ins_encode %{
11130 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10105 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10106 %}
11131 ins_pipe(pipe_slow); // XXX 10107 ins_pipe(pipe_slow); // XXX
11132 %} 10108 %}
11133 10109
11134 instruct convL2D_reg_reg(regD dst, rRegL src) 10110 instruct convL2D_reg_reg(regD dst, rRegL src)
11135 %{ 10111 %{
11136 match(Set dst (ConvL2D src)); 10112 match(Set dst (ConvL2D src));
11137 10113
11138 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10114 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11139 opcode(0xF2, 0x0F, 0x2A); 10115 ins_encode %{
11140 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10116 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10117 %}
11141 ins_pipe(pipe_slow); // XXX 10118 ins_pipe(pipe_slow); // XXX
11142 %} 10119 %}
11143 10120
11144 instruct convL2D_reg_mem(regD dst, memory src) 10121 instruct convL2D_reg_mem(regD dst, memory src)
11145 %{ 10122 %{
11146 match(Set dst (ConvL2D (LoadL src))); 10123 match(Set dst (ConvL2D (LoadL src)));
11147 10124
11148 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10125 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11149 opcode(0xF2, 0x0F, 0x2A); 10126 ins_encode %{
11150 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10127 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10128 %}
11151 ins_pipe(pipe_slow); // XXX 10129 ins_pipe(pipe_slow); // XXX
11152 %} 10130 %}
11153 10131
11154 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10132 instruct convI2L_reg_reg(rRegL dst, rRegI src)
11155 %{ 10133 %{
11184 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10162 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
11185 %{ 10163 %{
11186 match(Set dst (AndL (ConvI2L src) mask)); 10164 match(Set dst (AndL (ConvI2L src) mask));
11187 10165
11188 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10166 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11189 ins_encode(enc_copy(dst, src)); 10167 ins_encode %{
10168 if ($dst$$reg != $src$$reg) {
10169 __ movl($dst$$Register, $src$$Register);
10170 }
10171 %}
11190 ins_pipe(ialu_reg_reg); 10172 ins_pipe(ialu_reg_reg);
11191 %} 10173 %}
11192 10174
11193 // Zero-extend convert int to long 10175 // Zero-extend convert int to long
11194 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10176 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
11195 %{ 10177 %{
11196 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10178 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
11197 10179
11198 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10180 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11199 opcode(0x8B); 10181 ins_encode %{
11200 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 10182 __ movl($dst$$Register, $src$$Address);
10183 %}
11201 ins_pipe(ialu_reg_mem); 10184 ins_pipe(ialu_reg_mem);
11202 %} 10185 %}
11203 10186
11204 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10187 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
11205 %{ 10188 %{
11206 match(Set dst (AndL src mask)); 10189 match(Set dst (AndL src mask));
11207 10190
11208 format %{ "movl $dst, $src\t# zero-extend long" %} 10191 format %{ "movl $dst, $src\t# zero-extend long" %}
11209 ins_encode(enc_copy_always(dst, src)); 10192 ins_encode %{
10193 __ movl($dst$$Register, $src$$Register);
10194 %}
11210 ins_pipe(ialu_reg_reg); 10195 ins_pipe(ialu_reg_reg);
11211 %} 10196 %}
11212 10197
11213 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10198 instruct convL2I_reg_reg(rRegI dst, rRegL src)
11214 %{ 10199 %{
11215 match(Set dst (ConvL2I src)); 10200 match(Set dst (ConvL2I src));
11216 10201
11217 format %{ "movl $dst, $src\t# l2i" %} 10202 format %{ "movl $dst, $src\t# l2i" %}
11218 ins_encode(enc_copy_always(dst, src)); 10203 ins_encode %{
10204 __ movl($dst$$Register, $src$$Register);
10205 %}
11219 ins_pipe(ialu_reg_reg); 10206 ins_pipe(ialu_reg_reg);
11220 %} 10207 %}
11221 10208
11222 10209
11223 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10210 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11224 match(Set dst (MoveF2I src)); 10211 match(Set dst (MoveF2I src));
11225 effect(DEF dst, USE src); 10212 effect(DEF dst, USE src);
11226 10213
11227 ins_cost(125); 10214 ins_cost(125);
11228 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10215 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
11229 opcode(0x8B); 10216 ins_encode %{
11230 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 10217 __ movl($dst$$Register, Address(rsp, $src$$disp));
10218 %}
11231 ins_pipe(ialu_reg_mem); 10219 ins_pipe(ialu_reg_mem);
11232 %} 10220 %}
11233 10221
11234 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10222 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
11235 match(Set dst (MoveI2F src)); 10223 match(Set dst (MoveI2F src));
11236 effect(DEF dst, USE src); 10224 effect(DEF dst, USE src);
11237 10225
11238 ins_cost(125); 10226 ins_cost(125);
11239 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10227 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
11240 opcode(0xF3, 0x0F, 0x10); 10228 ins_encode %{
11241 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10229 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10230 %}
11242 ins_pipe(pipe_slow); 10231 ins_pipe(pipe_slow);
11243 %} 10232 %}
11244 10233
11245 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10234 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
11246 match(Set dst (MoveD2L src)); 10235 match(Set dst (MoveD2L src));
11247 effect(DEF dst, USE src); 10236 effect(DEF dst, USE src);
11248 10237
11249 ins_cost(125); 10238 ins_cost(125);
11250 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10239 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
11251 opcode(0x8B); 10240 ins_encode %{
11252 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10241 __ movq($dst$$Register, Address(rsp, $src$$disp));
10242 %}
11253 ins_pipe(ialu_reg_mem); 10243 ins_pipe(ialu_reg_mem);
11254 %} 10244 %}
11255 10245
11256 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10246 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
11257 predicate(!UseXmmLoadAndClearUpper); 10247 predicate(!UseXmmLoadAndClearUpper);
11258 match(Set dst (MoveL2D src)); 10248 match(Set dst (MoveL2D src));
11259 effect(DEF dst, USE src); 10249 effect(DEF dst, USE src);
11260 10250
11261 ins_cost(125); 10251 ins_cost(125);
11262 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10252 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
11263 opcode(0x66, 0x0F, 0x12); 10253 ins_encode %{
11264 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10254 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10255 %}
11265 ins_pipe(pipe_slow); 10256 ins_pipe(pipe_slow);
11266 %} 10257 %}
11267 10258
11268 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10259 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
11269 predicate(UseXmmLoadAndClearUpper); 10260 predicate(UseXmmLoadAndClearUpper);
11270 match(Set dst (MoveL2D src)); 10261 match(Set dst (MoveL2D src));
11271 effect(DEF dst, USE src); 10262 effect(DEF dst, USE src);
11272 10263
11273 ins_cost(125); 10264 ins_cost(125);
11274 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10265 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
11275 opcode(0xF2, 0x0F, 0x10); 10266 ins_encode %{
11276 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10267 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10268 %}
11277 ins_pipe(pipe_slow); 10269 ins_pipe(pipe_slow);
11278 %} 10270 %}
11279 10271
11280 10272
11281 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10273 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
11282 match(Set dst (MoveF2I src)); 10274 match(Set dst (MoveF2I src));
11283 effect(DEF dst, USE src); 10275 effect(DEF dst, USE src);
11284 10276
11285 ins_cost(95); // XXX 10277 ins_cost(95); // XXX
11286 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10278 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
11287 opcode(0xF3, 0x0F, 0x11); 10279 ins_encode %{
11288 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 10280 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10281 %}
11289 ins_pipe(pipe_slow); 10282 ins_pipe(pipe_slow);
11290 %} 10283 %}
11291 10284
11292 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10285 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
11293 match(Set dst (MoveI2F src)); 10286 match(Set dst (MoveI2F src));
11294 effect(DEF dst, USE src); 10287 effect(DEF dst, USE src);
11295 10288
11296 ins_cost(100); 10289 ins_cost(100);
11297 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10290 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
11298 opcode(0x89); 10291 ins_encode %{
11299 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 10292 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10293 %}
11300 ins_pipe( ialu_mem_reg ); 10294 ins_pipe( ialu_mem_reg );
11301 %} 10295 %}
11302 10296
11303 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10297 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
11304 match(Set dst (MoveD2L src)); 10298 match(Set dst (MoveD2L src));
11305 effect(DEF dst, USE src); 10299 effect(DEF dst, USE src);
11306 10300
11307 ins_cost(95); // XXX 10301 ins_cost(95); // XXX
11308 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10302 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
11309 opcode(0xF2, 0x0F, 0x11); 10303 ins_encode %{
11310 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 10304 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10305 %}
11311 ins_pipe(pipe_slow); 10306 ins_pipe(pipe_slow);
11312 %} 10307 %}
11313 10308
11314 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10309 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
11315 match(Set dst (MoveL2D src)); 10310 match(Set dst (MoveL2D src));
11316 effect(DEF dst, USE src); 10311 effect(DEF dst, USE src);
11317 10312
11318 ins_cost(100); 10313 ins_cost(100);
11319 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10314 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
11320 opcode(0x89); 10315 ins_encode %{
11321 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10316 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10317 %}
11322 ins_pipe(ialu_mem_reg); 10318 ins_pipe(ialu_mem_reg);
11323 %} 10319 %}
11324 10320
11325 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10321 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
11326 match(Set dst (MoveF2I src)); 10322 match(Set dst (MoveF2I src));
11327 effect(DEF dst, USE src); 10323 effect(DEF dst, USE src);
11328 ins_cost(85); 10324 ins_cost(85);
11329 format %{ "movd $dst,$src\t# MoveF2I" %} 10325 format %{ "movd $dst,$src\t# MoveF2I" %}
11330 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %} 10326 ins_encode %{
10327 __ movdl($dst$$Register, $src$$XMMRegister);
10328 %}
11331 ins_pipe( pipe_slow ); 10329 ins_pipe( pipe_slow );
11332 %} 10330 %}
11333 10331
11334 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10332 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
11335 match(Set dst (MoveD2L src)); 10333 match(Set dst (MoveD2L src));
11336 effect(DEF dst, USE src); 10334 effect(DEF dst, USE src);
11337 ins_cost(85); 10335 ins_cost(85);
11338 format %{ "movd $dst,$src\t# MoveD2L" %} 10336 format %{ "movd $dst,$src\t# MoveD2L" %}
11339 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %} 10337 ins_encode %{
10338 __ movdq($dst$$Register, $src$$XMMRegister);
10339 %}
11340 ins_pipe( pipe_slow ); 10340 ins_pipe( pipe_slow );
11341 %} 10341 %}
11342 10342
11343 // The next instructions have long latency and use Int unit. Set high cost. 10343 // The next instructions have long latency and use Int unit. Set high cost.
11344 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10344 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
11345 match(Set dst (MoveI2F src)); 10345 match(Set dst (MoveI2F src));
11346 effect(DEF dst, USE src); 10346 effect(DEF dst, USE src);
11347 ins_cost(300); 10347 ins_cost(300);
11348 format %{ "movd $dst,$src\t# MoveI2F" %} 10348 format %{ "movd $dst,$src\t# MoveI2F" %}
11349 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %} 10349 ins_encode %{
10350 __ movdl($dst$$XMMRegister, $src$$Register);
10351 %}
11350 ins_pipe( pipe_slow ); 10352 ins_pipe( pipe_slow );
11351 %} 10353 %}
11352 10354
11353 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10355 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
11354 match(Set dst (MoveL2D src)); 10356 match(Set dst (MoveL2D src));
11355 effect(DEF dst, USE src); 10357 effect(DEF dst, USE src);
11356 ins_cost(300); 10358 ins_cost(300);
11357 format %{ "movd $dst,$src\t# MoveL2D" %} 10359 format %{ "movd $dst,$src\t# MoveL2D" %}
11358 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %} 10360 ins_encode %{
10361 __ movdq($dst$$XMMRegister, $src$$Register);
10362 %}
11359 ins_pipe( pipe_slow ); 10363 ins_pipe( pipe_slow );
11360 %} 10364 %}
11361 10365
11362 // Replicate scalar to packed byte (1 byte) values in xmm 10366 // Replicate scalar to packed byte (1 byte) values in xmm
11363 instruct Repl8B_reg(regD dst, regD src) %{ 10367 instruct Repl8B_reg(regD dst, regD src) %{
11364 match(Set dst (Replicate8B src)); 10368 match(Set dst (Replicate8B src));
11365 format %{ "MOVDQA $dst,$src\n\t" 10369 format %{ "MOVDQA $dst,$src\n\t"
11366 "PUNPCKLBW $dst,$dst\n\t" 10370 "PUNPCKLBW $dst,$dst\n\t"
11367 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10371 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11368 ins_encode( pshufd_8x8(dst, src)); 10372 ins_encode %{
10373 if ($dst$$reg != $src$$reg) {
10374 __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
10375 }
10376 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10377 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10378 %}
11369 ins_pipe( pipe_slow ); 10379 ins_pipe( pipe_slow );
11370 %} 10380 %}
11371 10381
11372 // Replicate scalar to packed byte (1 byte) values in xmm 10382 // Replicate scalar to packed byte (1 byte) values in xmm
11373 instruct Repl8B_rRegI(regD dst, rRegI src) %{ 10383 instruct Repl8B_rRegI(regD dst, rRegI src) %{
11374 match(Set dst (Replicate8B src)); 10384 match(Set dst (Replicate8B src));
11375 format %{ "MOVD $dst,$src\n\t" 10385 format %{ "MOVD $dst,$src\n\t"
11376 "PUNPCKLBW $dst,$dst\n\t" 10386 "PUNPCKLBW $dst,$dst\n\t"
11377 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10387 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11378 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst)); 10388 ins_encode %{
10389 __ movdl($dst$$XMMRegister, $src$$Register);
10390 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10391 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10392 %}
11379 ins_pipe( pipe_slow ); 10393 ins_pipe( pipe_slow );
11380 %} 10394 %}
11381 10395
11382 // Replicate scalar zero to packed byte (1 byte) values in xmm 10396 // Replicate scalar zero to packed byte (1 byte) values in xmm
11383 instruct Repl8B_immI0(regD dst, immI0 zero) %{ 10397 instruct Repl8B_immI0(regD dst, immI0 zero) %{
11384 match(Set dst (Replicate8B zero)); 10398 match(Set dst (Replicate8B zero));
11385 format %{ "PXOR $dst,$dst\t! replicate8B" %} 10399 format %{ "PXOR $dst,$dst\t! replicate8B" %}
11386 ins_encode( pxor(dst, dst)); 10400 ins_encode %{
10401 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10402 %}
11387 ins_pipe( fpu_reg_reg ); 10403 ins_pipe( fpu_reg_reg );
11388 %} 10404 %}
11389 10405
11390 // Replicate scalar to packed shore (2 byte) values in xmm 10406 // Replicate scalar to packed shore (2 byte) values in xmm
11391 instruct Repl4S_reg(regD dst, regD src) %{ 10407 instruct Repl4S_reg(regD dst, regD src) %{
11392 match(Set dst (Replicate4S src)); 10408 match(Set dst (Replicate4S src));
11393 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 10409 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
11394 ins_encode( pshufd_4x16(dst, src)); 10410 ins_encode %{
10411 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10412 %}
11395 ins_pipe( fpu_reg_reg ); 10413 ins_pipe( fpu_reg_reg );
11396 %} 10414 %}
11397 10415
11398 // Replicate scalar to packed shore (2 byte) values in xmm 10416 // Replicate scalar to packed shore (2 byte) values in xmm
11399 instruct Repl4S_rRegI(regD dst, rRegI src) %{ 10417 instruct Repl4S_rRegI(regD dst, rRegI src) %{
11400 match(Set dst (Replicate4S src)); 10418 match(Set dst (Replicate4S src));
11401 format %{ "MOVD $dst,$src\n\t" 10419 format %{ "MOVD $dst,$src\n\t"
11402 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 10420 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
11403 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 10421 ins_encode %{
10422 __ movdl($dst$$XMMRegister, $src$$Register);
10423 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10424 %}
11404 ins_pipe( fpu_reg_reg ); 10425 ins_pipe( fpu_reg_reg );
11405 %} 10426 %}
11406 10427
11407 // Replicate scalar zero to packed short (2 byte) values in xmm 10428 // Replicate scalar zero to packed short (2 byte) values in xmm
11408 instruct Repl4S_immI0(regD dst, immI0 zero) %{ 10429 instruct Repl4S_immI0(regD dst, immI0 zero) %{
11409 match(Set dst (Replicate4S zero)); 10430 match(Set dst (Replicate4S zero));
11410 format %{ "PXOR $dst,$dst\t! replicate4S" %} 10431 format %{ "PXOR $dst,$dst\t! replicate4S" %}
11411 ins_encode( pxor(dst, dst)); 10432 ins_encode %{
10433 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10434 %}
11412 ins_pipe( fpu_reg_reg ); 10435 ins_pipe( fpu_reg_reg );
11413 %} 10436 %}
11414 10437
11415 // Replicate scalar to packed char (2 byte) values in xmm 10438 // Replicate scalar to packed char (2 byte) values in xmm
11416 instruct Repl4C_reg(regD dst, regD src) %{ 10439 instruct Repl4C_reg(regD dst, regD src) %{
11417 match(Set dst (Replicate4C src)); 10440 match(Set dst (Replicate4C src));
11418 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 10441 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
11419 ins_encode( pshufd_4x16(dst, src)); 10442 ins_encode %{
10443 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10444 %}
11420 ins_pipe( fpu_reg_reg ); 10445 ins_pipe( fpu_reg_reg );
11421 %} 10446 %}
11422 10447
11423 // Replicate scalar to packed char (2 byte) values in xmm 10448 // Replicate scalar to packed char (2 byte) values in xmm
11424 instruct Repl4C_rRegI(regD dst, rRegI src) %{ 10449 instruct Repl4C_rRegI(regD dst, rRegI src) %{
11425 match(Set dst (Replicate4C src)); 10450 match(Set dst (Replicate4C src));
11426 format %{ "MOVD $dst,$src\n\t" 10451 format %{ "MOVD $dst,$src\n\t"
11427 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 10452 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
11428 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 10453 ins_encode %{
10454 __ movdl($dst$$XMMRegister, $src$$Register);
10455 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10456 %}
11429 ins_pipe( fpu_reg_reg ); 10457 ins_pipe( fpu_reg_reg );
11430 %} 10458 %}
11431 10459
11432 // Replicate scalar zero to packed char (2 byte) values in xmm 10460 // Replicate scalar zero to packed char (2 byte) values in xmm
11433 instruct Repl4C_immI0(regD dst, immI0 zero) %{ 10461 instruct Repl4C_immI0(regD dst, immI0 zero) %{
11434 match(Set dst (Replicate4C zero)); 10462 match(Set dst (Replicate4C zero));
11435 format %{ "PXOR $dst,$dst\t! replicate4C" %} 10463 format %{ "PXOR $dst,$dst\t! replicate4C" %}
11436 ins_encode( pxor(dst, dst)); 10464 ins_encode %{
10465 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10466 %}
11437 ins_pipe( fpu_reg_reg ); 10467 ins_pipe( fpu_reg_reg );
11438 %} 10468 %}
11439 10469
11440 // Replicate scalar to packed integer (4 byte) values in xmm 10470 // Replicate scalar to packed integer (4 byte) values in xmm
11441 instruct Repl2I_reg(regD dst, regD src) %{ 10471 instruct Repl2I_reg(regD dst, regD src) %{
11442 match(Set dst (Replicate2I src)); 10472 match(Set dst (Replicate2I src));
11443 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 10473 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
11444 ins_encode( pshufd(dst, src, 0x00)); 10474 ins_encode %{
10475 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10476 %}
11445 ins_pipe( fpu_reg_reg ); 10477 ins_pipe( fpu_reg_reg );
11446 %} 10478 %}
11447 10479
11448 // Replicate scalar to packed integer (4 byte) values in xmm 10480 // Replicate scalar to packed integer (4 byte) values in xmm
11449 instruct Repl2I_rRegI(regD dst, rRegI src) %{ 10481 instruct Repl2I_rRegI(regD dst, rRegI src) %{
11450 match(Set dst (Replicate2I src)); 10482 match(Set dst (Replicate2I src));
11451 format %{ "MOVD $dst,$src\n\t" 10483 format %{ "MOVD $dst,$src\n\t"
11452 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 10484 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
11453 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00)); 10485 ins_encode %{
10486 __ movdl($dst$$XMMRegister, $src$$Register);
10487 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10488 %}
11454 ins_pipe( fpu_reg_reg ); 10489 ins_pipe( fpu_reg_reg );
11455 %} 10490 %}
11456 10491
11457 // Replicate scalar zero to packed integer (2 byte) values in xmm 10492 // Replicate scalar zero to packed integer (2 byte) values in xmm
11458 instruct Repl2I_immI0(regD dst, immI0 zero) %{ 10493 instruct Repl2I_immI0(regD dst, immI0 zero) %{
11459 match(Set dst (Replicate2I zero)); 10494 match(Set dst (Replicate2I zero));
11460 format %{ "PXOR $dst,$dst\t! replicate2I" %} 10495 format %{ "PXOR $dst,$dst\t! replicate2I" %}
11461 ins_encode( pxor(dst, dst)); 10496 ins_encode %{
10497 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10498 %}
11462 ins_pipe( fpu_reg_reg ); 10499 ins_pipe( fpu_reg_reg );
11463 %} 10500 %}
11464 10501
11465 // Replicate scalar to packed single precision floating point values in xmm 10502 // Replicate scalar to packed single precision floating point values in xmm
11466 instruct Repl2F_reg(regD dst, regD src) %{ 10503 instruct Repl2F_reg(regD dst, regD src) %{
11467 match(Set dst (Replicate2F src)); 10504 match(Set dst (Replicate2F src));
11468 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10505 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11469 ins_encode( pshufd(dst, src, 0xe0)); 10506 ins_encode %{
10507 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
10508 %}
11470 ins_pipe( fpu_reg_reg ); 10509 ins_pipe( fpu_reg_reg );
11471 %} 10510 %}
11472 10511
11473 // Replicate scalar to packed single precision floating point values in xmm 10512 // Replicate scalar to packed single precision floating point values in xmm
11474 instruct Repl2F_regF(regD dst, regF src) %{ 10513 instruct Repl2F_regF(regD dst, regF src) %{
11475 match(Set dst (Replicate2F src)); 10514 match(Set dst (Replicate2F src));
11476 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10515 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11477 ins_encode( pshufd(dst, src, 0xe0)); 10516 ins_encode %{
10517 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
10518 %}
11478 ins_pipe( fpu_reg_reg ); 10519 ins_pipe( fpu_reg_reg );
11479 %} 10520 %}
11480 10521
11481 // Replicate scalar to packed single precision floating point values in xmm 10522 // Replicate scalar to packed single precision floating point values in xmm
11482 instruct Repl2F_immF0(regD dst, immF0 zero) %{ 10523 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11483 match(Set dst (Replicate2F zero)); 10524 match(Set dst (Replicate2F zero));
11484 format %{ "PXOR $dst,$dst\t! replicate2F" %} 10525 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11485 ins_encode( pxor(dst, dst)); 10526 ins_encode %{
10527 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10528 %}
11486 ins_pipe( fpu_reg_reg ); 10529 ins_pipe( fpu_reg_reg );
11487 %} 10530 %}
11488 10531
11489 10532
11490 // ======================================================================= 10533 // =======================================================================
12160 %{ 11203 %{
12161 match(Set result (PartialSubtypeCheck sub super)); 11204 match(Set result (PartialSubtypeCheck sub super));
12162 effect(KILL rcx, KILL cr); 11205 effect(KILL rcx, KILL cr);
12163 11206
12164 ins_cost(1100); // slightly larger than the next version 11207 ins_cost(1100); // slightly larger than the next version
12165 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 11208 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12166 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11209 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12167 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11210 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12168 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11211 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12169 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11212 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12170 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 11213 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12171 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11214 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12172 "miss:\t" %} 11215 "miss:\t" %}
12173 11216
12174 opcode(0x1); // Force a XOR of RDI 11217 opcode(0x1); // Force a XOR of RDI
12175 ins_encode(enc_PartialSubtypeCheck()); 11218 ins_encode(enc_PartialSubtypeCheck());
12183 %{ 11226 %{
12184 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11227 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12185 effect(KILL rcx, KILL result); 11228 effect(KILL rcx, KILL result);
12186 11229
12187 ins_cost(1000); 11230 ins_cost(1000);
12188 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 11231 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12189 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11232 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12190 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11233 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12191 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11234 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12192 "jne,s miss\t\t# Missed: flags nz\n\t" 11235 "jne,s miss\t\t# Missed: flags nz\n\t"
12193 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 11236 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12194 "miss:\t" %} 11237 "miss:\t" %}
12195 11238
12196 opcode(0x0); // No need to XOR RDI 11239 opcode(0x0); // No need to XOR RDI
12197 ins_encode(enc_PartialSubtypeCheck()); 11240 ins_encode(enc_PartialSubtypeCheck());
12198 ins_pipe(pipe_slow); 11241 ins_pipe(pipe_slow);
12356 11399
12357 // ============================================================================ 11400 // ============================================================================
12358 // inlined locking and unlocking 11401 // inlined locking and unlocking
12359 11402
12360 instruct cmpFastLock(rFlagsReg cr, 11403 instruct cmpFastLock(rFlagsReg cr,
12361 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 11404 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
12362 %{ 11405 %{
12363 match(Set cr (FastLock object box)); 11406 match(Set cr (FastLock object box));
12364 effect(TEMP tmp, TEMP scr); 11407 effect(TEMP tmp, TEMP scr, USE_KILL box);
12365 11408
12366 ins_cost(300); 11409 ins_cost(300);
12367 format %{ "fastlock $object,$box,$tmp,$scr" %} 11410 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
12368 ins_encode(Fast_Lock(object, box, tmp, scr)); 11411 ins_encode(Fast_Lock(object, box, tmp, scr));
12369 ins_pipe(pipe_slow); 11412 ins_pipe(pipe_slow);
12370 %} 11413 %}
12371 11414
12372 instruct cmpFastUnlock(rFlagsReg cr, 11415 instruct cmpFastUnlock(rFlagsReg cr,
12373 rRegP object, rax_RegP box, rRegP tmp) 11416 rRegP object, rax_RegP box, rRegP tmp)
12374 %{ 11417 %{
12375 match(Set cr (FastUnlock object box)); 11418 match(Set cr (FastUnlock object box));
12376 effect(TEMP tmp); 11419 effect(TEMP tmp, USE_KILL box);
12377 11420
12378 ins_cost(300); 11421 ins_cost(300);
12379 format %{ "fastunlock $object, $box, $tmp" %} 11422 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
12380 ins_encode(Fast_Unlock(object, box, tmp)); 11423 ins_encode(Fast_Unlock(object, box, tmp));
12381 ins_pipe(pipe_slow); 11424 ins_pipe(pipe_slow);
12382 %} 11425 %}
12383 11426
12384 11427
12578 11621
12579 // use the following format syntax 11622 // use the following format syntax
12580 format %{ "jmp rethrow_stub" %} 11623 format %{ "jmp rethrow_stub" %}
12581 ins_encode(enc_rethrow); 11624 ins_encode(enc_rethrow);
12582 ins_pipe(pipe_jmp); 11625 ins_pipe(pipe_jmp);
11626 %}
11627
11628
11629 // ============================================================================
11630 // This name is KNOWN by the ADLC and cannot be changed.
11631 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11632 // for this guy.
11633 instruct tlsLoadP(r15_RegP dst) %{
11634 match(Set dst (ThreadLocal));
11635 effect(DEF dst);
11636
11637 size(0);
11638 format %{ "# TLS is in R15" %}
11639 ins_encode( /*empty encoding*/ );
11640 ins_pipe(ialu_reg_reg);
12583 %} 11641 %}
12584 11642
12585 11643
12586 //----------PEEPHOLE RULES----------------------------------------------------- 11644 //----------PEEPHOLE RULES-----------------------------------------------------
12587 // These must follow all instruction definitions as they use the names 11645 // These must follow all instruction definitions as they use the names