comparison src/cpu/x86/vm/x86_64.ad @ 2008:2f644f85485d

6961690: load oops from constant table on SPARC Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence. Reviewed-by: never, kvn
author twisti
date Fri, 03 Dec 2010 01:34:31 -0800
parents ae065c367d93
children 6bbaedb03534
comparison
equal deleted inserted replaced
2007:5ddfcf4b079e 2008:2f644f85485d
828 MacroAssembler _masm(&cbuf); 828 MacroAssembler _masm(&cbuf);
829 829
830 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); 830 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
831 } 831 }
832 } 832 }
833
834
835 //=============================================================================
836 const bool Matcher::constant_table_absolute_addressing = true;
837 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
838
839 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
840 // Empty encoding
841 }
842
843 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
844 return 0;
845 }
846
847 #ifndef PRODUCT
848 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
849 st->print("# MachConstantBaseNode (empty encoding)");
850 }
851 #endif
833 852
834 853
835 //============================================================================= 854 //=============================================================================
836 #ifndef PRODUCT 855 #ifndef PRODUCT
837 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 856 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1920 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1939 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1921 __ end_a_stub(); 1940 __ end_a_stub();
1922 return offset; 1941 return offset;
1923 } 1942 }
1924 1943
1925 static void emit_double_constant(CodeBuffer& cbuf, double x) {
1926 int mark = cbuf.insts()->mark_off();
1927 MacroAssembler _masm(&cbuf);
1928 address double_address = __ double_constant(x);
1929 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1930 emit_d32_reloc(cbuf,
1931 (int) (double_address - cbuf.insts_end() - 4),
1932 internal_word_Relocation::spec(double_address),
1933 RELOC_DISP32);
1934 }
1935
1936 static void emit_float_constant(CodeBuffer& cbuf, float x) {
1937 int mark = cbuf.insts()->mark_off();
1938 MacroAssembler _masm(&cbuf);
1939 address float_address = __ float_constant(x);
1940 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1941 emit_d32_reloc(cbuf,
1942 (int) (float_address - cbuf.insts_end() - 4),
1943 internal_word_Relocation::spec(float_address),
1944 RELOC_DISP32);
1945 }
1946
1947 1944
1948 const bool Matcher::match_rule_supported(int opcode) { 1945 const bool Matcher::match_rule_supported(int opcode) {
1949 if (!has_match_rule(opcode)) 1946 if (!has_match_rule(opcode))
1950 return false; 1947 return false;
1951 1948
2787 } else { 2784 } else {
2788 emit_d64(cbuf, $src$$constant); 2785 emit_d64(cbuf, $src$$constant);
2789 } 2786 }
2790 %} 2787 %}
2791 2788
2792 enc_class load_immF(regF dst, immF con)
2793 %{
2794 // XXX reg_mem doesn't support RIP-relative addressing yet
2795 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2796 emit_float_constant(cbuf, $con$$constant);
2797 %}
2798
2799 enc_class load_immD(regD dst, immD con)
2800 %{
2801 // XXX reg_mem doesn't support RIP-relative addressing yet
2802 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2803 emit_double_constant(cbuf, $con$$constant);
2804 %}
2805
2806 enc_class load_conF (regF dst, immF con) %{ // Load float constant
2807 emit_opcode(cbuf, 0xF3);
2808 if ($dst$$reg >= 8) {
2809 emit_opcode(cbuf, Assembler::REX_R);
2810 }
2811 emit_opcode(cbuf, 0x0F);
2812 emit_opcode(cbuf, 0x10);
2813 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2814 emit_float_constant(cbuf, $con$$constant);
2815 %}
2816
2817 enc_class load_conD (regD dst, immD con) %{ // Load double constant
2818 // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
2819 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
2820 if ($dst$$reg >= 8) {
2821 emit_opcode(cbuf, Assembler::REX_R);
2822 }
2823 emit_opcode(cbuf, 0x0F);
2824 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
2825 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2826 emit_double_constant(cbuf, $con$$constant);
2827 %}
2828
2829 // Encode a reg-reg copy. If it is useless, then empty encoding. 2789 // Encode a reg-reg copy. If it is useless, then empty encoding.
2830 enc_class enc_copy(rRegI dst, rRegI src) 2790 enc_class enc_copy(rRegI dst, rRegI src)
2831 %{ 2791 %{
2832 encode_copy(cbuf, $dst$$reg, $src$$reg); 2792 encode_copy(cbuf, $dst$$reg, $src$$reg);
2833 %} 2793 %}
2922 2882
2923 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2883 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2924 // Output immediate memory reference 2884 // Output immediate memory reference
2925 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2885 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2926 emit_d32(cbuf, 0x00); 2886 emit_d32(cbuf, 0x00);
2927 %}
2928
2929 enc_class jump_enc(rRegL switch_val, rRegI dest) %{
2930 MacroAssembler masm(&cbuf);
2931
2932 Register switch_reg = as_Register($switch_val$$reg);
2933 Register dest_reg = as_Register($dest$$reg);
2934 address table_base = masm.address_table_constant(_index2label);
2935
2936 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2937 // to do that and the compiler is using that register as one it can allocate.
2938 // So we build it all by hand.
2939 // Address index(noreg, switch_reg, Address::times_1);
2940 // ArrayAddress dispatch(table, index);
2941
2942 Address dispatch(dest_reg, switch_reg, Address::times_1);
2943
2944 masm.lea(dest_reg, InternalAddress(table_base));
2945 masm.jmp(dispatch);
2946 %}
2947
2948 enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
2949 MacroAssembler masm(&cbuf);
2950
2951 Register switch_reg = as_Register($switch_val$$reg);
2952 Register dest_reg = as_Register($dest$$reg);
2953 address table_base = masm.address_table_constant(_index2label);
2954
2955 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2956 // to do that and the compiler is using that register as one it can allocate.
2957 // So we build it all by hand.
2958 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2959 // ArrayAddress dispatch(table, index);
2960
2961 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2962
2963 masm.lea(dest_reg, InternalAddress(table_base));
2964 masm.jmp(dispatch);
2965 %}
2966
2967 enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
2968 MacroAssembler masm(&cbuf);
2969
2970 Register switch_reg = as_Register($switch_val$$reg);
2971 Register dest_reg = as_Register($dest$$reg);
2972 address table_base = masm.address_table_constant(_index2label);
2973
2974 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2975 // to do that and the compiler is using that register as one it can allocate.
2976 // So we build it all by hand.
2977 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2978 // ArrayAddress dispatch(table, index);
2979
2980 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2981 masm.lea(dest_reg, InternalAddress(table_base));
2982 masm.jmp(dispatch);
2983
2984 %} 2887 %}
2985 2888
2986 enc_class lock_prefix() 2889 enc_class lock_prefix()
2987 %{ 2890 %{
2988 if (os::is_MP()) { 2891 if (os::is_MP()) {
6639 format %{ "movq $dst, $src\t# long (32-bit)" %} 6542 format %{ "movq $dst, $src\t# long (32-bit)" %}
6640 ins_encode(load_immL32(dst, src)); 6543 ins_encode(load_immL32(dst, src));
6641 ins_pipe(ialu_reg); 6544 ins_pipe(ialu_reg);
6642 %} 6545 %}
6643 6546
6644 instruct loadConP(rRegP dst, immP src) 6547 instruct loadConP(rRegP dst, immP con) %{
6645 %{ 6548 match(Set dst con);
6646 match(Set dst src); 6549
6647 6550 format %{ "movq $dst, $con\t# ptr" %}
6648 format %{ "movq $dst, $src\t# ptr" %} 6551 ins_encode(load_immP(dst, con));
6649 ins_encode(load_immP(dst, src));
6650 ins_pipe(ialu_reg_fat); // XXX 6552 ins_pipe(ialu_reg_fat); // XXX
6651 %} 6553 %}
6652 6554
6653 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 6555 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
6654 %{ 6556 %{
6671 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 6573 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
6672 ins_encode(load_immP31(dst, src)); 6574 ins_encode(load_immP31(dst, src));
6673 ins_pipe(ialu_reg); 6575 ins_pipe(ialu_reg);
6674 %} 6576 %}
6675 6577
6676 instruct loadConF(regF dst, immF src) 6578 instruct loadConF(regF dst, immF con) %{
6677 %{ 6579 match(Set dst con);
6678 match(Set dst src);
6679 ins_cost(125); 6580 ins_cost(125);
6680 6581 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
6681 format %{ "movss $dst, [$src]" %} 6582 ins_encode %{
6682 ins_encode(load_conF(dst, src)); 6583 __ movflt($dst$$XMMRegister, $constantaddress($con));
6584 %}
6683 ins_pipe(pipe_slow); 6585 ins_pipe(pipe_slow);
6684 %} 6586 %}
6685 6587
6686 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6588 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6687 match(Set dst src); 6589 match(Set dst src);
6719 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 6621 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6720 ins_pipe(pipe_slow); 6622 ins_pipe(pipe_slow);
6721 %} 6623 %}
6722 6624
6723 // Use the same format since predicate() can not be used here. 6625 // Use the same format since predicate() can not be used here.
6724 instruct loadConD(regD dst, immD src) 6626 instruct loadConD(regD dst, immD con) %{
6725 %{ 6627 match(Set dst con);
6726 match(Set dst src);
6727 ins_cost(125); 6628 ins_cost(125);
6728 6629 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
6729 format %{ "movsd $dst, [$src]" %} 6630 ins_encode %{
6730 ins_encode(load_conD(dst, src)); 6631 __ movdbl($dst$$XMMRegister, $constantaddress($con));
6632 %}
6731 ins_pipe(pipe_slow); 6633 ins_pipe(pipe_slow);
6732 %} 6634 %}
6733 6635
6734 instruct loadConD0(regD dst, immD0 src) 6636 instruct loadConD0(regD dst, immD0 src)
6735 %{ 6637 %{
7692 match(Jump (LShiftL switch_val shift)); 7594 match(Jump (LShiftL switch_val shift));
7693 ins_cost(350); 7595 ins_cost(350);
7694 predicate(false); 7596 predicate(false);
7695 effect(TEMP dest); 7597 effect(TEMP dest);
7696 7598
7697 format %{ "leaq $dest, table_base\n\t" 7599 format %{ "leaq $dest, [$constantaddress]\n\t"
7698 "jmp [$dest + $switch_val << $shift]\n\t" %} 7600 "jmp [$dest + $switch_val << $shift]\n\t" %}
7699 ins_encode(jump_enc_offset(switch_val, shift, dest)); 7601 ins_encode %{
7602 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7603 // to do that and the compiler is using that register as one it can allocate.
7604 // So we build it all by hand.
7605 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
7606 // ArrayAddress dispatch(table, index);
7607 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
7608 __ lea($dest$$Register, $constantaddress);
7609 __ jmp(dispatch);
7610 %}
7700 ins_pipe(pipe_jmp); 7611 ins_pipe(pipe_jmp);
7701 ins_pc_relative(1); 7612 ins_pc_relative(1);
7702 %} 7613 %}
7703 7614
7704 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7615 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
7705 match(Jump (AddL (LShiftL switch_val shift) offset)); 7616 match(Jump (AddL (LShiftL switch_val shift) offset));
7706 ins_cost(350); 7617 ins_cost(350);
7707 effect(TEMP dest); 7618 effect(TEMP dest);
7708 7619
7709 format %{ "leaq $dest, table_base\n\t" 7620 format %{ "leaq $dest, [$constantaddress]\n\t"
7710 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7621 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
7711 ins_encode(jump_enc_addr(switch_val, shift, offset, dest)); 7622 ins_encode %{
7623 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7624 // to do that and the compiler is using that register as one it can allocate.
7625 // So we build it all by hand.
7626 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7627 // ArrayAddress dispatch(table, index);
7628 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7629 __ lea($dest$$Register, $constantaddress);
7630 __ jmp(dispatch);
7631 %}
7712 ins_pipe(pipe_jmp); 7632 ins_pipe(pipe_jmp);
7713 ins_pc_relative(1); 7633 ins_pc_relative(1);
7714 %} 7634 %}
7715 7635
7716 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7636 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
7717 match(Jump switch_val); 7637 match(Jump switch_val);
7718 ins_cost(350); 7638 ins_cost(350);
7719 effect(TEMP dest); 7639 effect(TEMP dest);
7720 7640
7721 format %{ "leaq $dest, table_base\n\t" 7641 format %{ "leaq $dest, [$constantaddress]\n\t"
7722 "jmp [$dest + $switch_val]\n\t" %} 7642 "jmp [$dest + $switch_val]\n\t" %}
7723 ins_encode(jump_enc(switch_val, dest)); 7643 ins_encode %{
7644 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7645 // to do that and the compiler is using that register as one it can allocate.
7646 // So we build it all by hand.
7647 // Address index(noreg, switch_reg, Address::times_1);
7648 // ArrayAddress dispatch(table, index);
7649 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
7650 __ lea($dest$$Register, $constantaddress);
7651 __ jmp(dispatch);
7652 %}
7724 ins_pipe(pipe_jmp); 7653 ins_pipe(pipe_jmp);
7725 ins_pc_relative(1); 7654 ins_pc_relative(1);
7726 %} 7655 %}
7727 7656
7728 // Conditional move 7657 // Conditional move
10374 opcode(0x0F, 0x2E); 10303 opcode(0x0F, 0x2E);
10375 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2)); 10304 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10376 ins_pipe(pipe_slow); 10305 ins_pipe(pipe_slow);
10377 %} 10306 %}
10378 10307
10379 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) 10308 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10380 %{ 10309 match(Set cr (CmpF src con));
10381 match(Set cr (CmpF src1 src2));
10382 10310
10383 ins_cost(145); 10311 ins_cost(145);
10384 format %{ "ucomiss $src1, $src2\n\t" 10312 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10385 "jnp,s exit\n\t" 10313 "jnp,s exit\n\t"
10386 "pushfq\t# saw NaN, set CF\n\t" 10314 "pushfq\t# saw NaN, set CF\n\t"
10387 "andq [rsp], #0xffffff2b\n\t" 10315 "andq [rsp], #0xffffff2b\n\t"
10388 "popfq\n" 10316 "popfq\n"
10389 "exit: nop\t# avoid branch to branch" %} 10317 "exit: nop\t# avoid branch to branch" %}
10390 opcode(0x0F, 0x2E); 10318 ins_encode %{
10391 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 10319 Label L_exit;
10392 cmpfp_fixup); 10320 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10321 __ jcc(Assembler::noParity, L_exit);
10322 __ pushf();
10323 __ andq(rsp, 0xffffff2b);
10324 __ popf();
10325 __ bind(L_exit);
10326 __ nop();
10327 %}
10393 ins_pipe(pipe_slow); 10328 ins_pipe(pipe_slow);
10394 %} 10329 %}
10395 10330
10396 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{ 10331 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10397 match(Set cr (CmpF src1 src2)); 10332 match(Set cr (CmpF src con));
10398
10399 ins_cost(100); 10333 ins_cost(100);
10400 format %{ "ucomiss $src1, $src2" %} 10334 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10401 opcode(0x0F, 0x2E); 10335 ins_encode %{
10402 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2)); 10336 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10337 %}
10403 ins_pipe(pipe_slow); 10338 ins_pipe(pipe_slow);
10404 %} 10339 %}
10405 10340
10406 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10341 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10407 %{ 10342 %{
10456 opcode(0x66, 0x0F, 0x2E); 10391 opcode(0x66, 0x0F, 0x2E);
10457 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2)); 10392 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10458 ins_pipe(pipe_slow); 10393 ins_pipe(pipe_slow);
10459 %} 10394 %}
10460 10395
10461 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) 10396 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10462 %{ 10397 match(Set cr (CmpD src con));
10463 match(Set cr (CmpD src1 src2));
10464 10398
10465 ins_cost(145); 10399 ins_cost(145);
10466 format %{ "ucomisd $src1, [$src2]\n\t" 10400 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10467 "jnp,s exit\n\t" 10401 "jnp,s exit\n\t"
10468 "pushfq\t# saw NaN, set CF\n\t" 10402 "pushfq\t# saw NaN, set CF\n\t"
10469 "andq [rsp], #0xffffff2b\n\t" 10403 "andq [rsp], #0xffffff2b\n\t"
10470 "popfq\n" 10404 "popfq\n"
10471 "exit: nop\t# avoid branch to branch" %} 10405 "exit: nop\t# avoid branch to branch" %}
10472 opcode(0x66, 0x0F, 0x2E); 10406 ins_encode %{
10473 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 10407 Label L_exit;
10474 cmpfp_fixup); 10408 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10409 __ jcc(Assembler::noParity, L_exit);
10410 __ pushf();
10411 __ andq(rsp, 0xffffff2b);
10412 __ popf();
10413 __ bind(L_exit);
10414 __ nop();
10415 %}
10475 ins_pipe(pipe_slow); 10416 ins_pipe(pipe_slow);
10476 %} 10417 %}
10477 10418
10478 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{ 10419 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10479 match(Set cr (CmpD src1 src2)); 10420 match(Set cr (CmpD src con));
10480
10481 ins_cost(100); 10421 ins_cost(100);
10482 format %{ "ucomisd $src1, [$src2]" %} 10422 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10483 opcode(0x66, 0x0F, 0x2E); 10423 ins_encode %{
10484 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2)); 10424 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10425 %}
10485 ins_pipe(pipe_slow); 10426 ins_pipe(pipe_slow);
10486 %} 10427 %}
10487 10428
10488 // Compare into -1,0,1 10429 // Compare into -1,0,1
10489 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10430 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10526 cmpfp3(dst)); 10467 cmpfp3(dst));
10527 ins_pipe(pipe_slow); 10468 ins_pipe(pipe_slow);
10528 %} 10469 %}
10529 10470
10530 // Compare into -1,0,1 10471 // Compare into -1,0,1
10531 instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr) 10472 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10532 %{ 10473 match(Set dst (CmpF3 src con));
10533 match(Set dst (CmpF3 src1 src2));
10534 effect(KILL cr); 10474 effect(KILL cr);
10535 10475
10536 ins_cost(275); 10476 ins_cost(275);
10537 format %{ "ucomiss $src1, [$src2]\n\t" 10477 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10538 "movl $dst, #-1\n\t" 10478 "movl $dst, #-1\n\t"
10539 "jp,s done\n\t" 10479 "jp,s done\n\t"
10540 "jb,s done\n\t" 10480 "jb,s done\n\t"
10541 "setne $dst\n\t" 10481 "setne $dst\n\t"
10542 "movzbl $dst, $dst\n" 10482 "movzbl $dst, $dst\n"
10543 "done:" %} 10483 "done:" %}
10544 10484 ins_encode %{
10545 opcode(0x0F, 0x2E); 10485 Label L_done;
10546 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 10486 Register Rdst = $dst$$Register;
10547 cmpfp3(dst)); 10487 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10488 __ movl(Rdst, -1);
10489 __ jcc(Assembler::parity, L_done);
10490 __ jcc(Assembler::below, L_done);
10491 __ setb(Assembler::notEqual, Rdst);
10492 __ movzbl(Rdst, Rdst);
10493 __ bind(L_done);
10494 %}
10548 ins_pipe(pipe_slow); 10495 ins_pipe(pipe_slow);
10549 %} 10496 %}
10550 10497
10551 // Compare into -1,0,1 10498 // Compare into -1,0,1
10552 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10499 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10589 cmpfp3(dst)); 10536 cmpfp3(dst));
10590 ins_pipe(pipe_slow); 10537 ins_pipe(pipe_slow);
10591 %} 10538 %}
10592 10539
10593 // Compare into -1,0,1 10540 // Compare into -1,0,1
10594 instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr) 10541 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10595 %{ 10542 match(Set dst (CmpD3 src con));
10596 match(Set dst (CmpD3 src1 src2));
10597 effect(KILL cr); 10543 effect(KILL cr);
10598 10544
10599 ins_cost(275); 10545 ins_cost(275);
10600 format %{ "ucomisd $src1, [$src2]\n\t" 10546 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10601 "movl $dst, #-1\n\t" 10547 "movl $dst, #-1\n\t"
10602 "jp,s done\n\t" 10548 "jp,s done\n\t"
10603 "jb,s done\n\t" 10549 "jb,s done\n\t"
10604 "setne $dst\n\t" 10550 "setne $dst\n\t"
10605 "movzbl $dst, $dst\n" 10551 "movzbl $dst, $dst\n"
10606 "done:" %} 10552 "done:" %}
10607 10553 ins_encode %{
10608 opcode(0x66, 0x0F, 0x2E); 10554 Register Rdst = $dst$$Register;
10609 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 10555 Label L_done;
10610 cmpfp3(dst)); 10556 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10557 __ movl(Rdst, -1);
10558 __ jcc(Assembler::parity, L_done);
10559 __ jcc(Assembler::below, L_done);
10560 __ setb(Assembler::notEqual, Rdst);
10561 __ movzbl(Rdst, Rdst);
10562 __ bind(L_done);
10563 %}
10611 ins_pipe(pipe_slow); 10564 ins_pipe(pipe_slow);
10612 %} 10565 %}
10613 10566
10614 instruct addF_reg(regF dst, regF src) 10567 instruct addF_reg(regF dst, regF src)
10615 %{ 10568 %{
10631 opcode(0xF3, 0x0F, 0x58); 10584 opcode(0xF3, 0x0F, 0x58);
10632 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10585 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10633 ins_pipe(pipe_slow); 10586 ins_pipe(pipe_slow);
10634 %} 10587 %}
10635 10588
10636 instruct addF_imm(regF dst, immF src) 10589 instruct addF_imm(regF dst, immF con) %{
10637 %{ 10590 match(Set dst (AddF dst con));
10638 match(Set dst (AddF dst src)); 10591 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10639
10640 format %{ "addss $dst, [$src]" %}
10641 ins_cost(150); // XXX 10592 ins_cost(150); // XXX
10642 opcode(0xF3, 0x0F, 0x58); 10593 ins_encode %{
10643 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10594 __ addss($dst$$XMMRegister, $constantaddress($con));
10595 %}
10644 ins_pipe(pipe_slow); 10596 ins_pipe(pipe_slow);
10645 %} 10597 %}
10646 10598
10647 instruct addD_reg(regD dst, regD src) 10599 instruct addD_reg(regD dst, regD src)
10648 %{ 10600 %{
10664 opcode(0xF2, 0x0F, 0x58); 10616 opcode(0xF2, 0x0F, 0x58);
10665 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10617 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10666 ins_pipe(pipe_slow); 10618 ins_pipe(pipe_slow);
10667 %} 10619 %}
10668 10620
10669 instruct addD_imm(regD dst, immD src) 10621 instruct addD_imm(regD dst, immD con) %{
10670 %{ 10622 match(Set dst (AddD dst con));
10671 match(Set dst (AddD dst src)); 10623 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10672
10673 format %{ "addsd $dst, [$src]" %}
10674 ins_cost(150); // XXX 10624 ins_cost(150); // XXX
10675 opcode(0xF2, 0x0F, 0x58); 10625 ins_encode %{
10676 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10626 __ addsd($dst$$XMMRegister, $constantaddress($con));
10627 %}
10677 ins_pipe(pipe_slow); 10628 ins_pipe(pipe_slow);
10678 %} 10629 %}
10679 10630
10680 instruct subF_reg(regF dst, regF src) 10631 instruct subF_reg(regF dst, regF src)
10681 %{ 10632 %{
10697 opcode(0xF3, 0x0F, 0x5C); 10648 opcode(0xF3, 0x0F, 0x5C);
10698 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10649 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10699 ins_pipe(pipe_slow); 10650 ins_pipe(pipe_slow);
10700 %} 10651 %}
10701 10652
10702 instruct subF_imm(regF dst, immF src) 10653 instruct subF_imm(regF dst, immF con) %{
10703 %{ 10654 match(Set dst (SubF dst con));
10704 match(Set dst (SubF dst src)); 10655 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10705
10706 format %{ "subss $dst, [$src]" %}
10707 ins_cost(150); // XXX 10656 ins_cost(150); // XXX
10708 opcode(0xF3, 0x0F, 0x5C); 10657 ins_encode %{
10709 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10658 __ subss($dst$$XMMRegister, $constantaddress($con));
10659 %}
10710 ins_pipe(pipe_slow); 10660 ins_pipe(pipe_slow);
10711 %} 10661 %}
10712 10662
10713 instruct subD_reg(regD dst, regD src) 10663 instruct subD_reg(regD dst, regD src)
10714 %{ 10664 %{
10730 opcode(0xF2, 0x0F, 0x5C); 10680 opcode(0xF2, 0x0F, 0x5C);
10731 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10681 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10732 ins_pipe(pipe_slow); 10682 ins_pipe(pipe_slow);
10733 %} 10683 %}
10734 10684
10735 instruct subD_imm(regD dst, immD src) 10685 instruct subD_imm(regD dst, immD con) %{
10736 %{ 10686 match(Set dst (SubD dst con));
10737 match(Set dst (SubD dst src)); 10687 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10738
10739 format %{ "subsd $dst, [$src]" %}
10740 ins_cost(150); // XXX 10688 ins_cost(150); // XXX
10741 opcode(0xF2, 0x0F, 0x5C); 10689 ins_encode %{
10742 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10690 __ subsd($dst$$XMMRegister, $constantaddress($con));
10691 %}
10743 ins_pipe(pipe_slow); 10692 ins_pipe(pipe_slow);
10744 %} 10693 %}
10745 10694
10746 instruct mulF_reg(regF dst, regF src) 10695 instruct mulF_reg(regF dst, regF src)
10747 %{ 10696 %{
10763 opcode(0xF3, 0x0F, 0x59); 10712 opcode(0xF3, 0x0F, 0x59);
10764 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10713 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10765 ins_pipe(pipe_slow); 10714 ins_pipe(pipe_slow);
10766 %} 10715 %}
10767 10716
10768 instruct mulF_imm(regF dst, immF src) 10717 instruct mulF_imm(regF dst, immF con) %{
10769 %{ 10718 match(Set dst (MulF dst con));
10770 match(Set dst (MulF dst src)); 10719 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10771
10772 format %{ "mulss $dst, [$src]" %}
10773 ins_cost(150); // XXX 10720 ins_cost(150); // XXX
10774 opcode(0xF3, 0x0F, 0x59); 10721 ins_encode %{
10775 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10722 __ mulss($dst$$XMMRegister, $constantaddress($con));
10723 %}
10776 ins_pipe(pipe_slow); 10724 ins_pipe(pipe_slow);
10777 %} 10725 %}
10778 10726
10779 instruct mulD_reg(regD dst, regD src) 10727 instruct mulD_reg(regD dst, regD src)
10780 %{ 10728 %{
10796 opcode(0xF2, 0x0F, 0x59); 10744 opcode(0xF2, 0x0F, 0x59);
10797 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10745 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10798 ins_pipe(pipe_slow); 10746 ins_pipe(pipe_slow);
10799 %} 10747 %}
10800 10748
10801 instruct mulD_imm(regD dst, immD src) 10749 instruct mulD_imm(regD dst, immD con) %{
10802 %{ 10750 match(Set dst (MulD dst con));
10803 match(Set dst (MulD dst src)); 10751 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10804
10805 format %{ "mulsd $dst, [$src]" %}
10806 ins_cost(150); // XXX 10752 ins_cost(150); // XXX
10807 opcode(0xF2, 0x0F, 0x59); 10753 ins_encode %{
10808 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10754 __ mulsd($dst$$XMMRegister, $constantaddress($con));
10755 %}
10809 ins_pipe(pipe_slow); 10756 ins_pipe(pipe_slow);
10810 %} 10757 %}
10811 10758
10812 instruct divF_reg(regF dst, regF src) 10759 instruct divF_reg(regF dst, regF src)
10813 %{ 10760 %{
10829 opcode(0xF3, 0x0F, 0x5E); 10776 opcode(0xF3, 0x0F, 0x5E);
10830 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10777 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10831 ins_pipe(pipe_slow); 10778 ins_pipe(pipe_slow);
10832 %} 10779 %}
10833 10780
10834 instruct divF_imm(regF dst, immF src) 10781 instruct divF_imm(regF dst, immF con) %{
10835 %{ 10782 match(Set dst (DivF dst con));
10836 match(Set dst (DivF dst src)); 10783 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10837
10838 format %{ "divss $dst, [$src]" %}
10839 ins_cost(150); // XXX 10784 ins_cost(150); // XXX
10840 opcode(0xF3, 0x0F, 0x5E); 10785 ins_encode %{
10841 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10786 __ divss($dst$$XMMRegister, $constantaddress($con));
10787 %}
10842 ins_pipe(pipe_slow); 10788 ins_pipe(pipe_slow);
10843 %} 10789 %}
10844 10790
10845 instruct divD_reg(regD dst, regD src) 10791 instruct divD_reg(regD dst, regD src)
10846 %{ 10792 %{
10862 opcode(0xF2, 0x0F, 0x5E); 10808 opcode(0xF2, 0x0F, 0x5E);
10863 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10809 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10864 ins_pipe(pipe_slow); 10810 ins_pipe(pipe_slow);
10865 %} 10811 %}
10866 10812
10867 instruct divD_imm(regD dst, immD src) 10813 instruct divD_imm(regD dst, immD con) %{
10868 %{ 10814 match(Set dst (DivD dst con));
10869 match(Set dst (DivD dst src)); 10815 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10870
10871 format %{ "divsd $dst, [$src]" %}
10872 ins_cost(150); // XXX 10816 ins_cost(150); // XXX
10873 opcode(0xF2, 0x0F, 0x5E); 10817 ins_encode %{
10874 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10818 __ divsd($dst$$XMMRegister, $constantaddress($con));
10819 %}
10875 ins_pipe(pipe_slow); 10820 ins_pipe(pipe_slow);
10876 %} 10821 %}
10877 10822
10878 instruct sqrtF_reg(regF dst, regF src) 10823 instruct sqrtF_reg(regF dst, regF src)
10879 %{ 10824 %{
10895 opcode(0xF3, 0x0F, 0x51); 10840 opcode(0xF3, 0x0F, 0x51);
10896 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10841 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10897 ins_pipe(pipe_slow); 10842 ins_pipe(pipe_slow);
10898 %} 10843 %}
10899 10844
10900 instruct sqrtF_imm(regF dst, immF src) 10845 instruct sqrtF_imm(regF dst, immF con) %{
10901 %{ 10846 match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
10902 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10847 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10903
10904 format %{ "sqrtss $dst, [$src]" %}
10905 ins_cost(150); // XXX 10848 ins_cost(150); // XXX
10906 opcode(0xF3, 0x0F, 0x51); 10849 ins_encode %{
10907 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10850 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
10851 %}
10908 ins_pipe(pipe_slow); 10852 ins_pipe(pipe_slow);
10909 %} 10853 %}
10910 10854
10911 instruct sqrtD_reg(regD dst, regD src) 10855 instruct sqrtD_reg(regD dst, regD src)
10912 %{ 10856 %{
10928 opcode(0xF2, 0x0F, 0x51); 10872 opcode(0xF2, 0x0F, 0x51);
10929 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10873 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10930 ins_pipe(pipe_slow); 10874 ins_pipe(pipe_slow);
10931 %} 10875 %}
10932 10876
10933 instruct sqrtD_imm(regD dst, immD src) 10877 instruct sqrtD_imm(regD dst, immD con) %{
10934 %{ 10878 match(Set dst (SqrtD con));
10935 match(Set dst (SqrtD src)); 10879 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10936
10937 format %{ "sqrtsd $dst, [$src]" %}
10938 ins_cost(150); // XXX 10880 ins_cost(150); // XXX
10939 opcode(0xF2, 0x0F, 0x51); 10881 ins_encode %{
10940 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10882 __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
10883 %}
10941 ins_pipe(pipe_slow); 10884 ins_pipe(pipe_slow);
10942 %} 10885 %}
10943 10886
10944 instruct absF_reg(regF dst) 10887 instruct absF_reg(regF dst)
10945 %{ 10888 %{