Mercurial > hg > truffle
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 |