comparison src/cpu/ppc/vm/ppc.ad @ 17803:31e80afe3fed

8035647: PPC64: Support for elf v2 abi. Summary: ELFv2 ABI used by the little endian PowerPC64 on Linux. Reviewed-by: kvn Contributed-by: asmundak@google.com
author goetz
date Thu, 06 Mar 2014 10:55:28 -0800
parents 7c462558a08a
children 71a71b0bc844
comparison
equal deleted inserted replaced
17802:7c462558a08a 17803:31e80afe3fed
1006 return 24; 1006 return 24;
1007 } 1007 }
1008 } 1008 }
1009 1009
1010 int MachCallRuntimeNode::ret_addr_offset() { 1010 int MachCallRuntimeNode::ret_addr_offset() {
1011 #if defined(ABI_ELFv2)
1012 return 28;
1013 #else
1011 return 40; 1014 return 40;
1015 #endif
1012 } 1016 }
1013 1017
1014 //============================================================================= 1018 //=============================================================================
1015 1019
1016 // condition code conversions 1020 // condition code conversions
3684 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3688 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3685 3689
3686 MacroAssembler _masm(&cbuf); 3690 MacroAssembler _masm(&cbuf);
3687 const address start_pc = __ pc(); 3691 const address start_pc = __ pc();
3688 3692
3693 #if defined(ABI_ELFv2)
3694 address entry= !($meth$$method) ? NULL : (address)$meth$$method;
3695 __ call_c(entry, relocInfo::runtime_call_type);
3696 #else
3689 // The function we're going to call. 3697 // The function we're going to call.
3690 FunctionDescriptor fdtemp; 3698 FunctionDescriptor fdtemp;
3691 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3699 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3692 3700
3693 Register Rtoc = R12_scratch2; 3701 Register Rtoc = R12_scratch2;
3694 // Calculate the method's TOC. 3702 // Calculate the method's TOC.
3695 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3703 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3696 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3704 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3697 // pool entries; call_c_using_toc will optimize the call. 3705 // pool entries; call_c_using_toc will optimize the call.
3698 __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3706 __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3707 #endif
3699 3708
3700 // Check the ret_addr_offset. 3709 // Check the ret_addr_offset.
3701 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3710 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3702 "Fix constant in ret_addr_offset()"); 3711 "Fix constant in ret_addr_offset()");
3703 %} 3712 %}
3709 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3718 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3710 MacroAssembler _masm(&cbuf); 3719 MacroAssembler _masm(&cbuf);
3711 __ mtctr($src$$Register); 3720 __ mtctr($src$$Register);
3712 %} 3721 %}
3713 3722
3714 // postalloc expand emitter for runtime leaf calls. 3723 // Postalloc expand emitter for runtime leaf calls.
3715 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3724 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3725 loadConLNodesTuple loadConLNodes_Entry;
3726 #if defined(ABI_ELFv2)
3727 jlong entry_address = (jlong) this->entry_point();
3728 assert(entry_address, "need address here");
3729 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
3730 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3731 #else
3716 // Get the struct that describes the function we are about to call. 3732 // Get the struct that describes the function we are about to call.
3717 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3733 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3718 assert(fd, "need fd here"); 3734 assert(fd, "need fd here");
3735 jlong entry_address = (jlong) fd->entry();
3719 // new nodes 3736 // new nodes
3720 loadConLNodesTuple loadConLNodes_Entry;
3721 loadConLNodesTuple loadConLNodes_Env; 3737 loadConLNodesTuple loadConLNodes_Env;
3722 loadConLNodesTuple loadConLNodes_Toc; 3738 loadConLNodesTuple loadConLNodes_Toc;
3723 MachNode *mtctr = NULL;
3724 MachCallLeafNode *call = NULL;
3725 3739
3726 // Create nodes and operands for loading the entry point. 3740 // Create nodes and operands for loading the entry point.
3727 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->entry()), 3741 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
3728 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3742 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3729 3743
3730 3744
3731 // Create nodes and operands for loading the env pointer. 3745 // Create nodes and operands for loading the env pointer.
3732 if (fd->env() != NULL) { 3746 if (fd->env() != NULL) {
3743 } 3757 }
3744 3758
3745 // Create nodes and operands for loading the Toc point. 3759 // Create nodes and operands for loading the Toc point.
3746 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()), 3760 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()),
3747 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3761 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3762 #endif // ABI_ELFv2
3748 // mtctr node 3763 // mtctr node
3749 mtctr = new (C) CallLeafDirect_mtctrNode(); 3764 MachNode *mtctr = new (C) CallLeafDirect_mtctrNode();
3750 3765
3751 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3766 assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3752 mtctr->add_req(0, loadConLNodes_Entry._last); 3767 mtctr->add_req(0, loadConLNodes_Entry._last);
3753 3768
3754 mtctr->_opnds[0] = new (C) iRegLdstOper(); 3769 mtctr->_opnds[0] = new (C) iRegLdstOper();
3755 mtctr->_opnds[1] = new (C) iRegLdstOper(); 3770 mtctr->_opnds[1] = new (C) iRegLdstOper();
3756 3771
3757 // call node 3772 // call node
3758 call = new (C) CallLeafDirectNode(); 3773 MachCallLeafNode *call = new (C) CallLeafDirectNode();
3759 3774
3760 call->_opnds[0] = _opnds[0]; 3775 call->_opnds[0] = _opnds[0];
3761 call->_opnds[1] = new (C) methodOper((intptr_t) fd->entry()); // may get set later 3776 call->_opnds[1] = new (C) methodOper((intptr_t) entry_address); // May get set later.
3762 3777
3763 // Make the new call node look like the old one. 3778 // Make the new call node look like the old one.
3764 call->_name = _name; 3779 call->_name = _name;
3765 call->_tf = _tf; 3780 call->_tf = _tf;
3766 call->_entry_point = _entry_point; 3781 call->_entry_point = _entry_point;
3783 } 3798 }
3784 3799
3785 // These must be reqired edges, as the registers are live up to 3800 // These must be reqired edges, as the registers are live up to
3786 // the call. Else the constants are handled as kills. 3801 // the call. Else the constants are handled as kills.
3787 call->add_req(mtctr); 3802 call->add_req(mtctr);
3803 #if !defined(ABI_ELFv2)
3788 call->add_req(loadConLNodes_Env._last); 3804 call->add_req(loadConLNodes_Env._last);
3789 call->add_req(loadConLNodes_Toc._last); 3805 call->add_req(loadConLNodes_Toc._last);
3806 #endif
3790 3807
3791 // ...as well as prec 3808 // ...as well as prec
3792 for (uint i = req(); i < len(); ++i) { 3809 for (uint i = req(); i < len(); ++i) {
3793 call->add_prec(in(i)); 3810 call->add_prec(in(i));
3794 } 3811 }
3797 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3814 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3798 3815
3799 // Insert the new nodes. 3816 // Insert the new nodes.
3800 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3817 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3801 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3818 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3819 #if !defined(ABI_ELFv2)
3802 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3820 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3803 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3821 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3804 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3822 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3805 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3823 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3824 #endif
3806 nodes->push(mtctr); 3825 nodes->push(mtctr);
3807 nodes->push(call); 3826 nodes->push(call);
3808 %} 3827 %}
3809 %} 3828 %}
3810 3829
3847 3866
3848 // Number of outgoing stack slots killed above the 3867 // Number of outgoing stack slots killed above the
3849 // out_preserve_stack_slots for calls to C. Supports the var-args 3868 // out_preserve_stack_slots for calls to C. Supports the var-args
3850 // backing area for register parms. 3869 // backing area for register parms.
3851 // 3870 //
3852 varargs_C_out_slots_killed(((frame::abi_112_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3871 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3853 3872
3854 // The after-PROLOG location of the return address. Location of 3873 // The after-PROLOG location of the return address. Location of
3855 // return address specifies a type (REG or STACK) and a number 3874 // return address specifies a type (REG or STACK) and a number
3856 // representing the register number (i.e. - use a register name) or 3875 // representing the register number (i.e. - use a register name) or
3857 // stack slot. 3876 // stack slot.