3062 Label done; 3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3064 __ li($dst$$Register, $zero$$constant); 3065 __ beq($crx$$CondRegister, done); 3066 __ li($dst$$Register, $notzero$$constant); 3067 __ bind(done); 3068 %} 3069 3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3071 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3072 3073 MacroAssembler _masm(&cbuf); 3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3075 Label done; 3076 __ bso($crx$$CondRegister, done); 3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3078 // TODO PPC port __ endgroup_if_needed(_size == 12); 3079 __ bind(done); 3080 %} 3081 3082 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3083 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3084 3085 MacroAssembler _masm(&cbuf); 3086 Label d; // dummy 3087 __ bind(d); 3088 Label* p = ($lbl$$label); 3089 // `p' is `NULL' when this encoding class is used only to 3090 // determine the size of the encoded instruction. 3091 Label& l = (NULL == p)? d : *(p); 3092 int cc = $cmp$$cmpcode; 3093 int flags_reg = $crx$$reg; 3094 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3095 int bhint = Assembler::bhintNoHint; 3096 3097 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3098 if (_prob <= PROB_NEVER) { 3099 bhint = Assembler::bhintIsNotTaken; 3100 } else if (_prob >= PROB_ALWAYS) { 3101 bhint = Assembler::bhintIsTaken; 10061 10062 format %{ "ANDC $dst, $src1, $src2" %} 10063 size(4); 10064 ins_encode %{ 10065 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10066 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10067 %} 10068 ins_pipe(pipe_class_default); 10069 %} 10070 10071 //----------Moves between int/long and float/double---------------------------- 10072 // 10073 // The following rules move values from int/long registers/stack-locations 10074 // to float/double registers/stack-locations and vice versa, without doing any 10075 // conversions. These rules are used to implement the bit-conversion methods 10076 // of java.lang.Float etc., e.g. 10077 // int floatToIntBits(float value) 10078 // float intBitsToFloat(int bits) 10079 // 10080 // Notes on the implementation on ppc64: 10081 // We only provide rules which move between a register and a stack-location, 10082 // because we always have to go through memory when moving between a float 10083 // register and an integer register. 10084 10085 //---------- Chain stack slots between similar types -------- 10086 10087 // These are needed so that the rules below can match. 10088 10089 // Load integer from stack slot 10090 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10091 match(Set dst src); 10092 ins_cost(MEMORY_REF_COST); 10093 10094 format %{ "LWZ $dst, $src" %} 10095 size(4); 10096 ins_encode( enc_lwz(dst, src) ); 10097 ins_pipe(pipe_class_memory); 10098 %} 10099 10100 // Store integer to stack slot 10101 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10102 match(Set dst src); 10103 ins_cost(MEMORY_REF_COST); 10566 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10567 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10568 %} 10569 ins_pipe(pipe_class_default); 10570 %} 10571 10572 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10573 // no match-rule, false predicate 10574 effect(DEF dst, USE crx, USE src); 10575 predicate(false); 10576 10577 ins_variable_size_depending_on_alignment(true); 10578 10579 format %{ "cmovI $crx, $dst, $src" %} 10580 // Worst case is branch + move + stop, no stop without scheduler. 10581 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10582 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10583 ins_pipe(pipe_class_default); 10584 %} 10585 10586 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10587 // no match-rule, false predicate 10588 effect(DEF dst, USE crx, USE mem); 10589 predicate(false); 10590 10591 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10592 postalloc_expand %{ 10593 // 10594 // replaces 10595 // 10596 // region dst crx mem 10597 // \ | | / 10598 // dst=cmovI_bso_stackSlotL_conLvalue0 10599 // 10600 // with 10601 // 10602 // region dst 10603 // \ / 10604 // dst=loadConI16(0) 10605 // | 10620 m2->add_prec(m1); 10621 10622 // operands for new nodes 10623 m1->_opnds[0] = op_dst; 10624 m1->_opnds[1] = new immI16Oper(0); 10625 10626 m2->_opnds[0] = op_dst; 10627 m2->_opnds[1] = op_crx; 10628 m2->_opnds[2] = op_mem; 10629 10630 // registers for new nodes 10631 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10632 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10633 10634 // Insert new nodes. 10635 nodes->push(m1); 10636 nodes->push(m2); 10637 %} 10638 %} 10639 10640 // Double to Int conversion, NaN is mapped to 0. 10641 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10642 match(Set dst (ConvD2I src)); 10643 ins_cost(DEFAULT_COST); 10644 10645 expand %{ 10646 regD tmpD; 10647 stackSlotL tmpS; 10648 flagsReg crx; 10649 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10650 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10651 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10652 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10653 %} 10654 %} 10655 10656 instruct convF2IRaw_regF(regF dst, regF src) %{ 10657 // no match-rule, false predicate 10658 effect(DEF dst, USE src); 10659 predicate(false); 10660 10661 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10662 size(4); 10663 ins_encode %{ 10664 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10665 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10666 %} 10667 ins_pipe(pipe_class_default); 10668 %} 10669 10670 // Float to Int conversion, NaN is mapped to 0. 10671 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10672 match(Set dst (ConvF2I src)); 10673 ins_cost(DEFAULT_COST); 10674 10675 expand %{ 10676 regF tmpF; 10677 stackSlotL tmpS; 10678 flagsReg crx; 10679 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10680 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10681 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10682 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10683 %} 10684 %} 10685 10686 // Convert to Long 10687 10688 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10689 match(Set dst (ConvI2L src)); 10690 format %{ "EXTSW $dst, $src \t// int->long" %} 10691 size(4); 10692 ins_encode %{ 10693 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10694 __ extsw($dst$$Register, $src$$Register); 10695 %} 10696 ins_pipe(pipe_class_default); 10697 %} 10698 10699 // Zero-extend: convert unsigned int to long (convUI2L). 10700 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10701 match(Set dst (AndL (ConvI2L src) mask)); 10702 ins_cost(DEFAULT_COST); 10703 10704 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10705 size(4); 10735 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10736 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10737 %} 10738 ins_pipe(pipe_class_default); 10739 %} 10740 10741 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10742 // no match-rule, false predicate 10743 effect(DEF dst, USE crx, USE src); 10744 predicate(false); 10745 10746 ins_variable_size_depending_on_alignment(true); 10747 10748 format %{ "cmovL $crx, $dst, $src" %} 10749 // Worst case is branch + move + stop, no stop without scheduler. 10750 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10751 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10752 ins_pipe(pipe_class_default); 10753 %} 10754 10755 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10756 // no match-rule, false predicate 10757 effect(DEF dst, USE crx, USE mem); 10758 predicate(false); 10759 10760 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10761 postalloc_expand %{ 10762 // 10763 // replaces 10764 // 10765 // region dst crx mem 10766 // \ | | / 10767 // dst=cmovL_bso_stackSlotL_conLvalue0 10768 // 10769 // with 10770 // 10771 // region dst 10772 // \ / 10773 // dst=loadConL16(0) 10774 // | 10786 m2->add_req(n_region, n_crx, n_mem); 10787 m2->add_prec(m1); 10788 10789 // operands for new nodes 10790 m1->_opnds[0] = op_dst; 10791 m1->_opnds[1] = new immL16Oper(0); 10792 m2->_opnds[0] = op_dst; 10793 m2->_opnds[1] = op_crx; 10794 m2->_opnds[2] = op_mem; 10795 10796 // registers for new nodes 10797 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10798 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10799 10800 // Insert new nodes. 10801 nodes->push(m1); 10802 nodes->push(m2); 10803 %} 10804 %} 10805 10806 // Float to Long conversion, NaN is mapped to 0. 10807 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10808 match(Set dst (ConvF2L src)); 10809 ins_cost(DEFAULT_COST); 10810 10811 expand %{ 10812 regF tmpF; 10813 stackSlotL tmpS; 10814 flagsReg crx; 10815 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10816 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10817 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10818 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10819 %} 10820 %} 10821 10822 instruct convD2LRaw_regD(regD dst, regD src) %{ 10823 // no match-rule, false predicate 10824 effect(DEF dst, USE src); 10825 predicate(false); 10826 10827 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10828 size(4); 10829 ins_encode %{ 10830 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10831 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10832 %} 10833 ins_pipe(pipe_class_default); 10834 %} 10835 10836 // Double to Long conversion, NaN is mapped to 0. 10837 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10838 match(Set dst (ConvD2L src)); 10839 ins_cost(DEFAULT_COST); 10840 10841 expand %{ 10842 regD tmpD; 10843 stackSlotL tmpS; 10844 flagsReg crx; 10845 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10846 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10847 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10848 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10849 %} 10850 %} 10851 10852 // Convert to Float 10853 10854 // Placed here as needed in expand. 10855 instruct convL2DRaw_regD(regD dst, regD src) %{ 10856 // no match-rule, false predicate 10857 effect(DEF dst, USE src); 10858 predicate(false); 10859 10860 format %{ "FCFID $dst, $src \t// convL2D" %} 10861 size(4); 10862 ins_encode %{ 10863 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10864 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10865 %} 10866 ins_pipe(pipe_class_default); 10867 %} 10868 10869 // Placed here as needed in expand. 10870 instruct convD2F_reg(regF dst, regD src) %{ 10871 match(Set dst (ConvD2F src)); 10897 %} 10898 %} 10899 10900 instruct convL2FRaw_regF(regF dst, regD src) %{ 10901 // no match-rule, false predicate 10902 effect(DEF dst, USE src); 10903 predicate(false); 10904 10905 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10906 size(4); 10907 ins_encode %{ 10908 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10909 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10910 %} 10911 ins_pipe(pipe_class_default); 10912 %} 10913 10914 // Integer to Float conversion. Special version for Power7. 10915 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10916 match(Set dst (ConvI2F src)); 10917 predicate(VM_Version::has_fcfids()); 10918 ins_cost(DEFAULT_COST); 10919 10920 expand %{ 10921 iRegLdst tmpL; 10922 stackSlotL tmpS; 10923 regD tmpD; 10924 convI2L_reg(tmpL, src); // Sign-extension int to long. 10925 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10926 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10927 convL2FRaw_regF(dst, tmpD); // Convert to float. 10928 %} 10929 %} 10930 10931 // L2F to avoid runtime call. 10932 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10933 match(Set dst (ConvL2F src)); 10934 predicate(VM_Version::has_fcfids()); 10935 ins_cost(DEFAULT_COST); 10936 10937 expand %{ 10938 stackSlotL tmpS; 10939 regD tmpD; 10940 regL_to_stkL(tmpS, src); // Store long to stack. 10941 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10942 convL2FRaw_regF(dst, tmpD); // Convert to float. 10943 %} 10944 %} 10945 10946 // Moved up as used in expand. 10947 //instruct convD2F_reg(regF dst, regD src) %{%} 10948 10949 // Convert to Double 10950 10951 // Integer to Double conversion. 10952 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10953 match(Set dst (ConvI2D src)); 10954 ins_cost(DEFAULT_COST); 10955 10956 expand %{ 10957 iRegLdst tmpL; 10958 stackSlotL tmpS; 10959 regD tmpD; 10960 convI2L_reg(tmpL, src); // Sign-extension int to long. 10961 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10962 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10963 convL2DRaw_regD(dst, tmpD); // Convert to double. 10964 %} 10965 %} 10966 10967 // Long to Double conversion 10968 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10969 match(Set dst (ConvL2D src)); 10970 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10971 10972 expand %{ 10973 regD tmpD; 10974 moveL2D_stack_reg(tmpD, src); 10975 convL2DRaw_regD(dst, tmpD); 10976 %} 10977 %} 10978 10979 instruct convF2D_reg(regD dst, regF src) %{ 10980 match(Set dst (ConvF2D src)); 10981 format %{ "FMR $dst, $src \t// float->double" %} 10982 // variable size, 0 or 4 10983 ins_encode %{ 10984 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10985 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10986 %} 10987 ins_pipe(pipe_class_default); 10988 %} 10989 10990 //----------Control Flow Instructions------------------------------------------ 10991 // Compare Instructions 10992 10993 // Compare Integers 10994 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10995 match(Set crx (CmpI src1 src2)); | 3062 Label done; 3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3064 __ li($dst$$Register, $zero$$constant); 3065 __ beq($crx$$CondRegister, done); 3066 __ li($dst$$Register, $notzero$$constant); 3067 __ bind(done); 3068 %} 3069 3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3071 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3072 3073 MacroAssembler _masm(&cbuf); 3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3075 Label done; 3076 __ bso($crx$$CondRegister, done); 3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3078 // TODO PPC port __ endgroup_if_needed(_size == 12); 3079 __ bind(done); 3080 %} 3081 3082 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3083 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3084 3085 MacroAssembler _masm(&cbuf); 3086 Label done; 3087 __ bso($crx$$CondRegister, done); 3088 __ mffprd($dst$$Register, $src$$FloatRegister); 3089 // TODO PPC port __ endgroup_if_needed(_size == 12); 3090 __ bind(done); 3091 %} 3092 3093 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3094 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3095 3096 MacroAssembler _masm(&cbuf); 3097 Label d; // dummy 3098 __ bind(d); 3099 Label* p = ($lbl$$label); 3100 // `p' is `NULL' when this encoding class is used only to 3101 // determine the size of the encoded instruction. 3102 Label& l = (NULL == p)? d : *(p); 3103 int cc = $cmp$$cmpcode; 3104 int flags_reg = $crx$$reg; 3105 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3106 int bhint = Assembler::bhintNoHint; 3107 3108 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3109 if (_prob <= PROB_NEVER) { 3110 bhint = Assembler::bhintIsNotTaken; 3111 } else if (_prob >= PROB_ALWAYS) { 3112 bhint = Assembler::bhintIsTaken; 10072 10073 format %{ "ANDC $dst, $src1, $src2" %} 10074 size(4); 10075 ins_encode %{ 10076 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10077 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10078 %} 10079 ins_pipe(pipe_class_default); 10080 %} 10081 10082 //----------Moves between int/long and float/double---------------------------- 10083 // 10084 // The following rules move values from int/long registers/stack-locations 10085 // to float/double registers/stack-locations and vice versa, without doing any 10086 // conversions. These rules are used to implement the bit-conversion methods 10087 // of java.lang.Float etc., e.g. 10088 // int floatToIntBits(float value) 10089 // float intBitsToFloat(int bits) 10090 // 10091 // Notes on the implementation on ppc64: 10092 // For Power7 and earlier, the rules are limited to those which move between a 10093 // register and a stack-location, because we always have to go through memory 10094 // when moving between a float register and an integer register. 10095 // This restriction is removed in Power8 with the introduction of the mtfprd 10096 // and mffprd instructions. 10097 10098 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10099 match(Set dst (MoveL2D src)); 10100 predicate(VM_Version::has_mtfprd()); 10101 10102 format %{ "MTFPRD $dst, $src" %} 10103 size(4); 10104 ins_encode %{ 10105 __ mtfprd($dst$$FloatRegister, $src$$Register); 10106 %} 10107 ins_pipe(pipe_class_default); 10108 %} 10109 10110 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10111 // no match-rule, false predicate 10112 effect(DEF dst, USE src); 10113 predicate(false); 10114 10115 format %{ "MTFPRWA $dst, $src" %} 10116 size(4); 10117 ins_encode %{ 10118 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10119 %} 10120 ins_pipe(pipe_class_default); 10121 %} 10122 10123 //---------- Chain stack slots between similar types -------- 10124 10125 // These are needed so that the rules below can match. 10126 10127 // Load integer from stack slot 10128 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10129 match(Set dst src); 10130 ins_cost(MEMORY_REF_COST); 10131 10132 format %{ "LWZ $dst, $src" %} 10133 size(4); 10134 ins_encode( enc_lwz(dst, src) ); 10135 ins_pipe(pipe_class_memory); 10136 %} 10137 10138 // Store integer to stack slot 10139 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10140 match(Set dst src); 10141 ins_cost(MEMORY_REF_COST); 10604 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10605 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10606 %} 10607 ins_pipe(pipe_class_default); 10608 %} 10609 10610 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10611 // no match-rule, false predicate 10612 effect(DEF dst, USE crx, USE src); 10613 predicate(false); 10614 10615 ins_variable_size_depending_on_alignment(true); 10616 10617 format %{ "cmovI $crx, $dst, $src" %} 10618 // Worst case is branch + move + stop, no stop without scheduler. 10619 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10620 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10621 ins_pipe(pipe_class_default); 10622 %} 10623 10624 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10625 // no match-rule, false predicate 10626 effect(DEF dst, USE crx, USE src); 10627 predicate(false); 10628 10629 ins_variable_size_depending_on_alignment(true); 10630 10631 format %{ "cmovI $crx, $dst, $src" %} 10632 // Worst case is branch + move + stop, no stop without scheduler. 10633 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10634 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10635 ins_pipe(pipe_class_default); 10636 %} 10637 10638 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10639 // no match-rule, false predicate 10640 effect(DEF dst, USE crx, USE mem); 10641 predicate(false); 10642 10643 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10644 postalloc_expand %{ 10645 // 10646 // replaces 10647 // 10648 // region dst crx mem 10649 // \ | | / 10650 // dst=cmovI_bso_stackSlotL_conLvalue0 10651 // 10652 // with 10653 // 10654 // region dst 10655 // \ / 10656 // dst=loadConI16(0) 10657 // | 10672 m2->add_prec(m1); 10673 10674 // operands for new nodes 10675 m1->_opnds[0] = op_dst; 10676 m1->_opnds[1] = new immI16Oper(0); 10677 10678 m2->_opnds[0] = op_dst; 10679 m2->_opnds[1] = op_crx; 10680 m2->_opnds[2] = op_mem; 10681 10682 // registers for new nodes 10683 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10684 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10685 10686 // Insert new nodes. 10687 nodes->push(m1); 10688 nodes->push(m2); 10689 %} 10690 %} 10691 10692 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10693 // no match-rule, false predicate 10694 effect(DEF dst, USE crx, USE src); 10695 predicate(false); 10696 10697 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 10698 postalloc_expand %{ 10699 // 10700 // replaces 10701 // 10702 // region dst crx src 10703 // \ | | / 10704 // dst=cmovI_bso_reg_conLvalue0 10705 // 10706 // with 10707 // 10708 // region dst 10709 // \ / 10710 // dst=loadConI16(0) 10711 // | 10712 // ^ region dst crx src 10713 // | \ | | / 10714 // dst=cmovI_bso_reg 10715 // 10716 10717 // Create new nodes. 10718 MachNode *m1 = new loadConI16Node(); 10719 MachNode *m2 = new cmovI_bso_regNode(); 10720 10721 // inputs for new nodes 10722 m1->add_req(n_region); 10723 m2->add_req(n_region, n_crx, n_src); 10724 10725 // precedences for new nodes 10726 m2->add_prec(m1); 10727 10728 // operands for new nodes 10729 m1->_opnds[0] = op_dst; 10730 m1->_opnds[1] = new immI16Oper(0); 10731 10732 m2->_opnds[0] = op_dst; 10733 m2->_opnds[1] = op_crx; 10734 m2->_opnds[2] = op_src; 10735 10736 // registers for new nodes 10737 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10738 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10739 10740 // Insert new nodes. 10741 nodes->push(m1); 10742 nodes->push(m2); 10743 %} 10744 %} 10745 10746 // Double to Int conversion, NaN is mapped to 0. 10747 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10748 match(Set dst (ConvD2I src)); 10749 predicate(!VM_Version::has_mtfprd()); 10750 ins_cost(DEFAULT_COST); 10751 10752 expand %{ 10753 regD tmpD; 10754 stackSlotL tmpS; 10755 flagsReg crx; 10756 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10757 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10758 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10759 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10760 %} 10761 %} 10762 10763 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 10764 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 10765 match(Set dst (ConvD2I src)); 10766 predicate(VM_Version::has_mtfprd()); 10767 ins_cost(DEFAULT_COST); 10768 10769 expand %{ 10770 regD tmpD; 10771 flagsReg crx; 10772 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10773 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10774 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 10775 %} 10776 %} 10777 10778 instruct convF2IRaw_regF(regF dst, regF src) %{ 10779 // no match-rule, false predicate 10780 effect(DEF dst, USE src); 10781 predicate(false); 10782 10783 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10784 size(4); 10785 ins_encode %{ 10786 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10787 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10788 %} 10789 ins_pipe(pipe_class_default); 10790 %} 10791 10792 // Float to Int conversion, NaN is mapped to 0. 10793 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10794 match(Set dst (ConvF2I src)); 10795 predicate(!VM_Version::has_mtfprd()); 10796 ins_cost(DEFAULT_COST); 10797 10798 expand %{ 10799 regF tmpF; 10800 stackSlotL tmpS; 10801 flagsReg crx; 10802 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10803 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10804 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10805 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10806 %} 10807 %} 10808 10809 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 10810 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 10811 match(Set dst (ConvF2I src)); 10812 predicate(VM_Version::has_mtfprd()); 10813 ins_cost(DEFAULT_COST); 10814 10815 expand %{ 10816 regF tmpF; 10817 flagsReg crx; 10818 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10819 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10820 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 10821 %} 10822 %} 10823 10824 // Convert to Long 10825 10826 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10827 match(Set dst (ConvI2L src)); 10828 format %{ "EXTSW $dst, $src \t// int->long" %} 10829 size(4); 10830 ins_encode %{ 10831 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10832 __ extsw($dst$$Register, $src$$Register); 10833 %} 10834 ins_pipe(pipe_class_default); 10835 %} 10836 10837 // Zero-extend: convert unsigned int to long (convUI2L). 10838 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10839 match(Set dst (AndL (ConvI2L src) mask)); 10840 ins_cost(DEFAULT_COST); 10841 10842 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10843 size(4); 10873 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10874 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10875 %} 10876 ins_pipe(pipe_class_default); 10877 %} 10878 10879 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10880 // no match-rule, false predicate 10881 effect(DEF dst, USE crx, USE src); 10882 predicate(false); 10883 10884 ins_variable_size_depending_on_alignment(true); 10885 10886 format %{ "cmovL $crx, $dst, $src" %} 10887 // Worst case is branch + move + stop, no stop without scheduler. 10888 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10889 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10890 ins_pipe(pipe_class_default); 10891 %} 10892 10893 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 10894 // no match-rule, false predicate 10895 effect(DEF dst, USE crx, USE src); 10896 predicate(false); 10897 10898 ins_variable_size_depending_on_alignment(true); 10899 10900 format %{ "cmovL $crx, $dst, $src" %} 10901 // Worst case is branch + move + stop, no stop without scheduler. 10902 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10903 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10904 ins_pipe(pipe_class_default); 10905 %} 10906 10907 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10908 // no match-rule, false predicate 10909 effect(DEF dst, USE crx, USE mem); 10910 predicate(false); 10911 10912 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10913 postalloc_expand %{ 10914 // 10915 // replaces 10916 // 10917 // region dst crx mem 10918 // \ | | / 10919 // dst=cmovL_bso_stackSlotL_conLvalue0 10920 // 10921 // with 10922 // 10923 // region dst 10924 // \ / 10925 // dst=loadConL16(0) 10926 // | 10938 m2->add_req(n_region, n_crx, n_mem); 10939 m2->add_prec(m1); 10940 10941 // operands for new nodes 10942 m1->_opnds[0] = op_dst; 10943 m1->_opnds[1] = new immL16Oper(0); 10944 m2->_opnds[0] = op_dst; 10945 m2->_opnds[1] = op_crx; 10946 m2->_opnds[2] = op_mem; 10947 10948 // registers for new nodes 10949 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10950 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10951 10952 // Insert new nodes. 10953 nodes->push(m1); 10954 nodes->push(m2); 10955 %} 10956 %} 10957 10958 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 10959 // no match-rule, false predicate 10960 effect(DEF dst, USE crx, USE src); 10961 predicate(false); 10962 10963 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 10964 postalloc_expand %{ 10965 // 10966 // replaces 10967 // 10968 // region dst crx src 10969 // \ | | / 10970 // dst=cmovL_bso_reg_conLvalue0 10971 // 10972 // with 10973 // 10974 // region dst 10975 // \ / 10976 // dst=loadConL16(0) 10977 // | 10978 // ^ region dst crx src 10979 // | \ | | / 10980 // dst=cmovL_bso_reg 10981 // 10982 10983 // Create new nodes. 10984 MachNode *m1 = new loadConL16Node(); 10985 MachNode *m2 = new cmovL_bso_regNode(); 10986 10987 // inputs for new nodes 10988 m1->add_req(n_region); 10989 m2->add_req(n_region, n_crx, n_src); 10990 m2->add_prec(m1); 10991 10992 // operands for new nodes 10993 m1->_opnds[0] = op_dst; 10994 m1->_opnds[1] = new immL16Oper(0); 10995 m2->_opnds[0] = op_dst; 10996 m2->_opnds[1] = op_crx; 10997 m2->_opnds[2] = op_src; 10998 10999 // registers for new nodes 11000 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11001 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11002 11003 // Insert new nodes. 11004 nodes->push(m1); 11005 nodes->push(m2); 11006 %} 11007 %} 11008 11009 // Float to Long conversion, NaN is mapped to 0. 11010 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11011 match(Set dst (ConvF2L src)); 11012 predicate(!VM_Version::has_mtfprd()); 11013 ins_cost(DEFAULT_COST); 11014 11015 expand %{ 11016 regF tmpF; 11017 stackSlotL tmpS; 11018 flagsReg crx; 11019 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11020 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11021 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11022 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11023 %} 11024 %} 11025 11026 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11027 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11028 match(Set dst (ConvF2L src)); 11029 predicate(VM_Version::has_mtfprd()); 11030 ins_cost(DEFAULT_COST); 11031 11032 expand %{ 11033 regF tmpF; 11034 flagsReg crx; 11035 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11036 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11037 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11038 %} 11039 %} 11040 11041 instruct convD2LRaw_regD(regD dst, regD src) %{ 11042 // no match-rule, false predicate 11043 effect(DEF dst, USE src); 11044 predicate(false); 11045 11046 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11047 size(4); 11048 ins_encode %{ 11049 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11050 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11051 %} 11052 ins_pipe(pipe_class_default); 11053 %} 11054 11055 // Double to Long conversion, NaN is mapped to 0. 11056 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11057 match(Set dst (ConvD2L src)); 11058 predicate(!VM_Version::has_mtfprd()); 11059 ins_cost(DEFAULT_COST); 11060 11061 expand %{ 11062 regD tmpD; 11063 stackSlotL tmpS; 11064 flagsReg crx; 11065 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11066 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11067 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11068 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11069 %} 11070 %} 11071 11072 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11073 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11074 match(Set dst (ConvD2L src)); 11075 predicate(VM_Version::has_mtfprd()); 11076 ins_cost(DEFAULT_COST); 11077 11078 expand %{ 11079 regD tmpD; 11080 flagsReg crx; 11081 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11082 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11083 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11084 %} 11085 %} 11086 11087 // Convert to Float 11088 11089 // Placed here as needed in expand. 11090 instruct convL2DRaw_regD(regD dst, regD src) %{ 11091 // no match-rule, false predicate 11092 effect(DEF dst, USE src); 11093 predicate(false); 11094 11095 format %{ "FCFID $dst, $src \t// convL2D" %} 11096 size(4); 11097 ins_encode %{ 11098 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11099 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11100 %} 11101 ins_pipe(pipe_class_default); 11102 %} 11103 11104 // Placed here as needed in expand. 11105 instruct convD2F_reg(regF dst, regD src) %{ 11106 match(Set dst (ConvD2F src)); 11132 %} 11133 %} 11134 11135 instruct convL2FRaw_regF(regF dst, regD src) %{ 11136 // no match-rule, false predicate 11137 effect(DEF dst, USE src); 11138 predicate(false); 11139 11140 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11141 size(4); 11142 ins_encode %{ 11143 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11144 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11145 %} 11146 ins_pipe(pipe_class_default); 11147 %} 11148 11149 // Integer to Float conversion. Special version for Power7. 11150 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11151 match(Set dst (ConvI2F src)); 11152 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11153 ins_cost(DEFAULT_COST); 11154 11155 expand %{ 11156 iRegLdst tmpL; 11157 stackSlotL tmpS; 11158 regD tmpD; 11159 convI2L_reg(tmpL, src); // Sign-extension int to long. 11160 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11161 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11162 convL2FRaw_regF(dst, tmpD); // Convert to float. 11163 %} 11164 %} 11165 11166 // Integer to Float conversion. Special version for Power8. 11167 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11168 match(Set dst (ConvI2F src)); 11169 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11170 ins_cost(DEFAULT_COST); 11171 11172 expand %{ 11173 regD tmpD; 11174 moveI2D_reg(tmpD, src); 11175 convL2FRaw_regF(dst, tmpD); // Convert to float. 11176 %} 11177 %} 11178 11179 // L2F to avoid runtime call. 11180 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11181 match(Set dst (ConvL2F src)); 11182 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11183 ins_cost(DEFAULT_COST); 11184 11185 expand %{ 11186 stackSlotL tmpS; 11187 regD tmpD; 11188 regL_to_stkL(tmpS, src); // Store long to stack. 11189 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11190 convL2FRaw_regF(dst, tmpD); // Convert to float. 11191 %} 11192 %} 11193 11194 // L2F to avoid runtime call. Special version for Power8. 11195 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11196 match(Set dst (ConvL2F src)); 11197 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11198 ins_cost(DEFAULT_COST); 11199 11200 expand %{ 11201 regD tmpD; 11202 moveL2D_reg(tmpD, src); 11203 convL2FRaw_regF(dst, tmpD); // Convert to float. 11204 %} 11205 %} 11206 11207 // Moved up as used in expand. 11208 //instruct convD2F_reg(regF dst, regD src) %{%} 11209 11210 // Convert to Double 11211 11212 // Integer to Double conversion. 11213 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11214 match(Set dst (ConvI2D src)); 11215 predicate(!VM_Version::has_mtfprd()); 11216 ins_cost(DEFAULT_COST); 11217 11218 expand %{ 11219 iRegLdst tmpL; 11220 stackSlotL tmpS; 11221 regD tmpD; 11222 convI2L_reg(tmpL, src); // Sign-extension int to long. 11223 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11224 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11225 convL2DRaw_regD(dst, tmpD); // Convert to double. 11226 %} 11227 %} 11228 11229 // Integer to Double conversion. Special version for Power8. 11230 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11231 match(Set dst (ConvI2D src)); 11232 predicate(VM_Version::has_mtfprd()); 11233 ins_cost(DEFAULT_COST); 11234 11235 expand %{ 11236 regD tmpD; 11237 moveI2D_reg(tmpD, src); 11238 convL2DRaw_regD(dst, tmpD); // Convert to double. 11239 %} 11240 %} 11241 11242 // Long to Double conversion 11243 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11244 match(Set dst (ConvL2D src)); 11245 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11246 11247 expand %{ 11248 regD tmpD; 11249 moveL2D_stack_reg(tmpD, src); 11250 convL2DRaw_regD(dst, tmpD); 11251 %} 11252 %} 11253 11254 // Long to Double conversion. Special version for Power8. 11255 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11256 match(Set dst (ConvL2D src)); 11257 predicate(VM_Version::has_mtfprd()); 11258 ins_cost(DEFAULT_COST); 11259 11260 expand %{ 11261 regD tmpD; 11262 moveL2D_reg(tmpD, src); 11263 convL2DRaw_regD(dst, tmpD); // Convert to double. 11264 %} 11265 %} 11266 11267 instruct convF2D_reg(regD dst, regF src) %{ 11268 match(Set dst (ConvF2D src)); 11269 format %{ "FMR $dst, $src \t// float->double" %} 11270 // variable size, 0 or 4 11271 ins_encode %{ 11272 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11273 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11274 %} 11275 ins_pipe(pipe_class_default); 11276 %} 11277 11278 //----------Control Flow Instructions------------------------------------------ 11279 // Compare Instructions 11280 11281 // Compare Integers 11282 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11283 match(Set crx (CmpI src1 src2)); |