Mercurial > hg > graal-jvmci-8
comparison src/cpu/ppc/vm/ppc.ad @ 17917:63c5920a038d
8042309: Some bugfixes for the ppc64 port.
Reviewed-by: kvn
author | goetz |
---|---|
date | Fri, 02 May 2014 14:53:06 +0200 |
parents | 3a55cf1e3c9f |
children | 0bf37f737702 |
comparison
equal
deleted
inserted
replaced
17916:34862ced4a87 | 17917:63c5920a038d |
---|---|
896 // the ad-scope can conveniently be defined here. | 896 // the ad-scope can conveniently be defined here. |
897 // | 897 // |
898 // To keep related declarations/definitions/uses close together, | 898 // To keep related declarations/definitions/uses close together, |
899 // we switch between source %{ }% and source_hpp %{ }% freely as needed. | 899 // we switch between source %{ }% and source_hpp %{ }% freely as needed. |
900 | 900 |
901 // Returns true if Node n is followed by a MemBar node that | 901 // Returns true if Node n is followed by a MemBar node that |
902 // will do an acquire. If so, this node must not do the acquire | 902 // will do an acquire. If so, this node must not do the acquire |
903 // operation. | 903 // operation. |
904 bool followed_by_acquire(const Node *n); | 904 bool followed_by_acquire(const Node *n); |
905 %} | 905 %} |
906 | 906 |
907 source %{ | 907 source %{ |
908 | 908 |
909 // Optimize load-acquire. | 909 // Optimize load-acquire. |
910 // | 910 // |
911 // Check if acquire is unnecessary due to following operation that does | 911 // Check if acquire is unnecessary due to following operation that does |
912 // acquire anyways. | 912 // acquire anyways. |
913 // Walk the pattern: | 913 // Walk the pattern: |
914 // | 914 // |
915 // n: Load.acq | 915 // n: Load.acq |
916 // | | 916 // | |
917 // MemBarAcquire | 917 // MemBarAcquire |
918 // | | | 918 // | | |
919 // Proj(ctrl) Proj(mem) | 919 // Proj(ctrl) Proj(mem) |
920 // | | | 920 // | | |
921 // MemBarRelease/Volatile | 921 // MemBarRelease/Volatile |
922 // | 922 // |
923 bool followed_by_acquire(const Node *load) { | 923 bool followed_by_acquire(const Node *load) { |
924 assert(load->is_Load(), "So far implemented only for loads."); | 924 assert(load->is_Load(), "So far implemented only for loads."); |
925 | 925 |
926 // Find MemBarAcquire. | 926 // Find MemBarAcquire. |
927 const Node *mba = NULL; | 927 const Node *mba = NULL; |
928 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { | 928 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { |
929 const Node *out = load->fast_out(i); | 929 const Node *out = load->fast_out(i); |
930 if (out->Opcode() == Op_MemBarAcquire) { | 930 if (out->Opcode() == Op_MemBarAcquire) { |
931 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. | 931 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. |
932 mba = out; | 932 mba = out; |
935 } | 935 } |
936 if (!mba) return false; | 936 if (!mba) return false; |
937 | 937 |
938 // Find following MemBar node. | 938 // Find following MemBar node. |
939 // | 939 // |
940 // The following node must be reachable by control AND memory | 940 // The following node must be reachable by control AND memory |
941 // edge to assure no other operations are in between the two nodes. | 941 // edge to assure no other operations are in between the two nodes. |
942 // | 942 // |
943 // So first get the Proj node, mem_proj, to use it to iterate forward. | 943 // So first get the Proj node, mem_proj, to use it to iterate forward. |
944 Node *mem_proj = NULL; | 944 Node *mem_proj = NULL; |
945 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { | 945 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { |
1133 | 1133 |
1134 class CallStubImpl { | 1134 class CallStubImpl { |
1135 | 1135 |
1136 public: | 1136 public: |
1137 | 1137 |
1138 // Emit call stub, compiled java to interpreter. | |
1138 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); | 1139 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); |
1139 | 1140 |
1140 // Size of call trampoline stub. | 1141 // Size of call trampoline stub. |
1141 // This doesn't need to be accurate to the byte, but it | 1142 // This doesn't need to be accurate to the byte, but it |
1142 // must be larger than or equal to the real size of the stub. | 1143 // must be larger than or equal to the real size of the stub. |
2750 loadConP_loNode *m2 = new (C) loadConP_loNode(); | 2751 loadConP_loNode *m2 = new (C) loadConP_loNode(); |
2751 | 2752 |
2752 // inputs for new nodes | 2753 // inputs for new nodes |
2753 m1->add_req(NULL, n_toc); | 2754 m1->add_req(NULL, n_toc); |
2754 m2->add_req(NULL, m1); | 2755 m2->add_req(NULL, m1); |
2755 | 2756 |
2756 // operands for new nodes | 2757 // operands for new nodes |
2757 m1->_opnds[0] = new (C) iRegPdstOper(); // dst | 2758 m1->_opnds[0] = new (C) iRegPdstOper(); // dst |
2758 m1->_opnds[1] = op_src; // src | 2759 m1->_opnds[1] = op_src; // src |
2759 m1->_opnds[2] = new (C) iRegPdstOper(); // toc | 2760 m1->_opnds[2] = new (C) iRegPdstOper(); // toc |
2760 m2->_opnds[0] = new (C) iRegPdstOper(); // dst | 2761 m2->_opnds[0] = new (C) iRegPdstOper(); // dst |
2761 m2->_opnds[1] = op_src; // src | 2762 m2->_opnds[1] = op_src; // src |
2762 m2->_opnds[2] = new (C) iRegLdstOper(); // base | 2763 m2->_opnds[2] = new (C) iRegLdstOper(); // base |
2763 | 2764 |
2764 // Initialize ins_attrib TOC fields. | 2765 // Initialize ins_attrib TOC fields. |
2765 m1->_const_toc_offset = -1; | 2766 m1->_const_toc_offset = -1; |
2766 m2->_const_toc_offset_hi_node = m1; | 2767 m2->_const_toc_offset_hi_node = m1; |
2767 | 2768 |
2768 // Register allocation for new nodes. | 2769 // Register allocation for new nodes. |
2769 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2770 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2770 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2771 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2771 | 2772 |
2772 nodes->push(m1); | 2773 nodes->push(m1); |
2773 nodes->push(m2); | 2774 nodes->push(m2); |
2774 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); | 2775 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); |
2775 } else { | 2776 } else { |
2776 loadConPNode *m2 = new (C) loadConPNode(); | 2777 loadConPNode *m2 = new (C) loadConPNode(); |
2777 | 2778 |
2778 // inputs for new nodes | 2779 // inputs for new nodes |
2779 m2->add_req(NULL, n_toc); | 2780 m2->add_req(NULL, n_toc); |
2780 | 2781 |
2781 // operands for new nodes | 2782 // operands for new nodes |
2782 m2->_opnds[0] = new (C) iRegPdstOper(); // dst | 2783 m2->_opnds[0] = new (C) iRegPdstOper(); // dst |
2783 m2->_opnds[1] = op_src; // src | 2784 m2->_opnds[1] = op_src; // src |
2784 m2->_opnds[2] = new (C) iRegPdstOper(); // toc | 2785 m2->_opnds[2] = new (C) iRegPdstOper(); // toc |
2785 | 2786 |
2786 // Register allocation for new nodes. | 2787 // Register allocation for new nodes. |
2787 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2788 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2788 | 2789 |
2789 nodes->push(m2); | 2790 nodes->push(m2); |
2790 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); | 2791 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); |
2972 n_sub_base->add_req(n_region, n_compare, n_src); | 2973 n_sub_base->add_req(n_region, n_compare, n_src); |
2973 n_sub_base->_opnds[0] = op_dst; | 2974 n_sub_base->_opnds[0] = op_dst; |
2974 n_sub_base->_opnds[1] = op_crx; | 2975 n_sub_base->_opnds[1] = op_crx; |
2975 n_sub_base->_opnds[2] = op_src; | 2976 n_sub_base->_opnds[2] = op_src; |
2976 n_sub_base->_bottom_type = _bottom_type; | 2977 n_sub_base->_bottom_type = _bottom_type; |
2977 | 2978 |
2978 n_shift->add_req(n_region, n_sub_base); | 2979 n_shift->add_req(n_region, n_sub_base); |
2979 n_shift->_opnds[0] = op_dst; | 2980 n_shift->_opnds[0] = op_dst; |
2980 n_shift->_opnds[1] = op_dst; | 2981 n_shift->_opnds[1] = op_dst; |
2981 n_shift->_bottom_type = _bottom_type; | 2982 n_shift->_bottom_type = _bottom_type; |
2982 | 2983 |
2983 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2984 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2984 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); | 2985 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); |
2985 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2986 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2986 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 2987 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
2987 | 2988 |
2988 nodes->push(n_move); | 2989 nodes->push(n_move); |
2989 nodes->push(n_compare); | 2990 nodes->push(n_compare); |
2990 nodes->push(n_sub_base); | 2991 nodes->push(n_sub_base); |
2991 nodes->push(n_shift); | 2992 nodes->push(n_shift); |
2992 } | 2993 } |
3059 nodes->push(n_cond_set); | 3060 nodes->push(n_cond_set); |
3060 | 3061 |
3061 } else { | 3062 } else { |
3062 // before Power 7 | 3063 // before Power 7 |
3063 cond_add_baseNode *n_add_base = new (C) cond_add_baseNode(); | 3064 cond_add_baseNode *n_add_base = new (C) cond_add_baseNode(); |
3064 | 3065 |
3065 n_add_base->add_req(n_region, n_compare, n_shift); | 3066 n_add_base->add_req(n_region, n_compare, n_shift); |
3066 n_add_base->_opnds[0] = op_dst; | 3067 n_add_base->_opnds[0] = op_dst; |
3067 n_add_base->_opnds[1] = op_crx; | 3068 n_add_base->_opnds[1] = op_crx; |
3068 n_add_base->_opnds[2] = op_dst; | 3069 n_add_base->_opnds[2] = op_dst; |
3069 n_add_base->_bottom_type = _bottom_type; | 3070 n_add_base->_bottom_type = _bottom_type; |
3070 | 3071 |
3071 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); | 3072 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); |
3072 ra_->set_oop(n_add_base, true); | 3073 ra_->set_oop(n_add_base, true); |
3073 | 3074 |
3074 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 3075 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
3075 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); | 3076 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); |
3076 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 3077 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
3077 | 3078 |
3078 nodes->push(n_compare); | 3079 nodes->push(n_compare); |
3079 nodes->push(n_shift); | 3080 nodes->push(n_shift); |
3080 nodes->push(n_add_base); | 3081 nodes->push(n_add_base); |
3081 } | 3082 } |
3082 %} | 3083 %} |
3629 | 3630 |
3630 // New call needs all inputs of old call. | 3631 // New call needs all inputs of old call. |
3631 // Req... | 3632 // Req... |
3632 for (uint i = 0; i < req(); ++i) { | 3633 for (uint i = 0; i < req(); ++i) { |
3633 // The expanded node does not need toc any more. | 3634 // The expanded node does not need toc any more. |
3634 // Add the inline cache constant here instead. This expresses the | 3635 // Add the inline cache constant here instead. This expresses the |
3635 // register of the inline cache must be live at the call. | 3636 // register of the inline cache must be live at the call. |
3636 // Else we would have to adapt JVMState by -1. | 3637 // Else we would have to adapt JVMState by -1. |
3637 if (i == mach_constant_base_node_input()) { | 3638 if (i == mach_constant_base_node_input()) { |
3638 call->add_req(loadConLNodes_IC._last); | 3639 call->add_req(loadConLNodes_IC._last); |
3639 } else { | 3640 } else { |
3640 call->add_req(in(i)); | 3641 call->add_req(in(i)); |
3641 } | 3642 } |
3642 } | 3643 } |
3643 // ...as well as prec | 3644 // ...as well as prec |
3661 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); | 3662 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); |
3662 nodes->push(call); | 3663 nodes->push(call); |
3663 %} | 3664 %} |
3664 | 3665 |
3665 // Compound version of call dynamic | 3666 // Compound version of call dynamic |
3667 // Toc is only passed so that it can be used in ins_encode statement. | |
3668 // In the code we have to use $constanttablebase. | |
3666 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ | 3669 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ |
3667 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 3670 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
3668 MacroAssembler _masm(&cbuf); | 3671 MacroAssembler _masm(&cbuf); |
3669 int start_offset = __ offset(); | 3672 int start_offset = __ offset(); |
3670 | 3673 |
3671 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; | 3674 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; |
3672 #if 0 | 3675 #if 0 |
3676 int vtable_index = this->_vtable_index; | |
3673 if (_vtable_index < 0) { | 3677 if (_vtable_index < 0) { |
3674 // Must be invalid_vtable_index, not nonvirtual_vtable_index. | 3678 // Must be invalid_vtable_index, not nonvirtual_vtable_index. |
3675 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); | 3679 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); |
3676 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); | 3680 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); |
3677 AddressLiteral meta = __ allocate_metadata_address((Metadata *)Universe::non_oop_word()); | 3681 |
3678 | 3682 // Virtual call relocation will point to ic load. |
3679 address virtual_call_meta_addr = __ pc(); | 3683 address virtual_call_meta_addr = __ pc(); |
3680 __ load_const_from_method_toc(ic_reg, meta, Rtoc); | 3684 // Load a clear inline cache. |
3685 AddressLiteral empty_ic((address) Universe::non_oop_word()); | |
3686 __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc); | |
3681 // CALL to fixup routine. Fixup routine uses ScopeDesc info | 3687 // CALL to fixup routine. Fixup routine uses ScopeDesc info |
3682 // to determine who we intended to call. | 3688 // to determine who we intended to call. |
3683 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); | 3689 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); |
3684 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); | 3690 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); |
3685 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, | 3691 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, |
3708 } | 3714 } |
3709 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, | 3715 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, |
3710 "Fix constant in ret_addr_offset()"); | 3716 "Fix constant in ret_addr_offset()"); |
3711 } | 3717 } |
3712 #endif | 3718 #endif |
3713 guarantee(0, "Fix handling of toc edge: messes up derived/base pairs."); | |
3714 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). | 3719 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). |
3715 %} | 3720 %} |
3716 | 3721 |
3717 // a runtime call | 3722 // a runtime call |
3718 enc_class enc_java_to_runtime_call (method meth) %{ | 3723 enc_class enc_java_to_runtime_call (method meth) %{ |
5434 size(12); | 5439 size(12); |
5435 ins_encode( enc_lwz_ac(dst, mem) ); | 5440 ins_encode( enc_lwz_ac(dst, mem) ); |
5436 ins_pipe(pipe_class_memory); | 5441 ins_pipe(pipe_class_memory); |
5437 %} | 5442 %} |
5438 | 5443 |
5439 // Match loading integer and casting it to unsigned int in | 5444 // Match loading integer and casting it to unsigned int in |
5440 // long register. | 5445 // long register. |
5441 // LoadI + ConvI2L + AndL 0xffffffff. | 5446 // LoadI + ConvI2L + AndL 0xffffffff. |
5442 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ | 5447 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ |
5443 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); | 5448 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); |
5444 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); | 5449 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); |
6076 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); | 6081 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); |
6077 %} | 6082 %} |
6078 ins_pipe(pipe_class_default); | 6083 ins_pipe(pipe_class_default); |
6079 %} | 6084 %} |
6080 | 6085 |
6081 // This needs a match rule so that build_oop_map knows this is | 6086 // This needs a match rule so that build_oop_map knows this is |
6082 // not a narrow oop. | 6087 // not a narrow oop. |
6083 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ | 6088 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ |
6084 match(Set dst src1); | 6089 match(Set dst src1); |
6085 effect(TEMP src2); | 6090 effect(TEMP src2); |
6086 ins_cost(DEFAULT_COST); | 6091 ins_cost(DEFAULT_COST); |
6700 | 6705 |
6701 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} | 6706 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} |
6702 size(4); | 6707 size(4); |
6703 ins_encode %{ | 6708 ins_encode %{ |
6704 // This is a Power7 instruction for which no machine description exists. | 6709 // This is a Power7 instruction for which no machine description exists. |
6705 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 6710 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
6706 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); | 6711 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); |
6707 %} | 6712 %} |
6708 ins_pipe(pipe_class_default); | 6713 ins_pipe(pipe_class_default); |
6709 %} | 6714 %} |
6710 | 6715 |
6845 | 6850 |
6846 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} | 6851 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} |
6847 size(4); | 6852 size(4); |
6848 ins_encode %{ | 6853 ins_encode %{ |
6849 // This is a Power7 instruction for which no machine description exists. | 6854 // This is a Power7 instruction for which no machine description exists. |
6850 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 6855 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
6851 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); | 6856 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); |
6852 %} | 6857 %} |
6853 ins_pipe(pipe_class_default); | 6858 ins_pipe(pipe_class_default); |
6854 %} | 6859 %} |
6855 | 6860 |
7062 n1->_opnds[1] = op_base; | 7067 n1->_opnds[1] = op_base; |
7063 n1->_opnds[2] = op_src; | 7068 n1->_opnds[2] = op_src; |
7064 n1->_bottom_type = _bottom_type; | 7069 n1->_bottom_type = _bottom_type; |
7065 | 7070 |
7066 decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode(); | 7071 decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode(); |
7067 n2->add_req(n_region, n2); | 7072 n2->add_req(n_region, n1); |
7068 n2->_opnds[0] = op_dst; | 7073 n2->_opnds[0] = op_dst; |
7069 n2->_opnds[1] = op_dst; | 7074 n2->_opnds[1] = op_dst; |
7070 n2->_bottom_type = _bottom_type; | 7075 n2->_bottom_type = _bottom_type; |
7071 | 7076 |
7072 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 7077 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
7197 // Vladimir, this pattern can not occur on Oracle platforms. | 7202 // Vladimir, this pattern can not occur on Oracle platforms. |
7198 // However, it does occur on PPC64 (because of membars in | 7203 // However, it does occur on PPC64 (because of membars in |
7199 // inline_unsafe_load_store). | 7204 // inline_unsafe_load_store). |
7200 // | 7205 // |
7201 // Add this node again if we found a good solution for inline_unsafe_load_store(). | 7206 // Add this node again if we found a good solution for inline_unsafe_load_store(). |
7202 // Don't forget to look at the implementation of post_store_load_barrier again, | 7207 // Don't forget to look at the implementation of post_store_load_barrier again, |
7203 // we did other fixes in that method. | 7208 // we did other fixes in that method. |
7204 //instruct unnecessary_membar_volatile() %{ | 7209 //instruct unnecessary_membar_volatile() %{ |
7205 // match(MemBarVolatile); | 7210 // match(MemBarVolatile); |
7206 // predicate(Matcher::post_store_load_barrier(n)); | 7211 // predicate(Matcher::post_store_load_barrier(n)); |
7207 // ins_cost(0); | 7212 // ins_cost(0); |
7235 ins_encode %{ | 7240 ins_encode %{ |
7236 // This is a Power7 instruction for which no machine description | 7241 // This is a Power7 instruction for which no machine description |
7237 // exists. Anyways, the scheduler should be off on Power7. | 7242 // exists. Anyways, the scheduler should be off on Power7. |
7238 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 7243 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
7239 int cc = $cmp$$cmpcode; | 7244 int cc = $cmp$$cmpcode; |
7240 __ isel($dst$$Register, $crx$$CondRegister, | 7245 __ isel($dst$$Register, $crx$$CondRegister, |
7241 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); | 7246 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); |
7242 %} | 7247 %} |
7243 ins_pipe(pipe_class_default); | 7248 ins_pipe(pipe_class_default); |
7244 %} | 7249 %} |
7245 | 7250 |
7281 ins_encode %{ | 7286 ins_encode %{ |
7282 // This is a Power7 instruction for which no machine description | 7287 // This is a Power7 instruction for which no machine description |
7283 // exists. Anyways, the scheduler should be off on Power7. | 7288 // exists. Anyways, the scheduler should be off on Power7. |
7284 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 7289 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
7285 int cc = $cmp$$cmpcode; | 7290 int cc = $cmp$$cmpcode; |
7286 __ isel($dst$$Register, $crx$$CondRegister, | 7291 __ isel($dst$$Register, $crx$$CondRegister, |
7287 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); | 7292 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); |
7288 %} | 7293 %} |
7289 ins_pipe(pipe_class_default); | 7294 ins_pipe(pipe_class_default); |
7290 %} | 7295 %} |
7291 | 7296 |
7327 ins_encode %{ | 7332 ins_encode %{ |
7328 // This is a Power7 instruction for which no machine description | 7333 // This is a Power7 instruction for which no machine description |
7329 // exists. Anyways, the scheduler should be off on Power7. | 7334 // exists. Anyways, the scheduler should be off on Power7. |
7330 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 7335 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
7331 int cc = $cmp$$cmpcode; | 7336 int cc = $cmp$$cmpcode; |
7332 __ isel($dst$$Register, $crx$$CondRegister, | 7337 __ isel($dst$$Register, $crx$$CondRegister, |
7333 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); | 7338 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); |
7334 %} | 7339 %} |
7335 ins_pipe(pipe_class_default); | 7340 ins_pipe(pipe_class_default); |
7336 %} | 7341 %} |
7337 | 7342 |
7374 ins_encode %{ | 7379 ins_encode %{ |
7375 // This is a Power7 instruction for which no machine description | 7380 // This is a Power7 instruction for which no machine description |
7376 // exists. Anyways, the scheduler should be off on Power7. | 7381 // exists. Anyways, the scheduler should be off on Power7. |
7377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 7382 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
7378 int cc = $cmp$$cmpcode; | 7383 int cc = $cmp$$cmpcode; |
7379 __ isel($dst$$Register, $crx$$CondRegister, | 7384 __ isel($dst$$Register, $crx$$CondRegister, |
7380 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); | 7385 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); |
7381 %} | 7386 %} |
7382 ins_pipe(pipe_class_default); | 7387 ins_pipe(pipe_class_default); |
7383 %} | 7388 %} |
7384 | 7389 |
7520 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} | 7525 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} |
7521 // Variable size: instruction count smaller if regs are disjoint. | 7526 // Variable size: instruction count smaller if regs are disjoint. |
7522 ins_encode %{ | 7527 ins_encode %{ |
7523 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 7528 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. | 7529 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. |
7525 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, | 7530 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, |
7526 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), | 7531 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), |
7527 $res$$Register, true); | 7532 $res$$Register, true); |
7528 %} | 7533 %} |
7529 ins_pipe(pipe_class_default); | 7534 ins_pipe(pipe_class_default); |
7530 %} | 7535 %} |
7531 | 7536 |
7927 ins_pipe(pipe_class_default); | 7932 ins_pipe(pipe_class_default); |
7928 %} | 7933 %} |
7929 | 7934 |
7930 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for | 7935 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for |
7931 // positive longs and 0xF...F for negative ones. | 7936 // positive longs and 0xF...F for negative ones. |
7932 instruct signmask64I_regI(iRegIdst dst, iRegIsrc src) %{ | 7937 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ |
7938 // no match-rule, false predicate | |
7939 effect(DEF dst, USE src); | |
7940 predicate(false); | |
7941 | |
7942 format %{ "SRADI $dst, $src, #63" %} | |
7943 size(4); | |
7944 ins_encode %{ | |
7945 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); | |
7946 __ sradi($dst$$Register, $src$$Register, 0x3f); | |
7947 %} | |
7948 ins_pipe(pipe_class_default); | |
7949 %} | |
7950 | |
7951 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for | |
7952 // positive longs and 0xF...F for negative ones. | |
7953 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ | |
7933 // no match-rule, false predicate | 7954 // no match-rule, false predicate |
7934 effect(DEF dst, USE src); | 7955 effect(DEF dst, USE src); |
7935 predicate(false); | 7956 predicate(false); |
7936 | 7957 |
7937 format %{ "SRADI $dst, $src, #63" %} | 7958 format %{ "SRADI $dst, $src, #63" %} |
8891 predicate(UseRotateAndMaskInstructionsPPC64); | 8912 predicate(UseRotateAndMaskInstructionsPPC64); |
8892 format %{ "ANDWI $dst, $src1, $src2" %} | 8913 format %{ "ANDWI $dst, $src1, $src2" %} |
8893 size(4); | 8914 size(4); |
8894 ins_encode %{ | 8915 ins_encode %{ |
8895 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); | 8916 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); |
8896 __ rlwinm($dst$$Register, $src1$$Register, 0, | 8917 __ rlwinm($dst$$Register, $src1$$Register, 0, |
8897 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); | 8918 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); |
8898 %} | 8919 %} |
8899 ins_pipe(pipe_class_default); | 8920 ins_pipe(pipe_class_default); |
8900 %} | 8921 %} |
8901 | 8922 |
9617 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ | 9638 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ |
9618 match(Set dst (CmpLTMask src1 src2)); | 9639 match(Set dst (CmpLTMask src1 src2)); |
9619 ins_cost(DEFAULT_COST*4); | 9640 ins_cost(DEFAULT_COST*4); |
9620 | 9641 |
9621 expand %{ | 9642 expand %{ |
9622 iRegIdst src1s; | 9643 iRegLdst src1s; |
9623 iRegIdst src2s; | 9644 iRegLdst src2s; |
9624 iRegIdst diff; | 9645 iRegLdst diff; |
9625 sxtI_reg(src1s, src1); // ensure proper sign extention | 9646 convI2L_reg(src1s, src1); // Ensure proper sign extension. |
9626 sxtI_reg(src2s, src2); // ensure proper sign extention | 9647 convI2L_reg(src2s, src2); // Ensure proper sign extension. |
9627 subI_reg_reg(diff, src1s, src2s); | 9648 subL_reg_reg(diff, src1s, src2s); |
9628 // Need to consider >=33 bit result, therefore we need signmaskL. | 9649 // Need to consider >=33 bit result, therefore we need signmaskL. |
9629 signmask64I_regI(dst, diff); | 9650 signmask64I_regL(dst, diff); |
9630 %} | 9651 %} |
9631 %} | 9652 %} |
9632 | 9653 |
9633 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ | 9654 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ |
9634 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 | 9655 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 |
10861 ins_cost(DEFAULT_COST*10); | 10882 ins_cost(DEFAULT_COST*10); |
10862 | 10883 |
10863 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} | 10884 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} |
10864 ins_encode %{ | 10885 ins_encode %{ |
10865 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 10886 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
10866 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, | 10887 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, |
10867 $tmp_klass$$Register, NULL, $result$$Register); | 10888 $tmp_klass$$Register, NULL, $result$$Register); |
10868 %} | 10889 %} |
10869 ins_pipe(pipe_class_default); | 10890 ins_pipe(pipe_class_default); |
10870 %} | 10891 %} |
10871 | 10892 |
11176 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ | 11197 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ |
11177 match(Set dst (MinI src1 src2)); | 11198 match(Set dst (MinI src1 src2)); |
11178 ins_cost(DEFAULT_COST*6); | 11199 ins_cost(DEFAULT_COST*6); |
11179 | 11200 |
11180 expand %{ | 11201 expand %{ |
11181 iRegIdst src1s; | 11202 iRegLdst src1s; |
11182 iRegIdst src2s; | 11203 iRegLdst src2s; |
11183 iRegIdst diff; | 11204 iRegLdst diff; |
11184 iRegIdst sm; | 11205 iRegLdst sm; |
11185 iRegIdst doz; // difference or zero | 11206 iRegLdst doz; // difference or zero |
11186 sxtI_reg(src1s, src1); // Ensure proper sign extention. | 11207 convI2L_reg(src1s, src1); // Ensure proper sign extension. |
11187 sxtI_reg(src2s, src2); // Ensure proper sign extention. | 11208 convI2L_reg(src2s, src2); // Ensure proper sign extension. |
11188 subI_reg_reg(diff, src2s, src1s); | 11209 subL_reg_reg(diff, src2s, src1s); |
11189 // Need to consider >=33 bit result, therefore we need signmaskL. | 11210 // Need to consider >=33 bit result, therefore we need signmaskL. |
11190 signmask64I_regI(sm, diff); | 11211 signmask64L_regL(sm, diff); |
11191 andI_reg_reg(doz, diff, sm); // <=0 | 11212 andL_reg_reg(doz, diff, sm); // <=0 |
11192 addI_reg_reg(dst, doz, src1s); | 11213 addI_regL_regL(dst, doz, src1s); |
11193 %} | 11214 %} |
11194 %} | 11215 %} |
11195 | 11216 |
11196 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ | 11217 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ |
11197 match(Set dst (MaxI src1 src2)); | 11218 match(Set dst (MaxI src1 src2)); |
11198 ins_cost(DEFAULT_COST*6); | 11219 ins_cost(DEFAULT_COST*6); |
11199 | 11220 |
11200 expand %{ | 11221 expand %{ |
11201 immI_minus1 m1 %{ -1 %} | 11222 iRegLdst src1s; |
11202 iRegIdst src1s; | 11223 iRegLdst src2s; |
11203 iRegIdst src2s; | 11224 iRegLdst diff; |
11204 iRegIdst diff; | 11225 iRegLdst sm; |
11205 iRegIdst sm; | 11226 iRegLdst doz; // difference or zero |
11206 iRegIdst doz; // difference or zero | 11227 convI2L_reg(src1s, src1); // Ensure proper sign extension. |
11207 sxtI_reg(src1s, src1); // Ensure proper sign extention. | 11228 convI2L_reg(src2s, src2); // Ensure proper sign extension. |
11208 sxtI_reg(src2s, src2); // Ensure proper sign extention. | 11229 subL_reg_reg(diff, src2s, src1s); |
11209 subI_reg_reg(diff, src2s, src1s); | |
11210 // Need to consider >=33 bit result, therefore we need signmaskL. | 11230 // Need to consider >=33 bit result, therefore we need signmaskL. |
11211 signmask64I_regI(sm, diff); | 11231 signmask64L_regL(sm, diff); |
11212 andcI_reg_reg(doz, sm, m1, diff); // >=0 | 11232 andcL_reg_reg(doz, diff, sm); // >=0 |
11213 addI_reg_reg(dst, doz, src1s); | 11233 addI_regL_regL(dst, doz, src1s); |
11214 %} | 11234 %} |
11215 %} | 11235 %} |
11216 | 11236 |
11217 //---------- Population Count Instructions ------------------------------------ | 11237 //---------- Population Count Instructions ------------------------------------ |
11218 | 11238 |