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