1268
1269 static inline jlong replicate_immF(float con) {
1270 // Replicate float con 2 times and pack into vector.
1271 int val = *((int*)&con);
1272 jlong lval = val;
1273 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1274 return lval;
1275 }
1276
1277 //=============================================================================
1278
1279 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1280 int Compile::ConstantTable::calculate_table_base_offset() const {
1281 return 0; // absolute addressing, no offset
1282 }
1283
1284 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1285 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1286 Compile *C = ra_->C;
1287
1288 iRegPdstOper *op_dst = new (C) iRegPdstOper();
1289 MachNode *m1 = new (C) loadToc_hiNode();
1290 MachNode *m2 = new (C) loadToc_loNode();
1291
1292 m1->add_req(NULL);
1293 m2->add_req(NULL, m1);
1294 m1->_opnds[0] = op_dst;
1295 m2->_opnds[0] = op_dst;
1296 m2->_opnds[1] = op_dst;
1297 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1298 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1299 nodes->push(m1);
1300 nodes->push(m2);
1301 }
1302
1303 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1304 // Is postalloc expanded.
1305 ShouldNotReachHere();
1306 }
1307
1308 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1309 return 0;
1310 }
2215 // ones.
2216 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2217 // Is the offset within the range of a ppc64 pc relative branch?
2218 bool b;
2219
2220 const int safety_zone = 3 * BytesPerInstWord;
2221 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2222 29 - 16 + 1 + 2);
2223 return b;
2224 }
2225
2226 const bool Matcher::isSimpleConstant64(jlong value) {
2227 // Probably always true, even if a temp register is required.
2228 return true;
2229 }
2230 /* TODO: PPC port
2231 // Make a new machine dependent decode node (with its operands).
2232 MachTypeNode *Matcher::make_decode_node(Compile *C) {
2233 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
2234 "This method is only implemented for unscaled cOops mode so far");
2235 MachTypeNode *decode = new (C) decodeN_unscaledNode();
2236 decode->set_opnd_array(0, new (C) iRegPdstOper());
2237 decode->set_opnd_array(1, new (C) iRegNsrcOper());
2238 return decode;
2239 }
2240 */
2241 // Threshold size for cleararray.
2242 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2243
2244 // false => size gets scaled to BytesPerLong, ok.
2245 const bool Matcher::init_array_count_is_in_bytes = false;
2246
2247 // Use conditional move (CMOVL) on Power7.
2248 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves
2249
2250 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet.
2251 // fsel doesn't accept a condition register as input, so this would be slightly different.
2252 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
2253
2254 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand).
2255 const bool Matcher::require_postalloc_expand = true;
2256
2257 // Should the Matcher clone shifts on addressing modes, expecting them to
2583 %}
2584
2585 %} // encode
2586
2587 source %{
2588
2589 typedef struct {
2590 loadConL_hiNode *_large_hi;
2591 loadConL_loNode *_large_lo;
2592 loadConLNode *_small;
2593 MachNode *_last;
2594 } loadConLNodesTuple;
2595
2596 loadConLNodesTuple loadConLNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2597 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2598 loadConLNodesTuple nodes;
2599
2600 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2601 if (large_constant_pool) {
2602 // Create new nodes.
2603 loadConL_hiNode *m1 = new (C) loadConL_hiNode();
2604 loadConL_loNode *m2 = new (C) loadConL_loNode();
2605
2606 // inputs for new nodes
2607 m1->add_req(NULL, toc);
2608 m2->add_req(NULL, m1);
2609
2610 // operands for new nodes
2611 m1->_opnds[0] = new (C) iRegLdstOper(); // dst
2612 m1->_opnds[1] = immSrc; // src
2613 m1->_opnds[2] = new (C) iRegPdstOper(); // toc
2614 m2->_opnds[0] = new (C) iRegLdstOper(); // dst
2615 m2->_opnds[1] = immSrc; // src
2616 m2->_opnds[2] = new (C) iRegLdstOper(); // base
2617
2618 // Initialize ins_attrib TOC fields.
2619 m1->_const_toc_offset = -1;
2620 m2->_const_toc_offset_hi_node = m1;
2621
2622 // Initialize ins_attrib instruction offset.
2623 m1->_cbuf_insts_offset = -1;
2624
2625 // register allocation for new nodes
2626 ra_->set_pair(m1->_idx, reg_second, reg_first);
2627 ra_->set_pair(m2->_idx, reg_second, reg_first);
2628
2629 // Create result.
2630 nodes._large_hi = m1;
2631 nodes._large_lo = m2;
2632 nodes._small = NULL;
2633 nodes._last = nodes._large_lo;
2634 assert(m2->bottom_type()->isa_long(), "must be long");
2635 } else {
2636 loadConLNode *m2 = new (C) loadConLNode();
2637
2638 // inputs for new nodes
2639 m2->add_req(NULL, toc);
2640
2641 // operands for new nodes
2642 m2->_opnds[0] = new (C) iRegLdstOper(); // dst
2643 m2->_opnds[1] = immSrc; // src
2644 m2->_opnds[2] = new (C) iRegPdstOper(); // toc
2645
2646 // Initialize ins_attrib instruction offset.
2647 m2->_cbuf_insts_offset = -1;
2648
2649 // register allocation for new nodes
2650 ra_->set_pair(m2->_idx, reg_second, reg_first);
2651
2652 // Create result.
2653 nodes._large_hi = NULL;
2654 nodes._large_lo = NULL;
2655 nodes._small = m2;
2656 nodes._last = nodes._small;
2657 assert(m2->bottom_type()->isa_long(), "must be long");
2658 }
2659
2660 return nodes;
2661 }
2662
2663 %} // source
2664
2733 // Create a non-oop constant, no relocation needed.
2734 const_toc_addr = __ long_constant((jlong)$src$$constant);
2735 }
2736
2737 // Get the constant's TOC offset.
2738 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2739 // Store the toc offset of the constant.
2740 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2741 }
2742
2743 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2744 %}
2745
2746 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2747 // Enc_class needed as consttanttablebase is not supported by postalloc
2748 // expand.
2749 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2750 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2751 if (large_constant_pool) {
2752 // Create new nodes.
2753 loadConP_hiNode *m1 = new (C) loadConP_hiNode();
2754 loadConP_loNode *m2 = new (C) loadConP_loNode();
2755
2756 // inputs for new nodes
2757 m1->add_req(NULL, n_toc);
2758 m2->add_req(NULL, m1);
2759
2760 // operands for new nodes
2761 m1->_opnds[0] = new (C) iRegPdstOper(); // dst
2762 m1->_opnds[1] = op_src; // src
2763 m1->_opnds[2] = new (C) iRegPdstOper(); // toc
2764 m2->_opnds[0] = new (C) iRegPdstOper(); // dst
2765 m2->_opnds[1] = op_src; // src
2766 m2->_opnds[2] = new (C) iRegLdstOper(); // base
2767
2768 // Initialize ins_attrib TOC fields.
2769 m1->_const_toc_offset = -1;
2770 m2->_const_toc_offset_hi_node = m1;
2771
2772 // Register allocation for new nodes.
2773 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2774 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2775
2776 nodes->push(m1);
2777 nodes->push(m2);
2778 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2779 } else {
2780 loadConPNode *m2 = new (C) loadConPNode();
2781
2782 // inputs for new nodes
2783 m2->add_req(NULL, n_toc);
2784
2785 // operands for new nodes
2786 m2->_opnds[0] = new (C) iRegPdstOper(); // dst
2787 m2->_opnds[1] = op_src; // src
2788 m2->_opnds[2] = new (C) iRegPdstOper(); // toc
2789
2790 // Register allocation for new nodes.
2791 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2792
2793 nodes->push(m2);
2794 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2795 }
2796 %}
2797
2798 // Enc_class needed as consttanttablebase is not supported by postalloc
2799 // expand.
2800 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2801 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2802
2803 MachNode *m2;
2804 if (large_constant_pool) {
2805 m2 = new (C) loadConFCompNode();
2806 } else {
2807 m2 = new (C) loadConFNode();
2808 }
2809 // inputs for new nodes
2810 m2->add_req(NULL, n_toc);
2811
2812 // operands for new nodes
2813 m2->_opnds[0] = op_dst;
2814 m2->_opnds[1] = op_src;
2815 m2->_opnds[2] = new (C) iRegPdstOper(); // constanttablebase
2816
2817 // register allocation for new nodes
2818 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2819 nodes->push(m2);
2820 %}
2821
2822 // Enc_class needed as consttanttablebase is not supported by postalloc
2823 // expand.
2824 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2825 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2826
2827 MachNode *m2;
2828 if (large_constant_pool) {
2829 m2 = new (C) loadConDCompNode();
2830 } else {
2831 m2 = new (C) loadConDNode();
2832 }
2833 // inputs for new nodes
2834 m2->add_req(NULL, n_toc);
2835
2836 // operands for new nodes
2837 m2->_opnds[0] = op_dst;
2838 m2->_opnds[1] = op_src;
2839 m2->_opnds[2] = new (C) iRegPdstOper(); // constanttablebase
2840
2841 // register allocation for new nodes
2842 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2843 nodes->push(m2);
2844 %}
2845
2846 enc_class enc_stw(iRegIsrc src, memory mem) %{
2847 // TODO: PPC port $archOpcode(ppc64Opcode_stw);
2848 MacroAssembler _masm(&cbuf);
2849 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2850 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2851 %}
2852
2853 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2854 // TODO: PPC port $archOpcode(ppc64Opcode_std);
2855 MacroAssembler _masm(&cbuf);
2856 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2857 // Operand 'ds' requires 4-alignment.
2858 assert((Idisp & 0x3) == 0, "unaligned offset");
2859 __ std($src$$Register, Idisp, $mem$$base$$Register);
2901 #endif
2902 __ li(R0, 0);
2903 __ membar(Assembler::StoreStore);
2904 #if 0 // TODO: PPC port
2905 __ bind(skip_storestore);
2906 #endif
2907
2908 // Do the store.
2909 if ($mem$$index == 0) {
2910 __ stb(R0, $mem$$disp, $mem$$base$$Register);
2911 } else {
2912 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc");
2913 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register);
2914 }
2915 %}
2916
2917 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2918
2919 if (VM_Version::has_isel()) {
2920 // use isel instruction with Power 7
2921 cmpP_reg_imm16Node *n_compare = new (C) cmpP_reg_imm16Node();
2922 encodeP_subNode *n_sub_base = new (C) encodeP_subNode();
2923 encodeP_shiftNode *n_shift = new (C) encodeP_shiftNode();
2924 cond_set_0_oopNode *n_cond_set = new (C) cond_set_0_oopNode();
2925
2926 n_compare->add_req(n_region, n_src);
2927 n_compare->_opnds[0] = op_crx;
2928 n_compare->_opnds[1] = op_src;
2929 n_compare->_opnds[2] = new (C) immL16Oper(0);
2930
2931 n_sub_base->add_req(n_region, n_src);
2932 n_sub_base->_opnds[0] = op_dst;
2933 n_sub_base->_opnds[1] = op_src;
2934 n_sub_base->_bottom_type = _bottom_type;
2935
2936 n_shift->add_req(n_region, n_sub_base);
2937 n_shift->_opnds[0] = op_dst;
2938 n_shift->_opnds[1] = op_dst;
2939 n_shift->_bottom_type = _bottom_type;
2940
2941 n_cond_set->add_req(n_region, n_compare, n_shift);
2942 n_cond_set->_opnds[0] = op_dst;
2943 n_cond_set->_opnds[1] = op_crx;
2944 n_cond_set->_opnds[2] = op_dst;
2945 n_cond_set->_bottom_type = _bottom_type;
2946
2947 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2948 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2949 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2950 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2951
2952 nodes->push(n_compare);
2953 nodes->push(n_sub_base);
2954 nodes->push(n_shift);
2955 nodes->push(n_cond_set);
2956
2957 } else {
2958 // before Power 7
2959 moveRegNode *n_move = new (C) moveRegNode();
2960 cmpP_reg_imm16Node *n_compare = new (C) cmpP_reg_imm16Node();
2961 encodeP_shiftNode *n_shift = new (C) encodeP_shiftNode();
2962 cond_sub_baseNode *n_sub_base = new (C) cond_sub_baseNode();
2963
2964 n_move->add_req(n_region, n_src);
2965 n_move->_opnds[0] = op_dst;
2966 n_move->_opnds[1] = op_src;
2967 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop.
2968
2969 n_compare->add_req(n_region, n_src);
2970 n_compare->add_prec(n_move);
2971
2972 n_compare->_opnds[0] = op_crx;
2973 n_compare->_opnds[1] = op_src;
2974 n_compare->_opnds[2] = new (C) immL16Oper(0);
2975
2976 n_sub_base->add_req(n_region, n_compare, n_src);
2977 n_sub_base->_opnds[0] = op_dst;
2978 n_sub_base->_opnds[1] = op_crx;
2979 n_sub_base->_opnds[2] = op_src;
2980 n_sub_base->_bottom_type = _bottom_type;
2981
2982 n_shift->add_req(n_region, n_sub_base);
2983 n_shift->_opnds[0] = op_dst;
2984 n_shift->_opnds[1] = op_dst;
2985 n_shift->_bottom_type = _bottom_type;
2986
2987 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2988 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2989 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2990 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2991
2992 nodes->push(n_move);
2993 nodes->push(n_compare);
2994 nodes->push(n_sub_base);
2995 nodes->push(n_shift);
2996 }
2997
2998 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2999 %}
3000
3001 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3002
3003 encodeP_subNode *n1 = new (C) encodeP_subNode();
3004 n1->add_req(n_region, n_src);
3005 n1->_opnds[0] = op_dst;
3006 n1->_opnds[1] = op_src;
3007 n1->_bottom_type = _bottom_type;
3008
3009 encodeP_shiftNode *n2 = new (C) encodeP_shiftNode();
3010 n2->add_req(n_region, n1);
3011 n2->_opnds[0] = op_dst;
3012 n2->_opnds[1] = op_dst;
3013 n2->_bottom_type = _bottom_type;
3014 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3016
3017 nodes->push(n1);
3018 nodes->push(n2);
3019 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3020 %}
3021
3022 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3023 decodeN_shiftNode *n_shift = new (C) decodeN_shiftNode();
3024 cmpN_reg_imm0Node *n_compare = new (C) cmpN_reg_imm0Node();
3025
3026 n_compare->add_req(n_region, n_src);
3027 n_compare->_opnds[0] = op_crx;
3028 n_compare->_opnds[1] = op_src;
3029 n_compare->_opnds[2] = new (C) immN_0Oper(TypeNarrowOop::NULL_PTR);
3030
3031 n_shift->add_req(n_region, n_src);
3032 n_shift->_opnds[0] = op_dst;
3033 n_shift->_opnds[1] = op_src;
3034 n_shift->_bottom_type = _bottom_type;
3035
3036 if (VM_Version::has_isel()) {
3037 // use isel instruction with Power 7
3038
3039 decodeN_addNode *n_add_base = new (C) decodeN_addNode();
3040 n_add_base->add_req(n_region, n_shift);
3041 n_add_base->_opnds[0] = op_dst;
3042 n_add_base->_opnds[1] = op_dst;
3043 n_add_base->_bottom_type = _bottom_type;
3044
3045 cond_set_0_ptrNode *n_cond_set = new (C) cond_set_0_ptrNode();
3046 n_cond_set->add_req(n_region, n_compare, n_add_base);
3047 n_cond_set->_opnds[0] = op_dst;
3048 n_cond_set->_opnds[1] = op_crx;
3049 n_cond_set->_opnds[2] = op_dst;
3050 n_cond_set->_bottom_type = _bottom_type;
3051
3052 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3053 ra_->set_oop(n_cond_set, true);
3054
3055 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3056 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3057 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3058 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3059
3060 nodes->push(n_compare);
3061 nodes->push(n_shift);
3062 nodes->push(n_add_base);
3063 nodes->push(n_cond_set);
3064
3065 } else {
3066 // before Power 7
3067 cond_add_baseNode *n_add_base = new (C) cond_add_baseNode();
3068
3069 n_add_base->add_req(n_region, n_compare, n_shift);
3070 n_add_base->_opnds[0] = op_dst;
3071 n_add_base->_opnds[1] = op_crx;
3072 n_add_base->_opnds[2] = op_dst;
3073 n_add_base->_bottom_type = _bottom_type;
3074
3075 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3076 ra_->set_oop(n_add_base, true);
3077
3078 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3079 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3080 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3081
3082 nodes->push(n_compare);
3083 nodes->push(n_shift);
3084 nodes->push(n_add_base);
3085 }
3086 %}
3087
3088 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3089 decodeN_shiftNode *n1 = new (C) decodeN_shiftNode();
3090 n1->add_req(n_region, n_src);
3091 n1->_opnds[0] = op_dst;
3092 n1->_opnds[1] = op_src;
3093 n1->_bottom_type = _bottom_type;
3094
3095 decodeN_addNode *n2 = new (C) decodeN_addNode();
3096 n2->add_req(n_region, n1);
3097 n2->_opnds[0] = op_dst;
3098 n2->_opnds[1] = op_dst;
3099 n2->_bottom_type = _bottom_type;
3100 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3101 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3102
3103 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3104 ra_->set_oop(n2, true);
3105
3106 nodes->push(n1);
3107 nodes->push(n2);
3108 %}
3109
3110 enc_class enc_cmove_reg(iRegIdst dst, flagsReg crx, iRegIsrc src, cmpOp cmp) %{
3111 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3112
3113 MacroAssembler _masm(&cbuf);
3114 int cc = $cmp$$cmpcode;
3115 int flags_reg = $crx$$reg;
3371 cc_to_biint(cc, flags_reg),
3372 l,
3373 MacroAssembler::bc_far_optimize_on_relocate);
3374 } else {
3375 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3376 cc_to_biint(cc, flags_reg),
3377 l);
3378 }
3379 #endif
3380 Unimplemented();
3381 %}
3382
3383 // Postalloc expand emitter for loading a replicatef float constant from
3384 // the method's TOC.
3385 // Enc_class needed as consttanttablebase is not supported by postalloc
3386 // expand.
3387 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3388 // Create new nodes.
3389
3390 // Make an operand with the bit pattern to load as float.
3391 immLOper *op_repl = new (C) immLOper((jlong)replicate_immF(op_src->constantF()));
3392
3393 loadConLNodesTuple loadConLNodes =
3394 loadConLNodesTuple_create(C, ra_, n_toc, op_repl,
3395 ra_->get_reg_second(this), ra_->get_reg_first(this));
3396
3397 // Push new nodes.
3398 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3399 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3400
3401 assert(nodes->length() >= 1, "must have created at least 1 node");
3402 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3403 %}
3404
3405 // This enc_class is needed so that scheduler gets proper
3406 // input mapping for latency computation.
3407 enc_class enc_poll(immI dst, iRegLdst poll) %{
3408 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
3409 // Fake operand dst needed for PPC scheduler.
3410 assert($dst$$constant == 0x0, "dst must be 0x0");
3411
3594 ? _load_ic_hi_node->_cbuf_insts_offset
3595 : _load_ic_node->_cbuf_insts_offset;
3596 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3597 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3598 "should be load from TOC");
3599
3600 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr));
3601 }
3602
3603 // At this point I do not have the address of the trampoline stub,
3604 // and the entry point might be too far away for bl. Pc() serves
3605 // as dummy and bl will be patched later.
3606 __ bl((address) __ pc());
3607 %}
3608
3609 // postalloc expand emitter for virtual calls.
3610 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3611
3612 // Create the nodes for loading the IC from the TOC.
3613 loadConLNodesTuple loadConLNodes_IC =
3614 loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong)Universe::non_oop_word()),
3615 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3616
3617 // Create the call node.
3618 CallDynamicJavaDirectSchedNode *call = new (C) CallDynamicJavaDirectSchedNode();
3619 call->_method_handle_invoke = _method_handle_invoke;
3620 call->_vtable_index = _vtable_index;
3621 call->_method = _method;
3622 call->_bci = _bci;
3623 call->_optimized_virtual = _optimized_virtual;
3624 call->_tf = _tf;
3625 call->_entry_point = _entry_point;
3626 call->_cnt = _cnt;
3627 call->_argsize = _argsize;
3628 call->_oop_map = _oop_map;
3629 call->_jvms = _jvms;
3630 call->_jvmadj = _jvmadj;
3631 call->_in_rms = _in_rms;
3632 call->_nesting = _nesting;
3633
3634 // New call needs all inputs of old call.
3635 // Req...
3636 for (uint i = 0; i < req(); ++i) {
3637 // The expanded node does not need toc any more.
3638 // Add the inline cache constant here instead. This expresses the
3748 // Check the ret_addr_offset.
3749 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3750 "Fix constant in ret_addr_offset()");
3751 %}
3752
3753 // Move to ctr for leaf call.
3754 // This enc_class is needed so that scheduler gets proper
3755 // input mapping for latency computation.
3756 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3757 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3758 MacroAssembler _masm(&cbuf);
3759 __ mtctr($src$$Register);
3760 %}
3761
3762 // Postalloc expand emitter for runtime leaf calls.
3763 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3764 loadConLNodesTuple loadConLNodes_Entry;
3765 #if defined(ABI_ELFv2)
3766 jlong entry_address = (jlong) this->entry_point();
3767 assert(entry_address, "need address here");
3768 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
3769 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3770 #else
3771 // Get the struct that describes the function we are about to call.
3772 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3773 assert(fd, "need fd here");
3774 jlong entry_address = (jlong) fd->entry();
3775 // new nodes
3776 loadConLNodesTuple loadConLNodes_Env;
3777 loadConLNodesTuple loadConLNodes_Toc;
3778
3779 // Create nodes and operands for loading the entry point.
3780 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
3781 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3782
3783
3784 // Create nodes and operands for loading the env pointer.
3785 if (fd->env() != NULL) {
3786 loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->env()),
3787 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3788 } else {
3789 loadConLNodes_Env._large_hi = NULL;
3790 loadConLNodes_Env._large_lo = NULL;
3791 loadConLNodes_Env._small = NULL;
3792 loadConLNodes_Env._last = new (C) loadConL16Node();
3793 loadConLNodes_Env._last->_opnds[0] = new (C) iRegLdstOper();
3794 loadConLNodes_Env._last->_opnds[1] = new (C) immL16Oper(0);
3795 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3796 }
3797
3798 // Create nodes and operands for loading the Toc point.
3799 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()),
3800 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3801 #endif // ABI_ELFv2
3802 // mtctr node
3803 MachNode *mtctr = new (C) CallLeafDirect_mtctrNode();
3804
3805 assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3806 mtctr->add_req(0, loadConLNodes_Entry._last);
3807
3808 mtctr->_opnds[0] = new (C) iRegLdstOper();
3809 mtctr->_opnds[1] = new (C) iRegLdstOper();
3810
3811 // call node
3812 MachCallLeafNode *call = new (C) CallLeafDirectNode();
3813
3814 call->_opnds[0] = _opnds[0];
3815 call->_opnds[1] = new (C) methodOper((intptr_t) entry_address); // May get set later.
3816
3817 // Make the new call node look like the old one.
3818 call->_name = _name;
3819 call->_tf = _tf;
3820 call->_entry_point = _entry_point;
3821 call->_cnt = _cnt;
3822 call->_argsize = _argsize;
3823 call->_oop_map = _oop_map;
3824 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3825 call->_jvms = NULL;
3826 call->_jvmadj = _jvmadj;
3827 call->_in_rms = _in_rms;
3828 call->_nesting = _nesting;
3829
3830
3831 // New call needs all inputs of old call.
3832 // Req...
3833 for (uint i = 0; i < req(); ++i) {
3834 if (i != mach_constant_base_node_input()) {
3835 call->add_req(in(i));
6033 predicate(false);
6034
6035 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
6036 size(4);
6037 ins_encode %{
6038 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6039 __ clrldi($dst$$Register, $src$$Register, 0x20);
6040 %}
6041 ins_pipe(pipe_class_default);
6042 %}
6043
6044 // Loading ConN must be postalloc expanded so that edges between
6045 // the nodes are safe. They may not interfere with a safepoint.
6046 // GL TODO: This needs three instructions: better put this into the constant pool.
6047 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6048 match(Set dst src);
6049 ins_cost(DEFAULT_COST*2);
6050
6051 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6052 postalloc_expand %{
6053 MachNode *m1 = new (C) loadConN_hiNode();
6054 MachNode *m2 = new (C) loadConN_loNode();
6055 MachNode *m3 = new (C) clearMs32bNode();
6056 m1->add_req(NULL);
6057 m2->add_req(NULL, m1);
6058 m3->add_req(NULL, m2);
6059 m1->_opnds[0] = op_dst;
6060 m1->_opnds[1] = op_src;
6061 m2->_opnds[0] = op_dst;
6062 m2->_opnds[1] = op_dst;
6063 m2->_opnds[2] = op_src;
6064 m3->_opnds[0] = op_dst;
6065 m3->_opnds[1] = op_dst;
6066 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6067 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6068 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6069 nodes->push(m1);
6070 nodes->push(m2);
6071 nodes->push(m3);
6072 %}
6073 %}
6074
6075 instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{
6100 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant);
6101 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
6102 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
6103 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6104
6105 __ relocate(rspec, 1);
6106 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6107 %}
6108 ins_pipe(pipe_class_default);
6109 %}
6110
6111 // Loading ConNKlass must be postalloc expanded so that edges between
6112 // the nodes are safe. They may not interfere with a safepoint.
6113 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6114 match(Set dst src);
6115 ins_cost(DEFAULT_COST*2);
6116
6117 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6118 postalloc_expand %{
6119 // Load high bits into register. Sign extended.
6120 MachNode *m1 = new (C) loadConNKlass_hiNode();
6121 m1->add_req(NULL);
6122 m1->_opnds[0] = op_dst;
6123 m1->_opnds[1] = op_src;
6124 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6125 nodes->push(m1);
6126
6127 MachNode *m2 = m1;
6128 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) {
6129 // Value might be 1-extended. Mask out these bits.
6130 m2 = new (C) clearMs32bNode();
6131 m2->add_req(NULL, m1);
6132 m2->_opnds[0] = op_dst;
6133 m2->_opnds[1] = op_dst;
6134 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6135 nodes->push(m2);
6136 }
6137
6138 MachNode *m3 = new (C) loadConNKlass_loNode();
6139 m3->add_req(NULL, m2);
6140 m3->_opnds[0] = op_dst;
6141 m3->_opnds[1] = op_src;
6142 m3->_opnds[2] = op_dst;
6143 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6144 nodes->push(m3);
6145 %}
6146 %}
6147
6148 // 0x1 is used in object initialization (initial object header).
6149 // No constant pool entries required.
6150 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6151 match(Set dst src);
6152
6153 format %{ "LI $dst, $src \t// ptr" %}
6154 size(4);
6155 ins_encode %{
6156 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
6157 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6158 %}
6970 instruct encodePKlass_32GAligned(iRegNdst dst, iRegPsrc src) %{
6971 match(Set dst (EncodePKlass src));
6972 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
6973
6974 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
6975 size(4);
6976 ins_encode %{
6977 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6978 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
6979 %}
6980 ins_pipe(pipe_class_default);
6981 %}
6982
6983 // shift != 0, base != 0
6984 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6985 match(Set dst (EncodePKlass (Binary base src)));
6986 predicate(false);
6987
6988 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6989 postalloc_expand %{
6990 encodePKlass_sub_baseNode *n1 = new (C) encodePKlass_sub_baseNode();
6991 n1->add_req(n_region, n_base, n_src);
6992 n1->_opnds[0] = op_dst;
6993 n1->_opnds[1] = op_base;
6994 n1->_opnds[2] = op_src;
6995 n1->_bottom_type = _bottom_type;
6996
6997 encodePKlass_shiftNode *n2 = new (C) encodePKlass_shiftNode();
6998 n2->add_req(n_region, n1);
6999 n2->_opnds[0] = op_dst;
7000 n2->_opnds[1] = op_dst;
7001 n2->_bottom_type = _bottom_type;
7002 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7003 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7004
7005 nodes->push(n1);
7006 nodes->push(n2);
7007 %}
7008 %}
7009
7010 // shift != 0, base != 0
7011 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
7012 match(Set dst (EncodePKlass src));
7013 //predicate(Universe::narrow_klass_shift() != 0 &&
7014 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/);
7015
7016 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7017 ins_cost(DEFAULT_COST*2); // Don't count constant.
7047 match(Set dst (DecodeNKlass (Binary base src)));
7048 predicate(false);
7049
7050 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
7051 size(4);
7052 ins_encode %{
7053 // TODO: PPC port $archOpcode(ppc64Opcode_add);
7054 __ add($dst$$Register, $base$$Register, $src$$Register);
7055 %}
7056 ins_pipe(pipe_class_default);
7057 %}
7058
7059 // src != 0, shift != 0, base != 0
7060 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
7061 match(Set dst (DecodeNKlass (Binary base src)));
7062 //effect(kill src); // We need a register for the immediate result after shifting.
7063 predicate(false);
7064
7065 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %}
7066 postalloc_expand %{
7067 decodeNKlass_add_baseNode *n1 = new (C) decodeNKlass_add_baseNode();
7068 n1->add_req(n_region, n_base, n_src);
7069 n1->_opnds[0] = op_dst;
7070 n1->_opnds[1] = op_base;
7071 n1->_opnds[2] = op_src;
7072 n1->_bottom_type = _bottom_type;
7073
7074 decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode();
7075 n2->add_req(n_region, n1);
7076 n2->_opnds[0] = op_dst;
7077 n2->_opnds[1] = op_dst;
7078 n2->_bottom_type = _bottom_type;
7079
7080 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7081 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7082
7083 nodes->push(n1);
7084 nodes->push(n2);
7085 %}
7086 %}
7087
7088 // src != 0, shift != 0, base != 0
7089 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
7090 match(Set dst (DecodeNKlass src));
7091 // predicate(Universe::narrow_klass_shift() != 0 &&
7092 // Universe::narrow_klass_base() != 0);
7093
7094 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %}
9756 postalloc_expand %{
9757 //
9758 // replaces
9759 //
9760 // region dst crx mem
9761 // \ | | /
9762 // dst=cmovI_bso_stackSlotL_conLvalue0
9763 //
9764 // with
9765 //
9766 // region dst
9767 // \ /
9768 // dst=loadConI16(0)
9769 // |
9770 // ^ region dst crx mem
9771 // | \ | | /
9772 // dst=cmovI_bso_stackSlotL
9773 //
9774
9775 // Create new nodes.
9776 MachNode *m1 = new (C) loadConI16Node();
9777 MachNode *m2 = new (C) cmovI_bso_stackSlotLNode();
9778
9779 // inputs for new nodes
9780 m1->add_req(n_region);
9781 m2->add_req(n_region, n_crx, n_mem);
9782
9783 // precedences for new nodes
9784 m2->add_prec(m1);
9785
9786 // operands for new nodes
9787 m1->_opnds[0] = op_dst;
9788 m1->_opnds[1] = new (C) immI16Oper(0);
9789
9790 m2->_opnds[0] = op_dst;
9791 m2->_opnds[1] = op_crx;
9792 m2->_opnds[2] = op_mem;
9793
9794 // registers for new nodes
9795 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9796 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9797
9798 // Insert new nodes.
9799 nodes->push(m1);
9800 nodes->push(m2);
9801 %}
9802 %}
9803
9804 // Double to Int conversion, NaN is mapped to 0.
9805 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
9806 match(Set dst (ConvD2I src));
9807 ins_cost(DEFAULT_COST);
9808
9925 postalloc_expand %{
9926 //
9927 // replaces
9928 //
9929 // region dst crx mem
9930 // \ | | /
9931 // dst=cmovL_bso_stackSlotL_conLvalue0
9932 //
9933 // with
9934 //
9935 // region dst
9936 // \ /
9937 // dst=loadConL16(0)
9938 // |
9939 // ^ region dst crx mem
9940 // | \ | | /
9941 // dst=cmovL_bso_stackSlotL
9942 //
9943
9944 // Create new nodes.
9945 MachNode *m1 = new (C) loadConL16Node();
9946 MachNode *m2 = new (C) cmovL_bso_stackSlotLNode();
9947
9948 // inputs for new nodes
9949 m1->add_req(n_region);
9950 m2->add_req(n_region, n_crx, n_mem);
9951 m2->add_prec(m1);
9952
9953 // operands for new nodes
9954 m1->_opnds[0] = op_dst;
9955 m1->_opnds[1] = new (C) immL16Oper(0);
9956 m2->_opnds[0] = op_dst;
9957 m2->_opnds[1] = op_crx;
9958 m2->_opnds[2] = op_mem;
9959
9960 // registers for new nodes
9961 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9962 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9963
9964 // Insert new nodes.
9965 nodes->push(m1);
9966 nodes->push(m2);
9967 %}
9968 %}
9969
9970 // Float to Long conversion, NaN is mapped to 0.
9971 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
9972 match(Set dst (ConvF2L src));
9973 ins_cost(DEFAULT_COST);
9974
9975 expand %{
10271 postalloc_expand %{
10272 //
10273 // replaces
10274 //
10275 // region crx
10276 // \ |
10277 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1
10278 //
10279 // with
10280 //
10281 // region
10282 // \
10283 // dst=loadConI16(0)
10284 // |
10285 // ^ region crx
10286 // | \ |
10287 // dst=cmovI_conIvalueMinus1_conIvalue1
10288 //
10289
10290 // Create new nodes.
10291 MachNode *m1 = new (C) loadConI16Node();
10292 MachNode *m2 = new (C) cmovI_conIvalueMinus1_conIvalue1Node();
10293
10294 // inputs for new nodes
10295 m1->add_req(n_region);
10296 m2->add_req(n_region, n_crx);
10297 m2->add_prec(m1);
10298
10299 // operands for new nodes
10300 m1->_opnds[0] = op_dst;
10301 m1->_opnds[1] = new (C) immI16Oper(0);
10302 m2->_opnds[0] = op_dst;
10303 m2->_opnds[1] = op_crx;
10304
10305 // registers for new nodes
10306 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10307 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10308
10309 // Insert new nodes.
10310 nodes->push(m1);
10311 nodes->push(m2);
10312 %}
10313 %}
10314
10315 // Manifest a CmpL3 result in an integer register. Very painful.
10316 // This is the test to avoid.
10317 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
10318 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
10319 match(Set dst (CmpL3 src1 src2));
10320 ins_cost(DEFAULT_COST*5+BRANCH_COST);
10321
10606 postalloc_expand %{
10607 //
10608 // replaces
10609 //
10610 // region src1 src2
10611 // \ | |
10612 // crx=cmpF_reg_reg
10613 //
10614 // with
10615 //
10616 // region src1 src2
10617 // \ | |
10618 // crx=cmpFUnordered_reg_reg
10619 // |
10620 // ^ region
10621 // | \
10622 // crx=cmov_bns_less
10623 //
10624
10625 // Create new nodes.
10626 MachNode *m1 = new (C) cmpFUnordered_reg_regNode();
10627 MachNode *m2 = new (C) cmov_bns_lessNode();
10628
10629 // inputs for new nodes
10630 m1->add_req(n_region, n_src1, n_src2);
10631 m2->add_req(n_region);
10632 m2->add_prec(m1);
10633
10634 // operands for new nodes
10635 m1->_opnds[0] = op_crx;
10636 m1->_opnds[1] = op_src1;
10637 m1->_opnds[2] = op_src2;
10638 m2->_opnds[0] = op_crx;
10639
10640 // registers for new nodes
10641 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10642 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10643
10644 // Insert new nodes.
10645 nodes->push(m1);
10646 nodes->push(m2);
10647 %}
10681 postalloc_expand %{
10682 //
10683 // replaces
10684 //
10685 // region src1 src2
10686 // \ | |
10687 // crx=cmpD_reg_reg
10688 //
10689 // with
10690 //
10691 // region src1 src2
10692 // \ | |
10693 // crx=cmpDUnordered_reg_reg
10694 // |
10695 // ^ region
10696 // | \
10697 // crx=cmov_bns_less
10698 //
10699
10700 // create new nodes
10701 MachNode *m1 = new (C) cmpDUnordered_reg_regNode();
10702 MachNode *m2 = new (C) cmov_bns_lessNode();
10703
10704 // inputs for new nodes
10705 m1->add_req(n_region, n_src1, n_src2);
10706 m2->add_req(n_region);
10707 m2->add_prec(m1);
10708
10709 // operands for new nodes
10710 m1->_opnds[0] = op_crx;
10711 m1->_opnds[1] = op_src1;
10712 m1->_opnds[2] = op_src2;
10713 m2->_opnds[0] = op_crx;
10714
10715 // registers for new nodes
10716 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10717 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10718
10719 // Insert new nodes.
10720 nodes->push(m1);
10721 nodes->push(m2);
10722 %}
|
1268
1269 static inline jlong replicate_immF(float con) {
1270 // Replicate float con 2 times and pack into vector.
1271 int val = *((int*)&con);
1272 jlong lval = val;
1273 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1274 return lval;
1275 }
1276
1277 //=============================================================================
1278
1279 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1280 int Compile::ConstantTable::calculate_table_base_offset() const {
1281 return 0; // absolute addressing, no offset
1282 }
1283
1284 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1285 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1286 Compile *C = ra_->C;
1287
1288 iRegPdstOper *op_dst = iRegPdstOper();
1289 MachNode *m1 = loadToc_hiNode();
1290 MachNode *m2 = loadToc_loNode();
1291
1292 m1->add_req(NULL);
1293 m2->add_req(NULL, m1);
1294 m1->_opnds[0] = op_dst;
1295 m2->_opnds[0] = op_dst;
1296 m2->_opnds[1] = op_dst;
1297 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1298 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1299 nodes->push(m1);
1300 nodes->push(m2);
1301 }
1302
1303 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1304 // Is postalloc expanded.
1305 ShouldNotReachHere();
1306 }
1307
1308 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1309 return 0;
1310 }
2215 // ones.
2216 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2217 // Is the offset within the range of a ppc64 pc relative branch?
2218 bool b;
2219
2220 const int safety_zone = 3 * BytesPerInstWord;
2221 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2222 29 - 16 + 1 + 2);
2223 return b;
2224 }
2225
2226 const bool Matcher::isSimpleConstant64(jlong value) {
2227 // Probably always true, even if a temp register is required.
2228 return true;
2229 }
2230 /* TODO: PPC port
2231 // Make a new machine dependent decode node (with its operands).
2232 MachTypeNode *Matcher::make_decode_node(Compile *C) {
2233 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
2234 "This method is only implemented for unscaled cOops mode so far");
2235 MachTypeNode *decode = decodeN_unscaledNode();
2236 decode->set_opnd_array(0, iRegPdstOper());
2237 decode->set_opnd_array(1, iRegNsrcOper());
2238 return decode;
2239 }
2240 */
2241 // Threshold size for cleararray.
2242 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2243
2244 // false => size gets scaled to BytesPerLong, ok.
2245 const bool Matcher::init_array_count_is_in_bytes = false;
2246
2247 // Use conditional move (CMOVL) on Power7.
2248 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves
2249
2250 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet.
2251 // fsel doesn't accept a condition register as input, so this would be slightly different.
2252 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
2253
2254 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand).
2255 const bool Matcher::require_postalloc_expand = true;
2256
2257 // Should the Matcher clone shifts on addressing modes, expecting them to
2583 %}
2584
2585 %} // encode
2586
2587 source %{
2588
2589 typedef struct {
2590 loadConL_hiNode *_large_hi;
2591 loadConL_loNode *_large_lo;
2592 loadConLNode *_small;
2593 MachNode *_last;
2594 } loadConLNodesTuple;
2595
2596 loadConLNodesTuple loadConLNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2597 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2598 loadConLNodesTuple nodes;
2599
2600 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2601 if (large_constant_pool) {
2602 // Create new nodes.
2603 loadConL_hiNode *m1 = loadConL_hiNode();
2604 loadConL_loNode *m2 = loadConL_loNode();
2605
2606 // inputs for new nodes
2607 m1->add_req(NULL, toc);
2608 m2->add_req(NULL, m1);
2609
2610 // operands for new nodes
2611 m1->_opnds[0] = iRegLdstOper(); // dst
2612 m1->_opnds[1] = immSrc; // src
2613 m1->_opnds[2] = iRegPdstOper(); // toc
2614 m2->_opnds[0] = iRegLdstOper(); // dst
2615 m2->_opnds[1] = immSrc; // src
2616 m2->_opnds[2] = iRegLdstOper(); // base
2617
2618 // Initialize ins_attrib TOC fields.
2619 m1->_const_toc_offset = -1;
2620 m2->_const_toc_offset_hi_node = m1;
2621
2622 // Initialize ins_attrib instruction offset.
2623 m1->_cbuf_insts_offset = -1;
2624
2625 // register allocation for new nodes
2626 ra_->set_pair(m1->_idx, reg_second, reg_first);
2627 ra_->set_pair(m2->_idx, reg_second, reg_first);
2628
2629 // Create result.
2630 nodes._large_hi = m1;
2631 nodes._large_lo = m2;
2632 nodes._small = NULL;
2633 nodes._last = nodes._large_lo;
2634 assert(m2->bottom_type()->isa_long(), "must be long");
2635 } else {
2636 loadConLNode *m2 = loadConLNode();
2637
2638 // inputs for new nodes
2639 m2->add_req(NULL, toc);
2640
2641 // operands for new nodes
2642 m2->_opnds[0] = iRegLdstOper(); // dst
2643 m2->_opnds[1] = immSrc; // src
2644 m2->_opnds[2] = iRegPdstOper(); // toc
2645
2646 // Initialize ins_attrib instruction offset.
2647 m2->_cbuf_insts_offset = -1;
2648
2649 // register allocation for new nodes
2650 ra_->set_pair(m2->_idx, reg_second, reg_first);
2651
2652 // Create result.
2653 nodes._large_hi = NULL;
2654 nodes._large_lo = NULL;
2655 nodes._small = m2;
2656 nodes._last = nodes._small;
2657 assert(m2->bottom_type()->isa_long(), "must be long");
2658 }
2659
2660 return nodes;
2661 }
2662
2663 %} // source
2664
2733 // Create a non-oop constant, no relocation needed.
2734 const_toc_addr = __ long_constant((jlong)$src$$constant);
2735 }
2736
2737 // Get the constant's TOC offset.
2738 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2739 // Store the toc offset of the constant.
2740 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2741 }
2742
2743 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2744 %}
2745
2746 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2747 // Enc_class needed as consttanttablebase is not supported by postalloc
2748 // expand.
2749 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2750 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2751 if (large_constant_pool) {
2752 // Create new nodes.
2753 loadConP_hiNode *m1 = loadConP_hiNode();
2754 loadConP_loNode *m2 = loadConP_loNode();
2755
2756 // inputs for new nodes
2757 m1->add_req(NULL, n_toc);
2758 m2->add_req(NULL, m1);
2759
2760 // operands for new nodes
2761 m1->_opnds[0] = iRegPdstOper(); // dst
2762 m1->_opnds[1] = op_src; // src
2763 m1->_opnds[2] = iRegPdstOper(); // toc
2764 m2->_opnds[0] = iRegPdstOper(); // dst
2765 m2->_opnds[1] = op_src; // src
2766 m2->_opnds[2] = iRegLdstOper(); // base
2767
2768 // Initialize ins_attrib TOC fields.
2769 m1->_const_toc_offset = -1;
2770 m2->_const_toc_offset_hi_node = m1;
2771
2772 // Register allocation for new nodes.
2773 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2774 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2775
2776 nodes->push(m1);
2777 nodes->push(m2);
2778 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2779 } else {
2780 loadConPNode *m2 = loadConPNode();
2781
2782 // inputs for new nodes
2783 m2->add_req(NULL, n_toc);
2784
2785 // operands for new nodes
2786 m2->_opnds[0] = iRegPdstOper(); // dst
2787 m2->_opnds[1] = op_src; // src
2788 m2->_opnds[2] = iRegPdstOper(); // toc
2789
2790 // Register allocation for new nodes.
2791 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2792
2793 nodes->push(m2);
2794 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2795 }
2796 %}
2797
2798 // Enc_class needed as consttanttablebase is not supported by postalloc
2799 // expand.
2800 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2801 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2802
2803 MachNode *m2;
2804 if (large_constant_pool) {
2805 m2 = loadConFCompNode();
2806 } else {
2807 m2 = loadConFNode();
2808 }
2809 // inputs for new nodes
2810 m2->add_req(NULL, n_toc);
2811
2812 // operands for new nodes
2813 m2->_opnds[0] = op_dst;
2814 m2->_opnds[1] = op_src;
2815 m2->_opnds[2] = iRegPdstOper(); // constanttablebase
2816
2817 // register allocation for new nodes
2818 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2819 nodes->push(m2);
2820 %}
2821
2822 // Enc_class needed as consttanttablebase is not supported by postalloc
2823 // expand.
2824 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2825 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2826
2827 MachNode *m2;
2828 if (large_constant_pool) {
2829 m2 = loadConDCompNode();
2830 } else {
2831 m2 = loadConDNode();
2832 }
2833 // inputs for new nodes
2834 m2->add_req(NULL, n_toc);
2835
2836 // operands for new nodes
2837 m2->_opnds[0] = op_dst;
2838 m2->_opnds[1] = op_src;
2839 m2->_opnds[2] = iRegPdstOper(); // constanttablebase
2840
2841 // register allocation for new nodes
2842 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2843 nodes->push(m2);
2844 %}
2845
2846 enc_class enc_stw(iRegIsrc src, memory mem) %{
2847 // TODO: PPC port $archOpcode(ppc64Opcode_stw);
2848 MacroAssembler _masm(&cbuf);
2849 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2850 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2851 %}
2852
2853 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2854 // TODO: PPC port $archOpcode(ppc64Opcode_std);
2855 MacroAssembler _masm(&cbuf);
2856 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2857 // Operand 'ds' requires 4-alignment.
2858 assert((Idisp & 0x3) == 0, "unaligned offset");
2859 __ std($src$$Register, Idisp, $mem$$base$$Register);
2901 #endif
2902 __ li(R0, 0);
2903 __ membar(Assembler::StoreStore);
2904 #if 0 // TODO: PPC port
2905 __ bind(skip_storestore);
2906 #endif
2907
2908 // Do the store.
2909 if ($mem$$index == 0) {
2910 __ stb(R0, $mem$$disp, $mem$$base$$Register);
2911 } else {
2912 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc");
2913 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register);
2914 }
2915 %}
2916
2917 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2918
2919 if (VM_Version::has_isel()) {
2920 // use isel instruction with Power 7
2921 cmpP_reg_imm16Node *n_compare = cmpP_reg_imm16Node();
2922 encodeP_subNode *n_sub_base = encodeP_subNode();
2923 encodeP_shiftNode *n_shift = encodeP_shiftNode();
2924 cond_set_0_oopNode *n_cond_set = cond_set_0_oopNode();
2925
2926 n_compare->add_req(n_region, n_src);
2927 n_compare->_opnds[0] = op_crx;
2928 n_compare->_opnds[1] = op_src;
2929 n_compare->_opnds[2] = immL16Oper(0);
2930
2931 n_sub_base->add_req(n_region, n_src);
2932 n_sub_base->_opnds[0] = op_dst;
2933 n_sub_base->_opnds[1] = op_src;
2934 n_sub_base->_bottom_type = _bottom_type;
2935
2936 n_shift->add_req(n_region, n_sub_base);
2937 n_shift->_opnds[0] = op_dst;
2938 n_shift->_opnds[1] = op_dst;
2939 n_shift->_bottom_type = _bottom_type;
2940
2941 n_cond_set->add_req(n_region, n_compare, n_shift);
2942 n_cond_set->_opnds[0] = op_dst;
2943 n_cond_set->_opnds[1] = op_crx;
2944 n_cond_set->_opnds[2] = op_dst;
2945 n_cond_set->_bottom_type = _bottom_type;
2946
2947 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2948 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2949 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2950 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2951
2952 nodes->push(n_compare);
2953 nodes->push(n_sub_base);
2954 nodes->push(n_shift);
2955 nodes->push(n_cond_set);
2956
2957 } else {
2958 // before Power 7
2959 moveRegNode *n_move = moveRegNode();
2960 cmpP_reg_imm16Node *n_compare = cmpP_reg_imm16Node();
2961 encodeP_shiftNode *n_shift = encodeP_shiftNode();
2962 cond_sub_baseNode *n_sub_base = cond_sub_baseNode();
2963
2964 n_move->add_req(n_region, n_src);
2965 n_move->_opnds[0] = op_dst;
2966 n_move->_opnds[1] = op_src;
2967 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop.
2968
2969 n_compare->add_req(n_region, n_src);
2970 n_compare->add_prec(n_move);
2971
2972 n_compare->_opnds[0] = op_crx;
2973 n_compare->_opnds[1] = op_src;
2974 n_compare->_opnds[2] = immL16Oper(0);
2975
2976 n_sub_base->add_req(n_region, n_compare, n_src);
2977 n_sub_base->_opnds[0] = op_dst;
2978 n_sub_base->_opnds[1] = op_crx;
2979 n_sub_base->_opnds[2] = op_src;
2980 n_sub_base->_bottom_type = _bottom_type;
2981
2982 n_shift->add_req(n_region, n_sub_base);
2983 n_shift->_opnds[0] = op_dst;
2984 n_shift->_opnds[1] = op_dst;
2985 n_shift->_bottom_type = _bottom_type;
2986
2987 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2988 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2989 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2990 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2991
2992 nodes->push(n_move);
2993 nodes->push(n_compare);
2994 nodes->push(n_sub_base);
2995 nodes->push(n_shift);
2996 }
2997
2998 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2999 %}
3000
3001 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3002
3003 encodeP_subNode *n1 = encodeP_subNode();
3004 n1->add_req(n_region, n_src);
3005 n1->_opnds[0] = op_dst;
3006 n1->_opnds[1] = op_src;
3007 n1->_bottom_type = _bottom_type;
3008
3009 encodeP_shiftNode *n2 = encodeP_shiftNode();
3010 n2->add_req(n_region, n1);
3011 n2->_opnds[0] = op_dst;
3012 n2->_opnds[1] = op_dst;
3013 n2->_bottom_type = _bottom_type;
3014 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3016
3017 nodes->push(n1);
3018 nodes->push(n2);
3019 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3020 %}
3021
3022 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3023 decodeN_shiftNode *n_shift = decodeN_shiftNode();
3024 cmpN_reg_imm0Node *n_compare = cmpN_reg_imm0Node();
3025
3026 n_compare->add_req(n_region, n_src);
3027 n_compare->_opnds[0] = op_crx;
3028 n_compare->_opnds[1] = op_src;
3029 n_compare->_opnds[2] = immN_0Oper(TypeNarrowOop::NULL_PTR);
3030
3031 n_shift->add_req(n_region, n_src);
3032 n_shift->_opnds[0] = op_dst;
3033 n_shift->_opnds[1] = op_src;
3034 n_shift->_bottom_type = _bottom_type;
3035
3036 if (VM_Version::has_isel()) {
3037 // use isel instruction with Power 7
3038
3039 decodeN_addNode *n_add_base = decodeN_addNode();
3040 n_add_base->add_req(n_region, n_shift);
3041 n_add_base->_opnds[0] = op_dst;
3042 n_add_base->_opnds[1] = op_dst;
3043 n_add_base->_bottom_type = _bottom_type;
3044
3045 cond_set_0_ptrNode *n_cond_set = cond_set_0_ptrNode();
3046 n_cond_set->add_req(n_region, n_compare, n_add_base);
3047 n_cond_set->_opnds[0] = op_dst;
3048 n_cond_set->_opnds[1] = op_crx;
3049 n_cond_set->_opnds[2] = op_dst;
3050 n_cond_set->_bottom_type = _bottom_type;
3051
3052 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3053 ra_->set_oop(n_cond_set, true);
3054
3055 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3056 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3057 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3058 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3059
3060 nodes->push(n_compare);
3061 nodes->push(n_shift);
3062 nodes->push(n_add_base);
3063 nodes->push(n_cond_set);
3064
3065 } else {
3066 // before Power 7
3067 cond_add_baseNode *n_add_base = cond_add_baseNode();
3068
3069 n_add_base->add_req(n_region, n_compare, n_shift);
3070 n_add_base->_opnds[0] = op_dst;
3071 n_add_base->_opnds[1] = op_crx;
3072 n_add_base->_opnds[2] = op_dst;
3073 n_add_base->_bottom_type = _bottom_type;
3074
3075 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3076 ra_->set_oop(n_add_base, true);
3077
3078 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3079 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3080 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3081
3082 nodes->push(n_compare);
3083 nodes->push(n_shift);
3084 nodes->push(n_add_base);
3085 }
3086 %}
3087
3088 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3089 decodeN_shiftNode *n1 = decodeN_shiftNode();
3090 n1->add_req(n_region, n_src);
3091 n1->_opnds[0] = op_dst;
3092 n1->_opnds[1] = op_src;
3093 n1->_bottom_type = _bottom_type;
3094
3095 decodeN_addNode *n2 = decodeN_addNode();
3096 n2->add_req(n_region, n1);
3097 n2->_opnds[0] = op_dst;
3098 n2->_opnds[1] = op_dst;
3099 n2->_bottom_type = _bottom_type;
3100 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3101 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3102
3103 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3104 ra_->set_oop(n2, true);
3105
3106 nodes->push(n1);
3107 nodes->push(n2);
3108 %}
3109
3110 enc_class enc_cmove_reg(iRegIdst dst, flagsReg crx, iRegIsrc src, cmpOp cmp) %{
3111 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3112
3113 MacroAssembler _masm(&cbuf);
3114 int cc = $cmp$$cmpcode;
3115 int flags_reg = $crx$$reg;
3371 cc_to_biint(cc, flags_reg),
3372 l,
3373 MacroAssembler::bc_far_optimize_on_relocate);
3374 } else {
3375 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3376 cc_to_biint(cc, flags_reg),
3377 l);
3378 }
3379 #endif
3380 Unimplemented();
3381 %}
3382
3383 // Postalloc expand emitter for loading a replicatef float constant from
3384 // the method's TOC.
3385 // Enc_class needed as consttanttablebase is not supported by postalloc
3386 // expand.
3387 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3388 // Create new nodes.
3389
3390 // Make an operand with the bit pattern to load as float.
3391 immLOper *op_repl = immLOper((jlong)replicate_immF(op_src->constantF()));
3392
3393 loadConLNodesTuple loadConLNodes =
3394 loadConLNodesTuple_create(C, ra_, n_toc, op_repl,
3395 ra_->get_reg_second(this), ra_->get_reg_first(this));
3396
3397 // Push new nodes.
3398 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3399 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3400
3401 assert(nodes->length() >= 1, "must have created at least 1 node");
3402 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3403 %}
3404
3405 // This enc_class is needed so that scheduler gets proper
3406 // input mapping for latency computation.
3407 enc_class enc_poll(immI dst, iRegLdst poll) %{
3408 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
3409 // Fake operand dst needed for PPC scheduler.
3410 assert($dst$$constant == 0x0, "dst must be 0x0");
3411
3594 ? _load_ic_hi_node->_cbuf_insts_offset
3595 : _load_ic_node->_cbuf_insts_offset;
3596 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3597 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3598 "should be load from TOC");
3599
3600 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr));
3601 }
3602
3603 // At this point I do not have the address of the trampoline stub,
3604 // and the entry point might be too far away for bl. Pc() serves
3605 // as dummy and bl will be patched later.
3606 __ bl((address) __ pc());
3607 %}
3608
3609 // postalloc expand emitter for virtual calls.
3610 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3611
3612 // Create the nodes for loading the IC from the TOC.
3613 loadConLNodesTuple loadConLNodes_IC =
3614 loadConLNodesTuple_create(C, ra_, n_toc, immLOper((jlong)Universe::non_oop_word()),
3615 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3616
3617 // Create the call node.
3618 CallDynamicJavaDirectSchedNode *call = CallDynamicJavaDirectSchedNode();
3619 call->_method_handle_invoke = _method_handle_invoke;
3620 call->_vtable_index = _vtable_index;
3621 call->_method = _method;
3622 call->_bci = _bci;
3623 call->_optimized_virtual = _optimized_virtual;
3624 call->_tf = _tf;
3625 call->_entry_point = _entry_point;
3626 call->_cnt = _cnt;
3627 call->_argsize = _argsize;
3628 call->_oop_map = _oop_map;
3629 call->_jvms = _jvms;
3630 call->_jvmadj = _jvmadj;
3631 call->_in_rms = _in_rms;
3632 call->_nesting = _nesting;
3633
3634 // New call needs all inputs of old call.
3635 // Req...
3636 for (uint i = 0; i < req(); ++i) {
3637 // The expanded node does not need toc any more.
3638 // Add the inline cache constant here instead. This expresses the
3748 // Check the ret_addr_offset.
3749 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3750 "Fix constant in ret_addr_offset()");
3751 %}
3752
3753 // Move to ctr for leaf call.
3754 // This enc_class is needed so that scheduler gets proper
3755 // input mapping for latency computation.
3756 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3757 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3758 MacroAssembler _masm(&cbuf);
3759 __ mtctr($src$$Register);
3760 %}
3761
3762 // Postalloc expand emitter for runtime leaf calls.
3763 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3764 loadConLNodesTuple loadConLNodes_Entry;
3765 #if defined(ABI_ELFv2)
3766 jlong entry_address = (jlong) this->entry_point();
3767 assert(entry_address, "need address here");
3768 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, immLOper(entry_address),
3769 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3770 #else
3771 // Get the struct that describes the function we are about to call.
3772 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3773 assert(fd, "need fd here");
3774 jlong entry_address = (jlong) fd->entry();
3775 // new nodes
3776 loadConLNodesTuple loadConLNodes_Env;
3777 loadConLNodesTuple loadConLNodes_Toc;
3778
3779 // Create nodes and operands for loading the entry point.
3780 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, immLOper(entry_address),
3781 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3782
3783
3784 // Create nodes and operands for loading the env pointer.
3785 if (fd->env() != NULL) {
3786 loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, immLOper((jlong) fd->env()),
3787 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3788 } else {
3789 loadConLNodes_Env._large_hi = NULL;
3790 loadConLNodes_Env._large_lo = NULL;
3791 loadConLNodes_Env._small = NULL;
3792 loadConLNodes_Env._last = loadConL16Node();
3793 loadConLNodes_Env._last->_opnds[0] = iRegLdstOper();
3794 loadConLNodes_Env._last->_opnds[1] = immL16Oper(0);
3795 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3796 }
3797
3798 // Create nodes and operands for loading the Toc point.
3799 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, immLOper((jlong) fd->toc()),
3800 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3801 #endif // ABI_ELFv2
3802 // mtctr node
3803 MachNode *mtctr = CallLeafDirect_mtctrNode();
3804
3805 assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3806 mtctr->add_req(0, loadConLNodes_Entry._last);
3807
3808 mtctr->_opnds[0] = iRegLdstOper();
3809 mtctr->_opnds[1] = iRegLdstOper();
3810
3811 // call node
3812 MachCallLeafNode *call = CallLeafDirectNode();
3813
3814 call->_opnds[0] = _opnds[0];
3815 call->_opnds[1] = methodOper((intptr_t) entry_address); // May get set later.
3816
3817 // Make the new call node look like the old one.
3818 call->_name = _name;
3819 call->_tf = _tf;
3820 call->_entry_point = _entry_point;
3821 call->_cnt = _cnt;
3822 call->_argsize = _argsize;
3823 call->_oop_map = _oop_map;
3824 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3825 call->_jvms = NULL;
3826 call->_jvmadj = _jvmadj;
3827 call->_in_rms = _in_rms;
3828 call->_nesting = _nesting;
3829
3830
3831 // New call needs all inputs of old call.
3832 // Req...
3833 for (uint i = 0; i < req(); ++i) {
3834 if (i != mach_constant_base_node_input()) {
3835 call->add_req(in(i));
6033 predicate(false);
6034
6035 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
6036 size(4);
6037 ins_encode %{
6038 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6039 __ clrldi($dst$$Register, $src$$Register, 0x20);
6040 %}
6041 ins_pipe(pipe_class_default);
6042 %}
6043
6044 // Loading ConN must be postalloc expanded so that edges between
6045 // the nodes are safe. They may not interfere with a safepoint.
6046 // GL TODO: This needs three instructions: better put this into the constant pool.
6047 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6048 match(Set dst src);
6049 ins_cost(DEFAULT_COST*2);
6050
6051 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6052 postalloc_expand %{
6053 MachNode *m1 = loadConN_hiNode();
6054 MachNode *m2 = loadConN_loNode();
6055 MachNode *m3 = clearMs32bNode();
6056 m1->add_req(NULL);
6057 m2->add_req(NULL, m1);
6058 m3->add_req(NULL, m2);
6059 m1->_opnds[0] = op_dst;
6060 m1->_opnds[1] = op_src;
6061 m2->_opnds[0] = op_dst;
6062 m2->_opnds[1] = op_dst;
6063 m2->_opnds[2] = op_src;
6064 m3->_opnds[0] = op_dst;
6065 m3->_opnds[1] = op_dst;
6066 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6067 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6068 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6069 nodes->push(m1);
6070 nodes->push(m2);
6071 nodes->push(m3);
6072 %}
6073 %}
6074
6075 instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{
6100 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant);
6101 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
6102 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
6103 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6104
6105 __ relocate(rspec, 1);
6106 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6107 %}
6108 ins_pipe(pipe_class_default);
6109 %}
6110
6111 // Loading ConNKlass must be postalloc expanded so that edges between
6112 // the nodes are safe. They may not interfere with a safepoint.
6113 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6114 match(Set dst src);
6115 ins_cost(DEFAULT_COST*2);
6116
6117 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6118 postalloc_expand %{
6119 // Load high bits into register. Sign extended.
6120 MachNode *m1 = loadConNKlass_hiNode();
6121 m1->add_req(NULL);
6122 m1->_opnds[0] = op_dst;
6123 m1->_opnds[1] = op_src;
6124 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6125 nodes->push(m1);
6126
6127 MachNode *m2 = m1;
6128 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) {
6129 // Value might be 1-extended. Mask out these bits.
6130 m2 = clearMs32bNode();
6131 m2->add_req(NULL, m1);
6132 m2->_opnds[0] = op_dst;
6133 m2->_opnds[1] = op_dst;
6134 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6135 nodes->push(m2);
6136 }
6137
6138 MachNode *m3 = loadConNKlass_loNode();
6139 m3->add_req(NULL, m2);
6140 m3->_opnds[0] = op_dst;
6141 m3->_opnds[1] = op_src;
6142 m3->_opnds[2] = op_dst;
6143 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6144 nodes->push(m3);
6145 %}
6146 %}
6147
6148 // 0x1 is used in object initialization (initial object header).
6149 // No constant pool entries required.
6150 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6151 match(Set dst src);
6152
6153 format %{ "LI $dst, $src \t// ptr" %}
6154 size(4);
6155 ins_encode %{
6156 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
6157 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6158 %}
6970 instruct encodePKlass_32GAligned(iRegNdst dst, iRegPsrc src) %{
6971 match(Set dst (EncodePKlass src));
6972 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
6973
6974 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
6975 size(4);
6976 ins_encode %{
6977 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6978 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
6979 %}
6980 ins_pipe(pipe_class_default);
6981 %}
6982
6983 // shift != 0, base != 0
6984 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6985 match(Set dst (EncodePKlass (Binary base src)));
6986 predicate(false);
6987
6988 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6989 postalloc_expand %{
6990 encodePKlass_sub_baseNode *n1 = encodePKlass_sub_baseNode();
6991 n1->add_req(n_region, n_base, n_src);
6992 n1->_opnds[0] = op_dst;
6993 n1->_opnds[1] = op_base;
6994 n1->_opnds[2] = op_src;
6995 n1->_bottom_type = _bottom_type;
6996
6997 encodePKlass_shiftNode *n2 = encodePKlass_shiftNode();
6998 n2->add_req(n_region, n1);
6999 n2->_opnds[0] = op_dst;
7000 n2->_opnds[1] = op_dst;
7001 n2->_bottom_type = _bottom_type;
7002 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7003 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7004
7005 nodes->push(n1);
7006 nodes->push(n2);
7007 %}
7008 %}
7009
7010 // shift != 0, base != 0
7011 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
7012 match(Set dst (EncodePKlass src));
7013 //predicate(Universe::narrow_klass_shift() != 0 &&
7014 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/);
7015
7016 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7017 ins_cost(DEFAULT_COST*2); // Don't count constant.
7047 match(Set dst (DecodeNKlass (Binary base src)));
7048 predicate(false);
7049
7050 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
7051 size(4);
7052 ins_encode %{
7053 // TODO: PPC port $archOpcode(ppc64Opcode_add);
7054 __ add($dst$$Register, $base$$Register, $src$$Register);
7055 %}
7056 ins_pipe(pipe_class_default);
7057 %}
7058
7059 // src != 0, shift != 0, base != 0
7060 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
7061 match(Set dst (DecodeNKlass (Binary base src)));
7062 //effect(kill src); // We need a register for the immediate result after shifting.
7063 predicate(false);
7064
7065 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %}
7066 postalloc_expand %{
7067 decodeNKlass_add_baseNode *n1 = decodeNKlass_add_baseNode();
7068 n1->add_req(n_region, n_base, n_src);
7069 n1->_opnds[0] = op_dst;
7070 n1->_opnds[1] = op_base;
7071 n1->_opnds[2] = op_src;
7072 n1->_bottom_type = _bottom_type;
7073
7074 decodeNKlass_shiftNode *n2 = decodeNKlass_shiftNode();
7075 n2->add_req(n_region, n1);
7076 n2->_opnds[0] = op_dst;
7077 n2->_opnds[1] = op_dst;
7078 n2->_bottom_type = _bottom_type;
7079
7080 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7081 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7082
7083 nodes->push(n1);
7084 nodes->push(n2);
7085 %}
7086 %}
7087
7088 // src != 0, shift != 0, base != 0
7089 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
7090 match(Set dst (DecodeNKlass src));
7091 // predicate(Universe::narrow_klass_shift() != 0 &&
7092 // Universe::narrow_klass_base() != 0);
7093
7094 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %}
9756 postalloc_expand %{
9757 //
9758 // replaces
9759 //
9760 // region dst crx mem
9761 // \ | | /
9762 // dst=cmovI_bso_stackSlotL_conLvalue0
9763 //
9764 // with
9765 //
9766 // region dst
9767 // \ /
9768 // dst=loadConI16(0)
9769 // |
9770 // ^ region dst crx mem
9771 // | \ | | /
9772 // dst=cmovI_bso_stackSlotL
9773 //
9774
9775 // Create new nodes.
9776 MachNode *m1 = loadConI16Node();
9777 MachNode *m2 = cmovI_bso_stackSlotLNode();
9778
9779 // inputs for new nodes
9780 m1->add_req(n_region);
9781 m2->add_req(n_region, n_crx, n_mem);
9782
9783 // precedences for new nodes
9784 m2->add_prec(m1);
9785
9786 // operands for new nodes
9787 m1->_opnds[0] = op_dst;
9788 m1->_opnds[1] = immI16Oper(0);
9789
9790 m2->_opnds[0] = op_dst;
9791 m2->_opnds[1] = op_crx;
9792 m2->_opnds[2] = op_mem;
9793
9794 // registers for new nodes
9795 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9796 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9797
9798 // Insert new nodes.
9799 nodes->push(m1);
9800 nodes->push(m2);
9801 %}
9802 %}
9803
9804 // Double to Int conversion, NaN is mapped to 0.
9805 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
9806 match(Set dst (ConvD2I src));
9807 ins_cost(DEFAULT_COST);
9808
9925 postalloc_expand %{
9926 //
9927 // replaces
9928 //
9929 // region dst crx mem
9930 // \ | | /
9931 // dst=cmovL_bso_stackSlotL_conLvalue0
9932 //
9933 // with
9934 //
9935 // region dst
9936 // \ /
9937 // dst=loadConL16(0)
9938 // |
9939 // ^ region dst crx mem
9940 // | \ | | /
9941 // dst=cmovL_bso_stackSlotL
9942 //
9943
9944 // Create new nodes.
9945 MachNode *m1 = loadConL16Node();
9946 MachNode *m2 = cmovL_bso_stackSlotLNode();
9947
9948 // inputs for new nodes
9949 m1->add_req(n_region);
9950 m2->add_req(n_region, n_crx, n_mem);
9951 m2->add_prec(m1);
9952
9953 // operands for new nodes
9954 m1->_opnds[0] = op_dst;
9955 m1->_opnds[1] = immL16Oper(0);
9956 m2->_opnds[0] = op_dst;
9957 m2->_opnds[1] = op_crx;
9958 m2->_opnds[2] = op_mem;
9959
9960 // registers for new nodes
9961 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9962 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
9963
9964 // Insert new nodes.
9965 nodes->push(m1);
9966 nodes->push(m2);
9967 %}
9968 %}
9969
9970 // Float to Long conversion, NaN is mapped to 0.
9971 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
9972 match(Set dst (ConvF2L src));
9973 ins_cost(DEFAULT_COST);
9974
9975 expand %{
10271 postalloc_expand %{
10272 //
10273 // replaces
10274 //
10275 // region crx
10276 // \ |
10277 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1
10278 //
10279 // with
10280 //
10281 // region
10282 // \
10283 // dst=loadConI16(0)
10284 // |
10285 // ^ region crx
10286 // | \ |
10287 // dst=cmovI_conIvalueMinus1_conIvalue1
10288 //
10289
10290 // Create new nodes.
10291 MachNode *m1 = loadConI16Node();
10292 MachNode *m2 = cmovI_conIvalueMinus1_conIvalue1Node();
10293
10294 // inputs for new nodes
10295 m1->add_req(n_region);
10296 m2->add_req(n_region, n_crx);
10297 m2->add_prec(m1);
10298
10299 // operands for new nodes
10300 m1->_opnds[0] = op_dst;
10301 m1->_opnds[1] = immI16Oper(0);
10302 m2->_opnds[0] = op_dst;
10303 m2->_opnds[1] = op_crx;
10304
10305 // registers for new nodes
10306 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10307 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10308
10309 // Insert new nodes.
10310 nodes->push(m1);
10311 nodes->push(m2);
10312 %}
10313 %}
10314
10315 // Manifest a CmpL3 result in an integer register. Very painful.
10316 // This is the test to avoid.
10317 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
10318 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
10319 match(Set dst (CmpL3 src1 src2));
10320 ins_cost(DEFAULT_COST*5+BRANCH_COST);
10321
10606 postalloc_expand %{
10607 //
10608 // replaces
10609 //
10610 // region src1 src2
10611 // \ | |
10612 // crx=cmpF_reg_reg
10613 //
10614 // with
10615 //
10616 // region src1 src2
10617 // \ | |
10618 // crx=cmpFUnordered_reg_reg
10619 // |
10620 // ^ region
10621 // | \
10622 // crx=cmov_bns_less
10623 //
10624
10625 // Create new nodes.
10626 MachNode *m1 = new cmpFUnordered_reg_regNode();
10627 MachNode *m2 = new cmov_bns_lessNode();
10628
10629 // inputs for new nodes
10630 m1->add_req(n_region, n_src1, n_src2);
10631 m2->add_req(n_region);
10632 m2->add_prec(m1);
10633
10634 // operands for new nodes
10635 m1->_opnds[0] = op_crx;
10636 m1->_opnds[1] = op_src1;
10637 m1->_opnds[2] = op_src2;
10638 m2->_opnds[0] = op_crx;
10639
10640 // registers for new nodes
10641 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10642 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10643
10644 // Insert new nodes.
10645 nodes->push(m1);
10646 nodes->push(m2);
10647 %}
10681 postalloc_expand %{
10682 //
10683 // replaces
10684 //
10685 // region src1 src2
10686 // \ | |
10687 // crx=cmpD_reg_reg
10688 //
10689 // with
10690 //
10691 // region src1 src2
10692 // \ | |
10693 // crx=cmpDUnordered_reg_reg
10694 // |
10695 // ^ region
10696 // | \
10697 // crx=cmov_bns_less
10698 //
10699
10700 // create new nodes
10701 MachNode *m1 = new cmpDUnordered_reg_regNode();
10702 MachNode *m2 = new cmov_bns_lessNode();
10703
10704 // inputs for new nodes
10705 m1->add_req(n_region, n_src1, n_src2);
10706 m2->add_req(n_region);
10707 m2->add_prec(m1);
10708
10709 // operands for new nodes
10710 m1->_opnds[0] = op_crx;
10711 m1->_opnds[1] = op_src1;
10712 m1->_opnds[2] = op_src2;
10713 m2->_opnds[0] = op_crx;
10714
10715 // registers for new nodes
10716 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10717 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10718
10719 // Insert new nodes.
10720 nodes->push(m1);
10721 nodes->push(m2);
10722 %}
|