Mercurial > hg > truffle
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. |