Mercurial > hg > truffle
comparison src/cpu/ppc/vm/ppc.ad @ 14684:e5e8aa897002
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 | 7e8e4d1a41d6 |
children | 92aa6797d639 |
comparison
equal
deleted
inserted
replaced
14682:84eafecdb9a9 | 14684:e5e8aa897002 |
---|---|
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 |
3672 // TODO: PPC port $archOpcode(ppc64Opcode_compound); | 3676 // TODO: PPC port $archOpcode(ppc64Opcode_compound); |
3673 | 3677 |
3674 MacroAssembler _masm(&cbuf); | 3678 MacroAssembler _masm(&cbuf); |
3675 const address start_pc = __ pc(); | 3679 const address start_pc = __ pc(); |
3676 | 3680 |
3681 #if defined(ABI_ELFv2) | |
3682 address entry= !($meth$$method) ? NULL : (address)$meth$$method; | |
3683 __ call_c(entry, relocInfo::runtime_call_type); | |
3684 #else | |
3677 // The function we're going to call. | 3685 // The function we're going to call. |
3678 FunctionDescriptor fdtemp; | 3686 FunctionDescriptor fdtemp; |
3679 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; | 3687 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; |
3680 | 3688 |
3681 Register Rtoc = R12_scratch2; | 3689 Register Rtoc = R12_scratch2; |
3682 // Calculate the method's TOC. | 3690 // Calculate the method's TOC. |
3683 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); | 3691 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); |
3684 // Put entry, env, toc into the constant pool, this needs up to 3 constant | 3692 // Put entry, env, toc into the constant pool, this needs up to 3 constant |
3685 // pool entries; call_c_using_toc will optimize the call. | 3693 // pool entries; call_c_using_toc will optimize the call. |
3686 __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); | 3694 __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); |
3695 #endif | |
3687 | 3696 |
3688 // Check the ret_addr_offset. | 3697 // Check the ret_addr_offset. |
3689 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, | 3698 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, |
3690 "Fix constant in ret_addr_offset()"); | 3699 "Fix constant in ret_addr_offset()"); |
3691 %} | 3700 %} |
3697 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); | 3706 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); |
3698 MacroAssembler _masm(&cbuf); | 3707 MacroAssembler _masm(&cbuf); |
3699 __ mtctr($src$$Register); | 3708 __ mtctr($src$$Register); |
3700 %} | 3709 %} |
3701 | 3710 |
3702 // postalloc expand emitter for runtime leaf calls. | 3711 // Postalloc expand emitter for runtime leaf calls. |
3703 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ | 3712 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ |
3713 loadConLNodesTuple loadConLNodes_Entry; | |
3714 #if defined(ABI_ELFv2) | |
3715 jlong entry_address = (jlong) this->entry_point(); | |
3716 assert(entry_address, "need address here"); | |
3717 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address), | |
3718 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); | |
3719 #else | |
3704 // Get the struct that describes the function we are about to call. | 3720 // Get the struct that describes the function we are about to call. |
3705 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); | 3721 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); |
3706 assert(fd, "need fd here"); | 3722 assert(fd, "need fd here"); |
3723 jlong entry_address = (jlong) fd->entry(); | |
3707 // new nodes | 3724 // new nodes |
3708 loadConLNodesTuple loadConLNodes_Entry; | |
3709 loadConLNodesTuple loadConLNodes_Env; | 3725 loadConLNodesTuple loadConLNodes_Env; |
3710 loadConLNodesTuple loadConLNodes_Toc; | 3726 loadConLNodesTuple loadConLNodes_Toc; |
3711 MachNode *mtctr = NULL; | |
3712 MachCallLeafNode *call = NULL; | |
3713 | 3727 |
3714 // Create nodes and operands for loading the entry point. | 3728 // Create nodes and operands for loading the entry point. |
3715 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->entry()), | 3729 loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address), |
3716 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); | 3730 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); |
3717 | 3731 |
3718 | 3732 |
3719 // Create nodes and operands for loading the env pointer. | 3733 // Create nodes and operands for loading the env pointer. |
3720 if (fd->env() != NULL) { | 3734 if (fd->env() != NULL) { |
3731 } | 3745 } |
3732 | 3746 |
3733 // Create nodes and operands for loading the Toc point. | 3747 // Create nodes and operands for loading the Toc point. |
3734 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()), | 3748 loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()), |
3735 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); | 3749 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); |
3750 #endif // ABI_ELFv2 | |
3736 // mtctr node | 3751 // mtctr node |
3737 mtctr = new (C) CallLeafDirect_mtctrNode(); | 3752 MachNode *mtctr = new (C) CallLeafDirect_mtctrNode(); |
3738 | 3753 |
3739 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); | 3754 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); |
3740 mtctr->add_req(0, loadConLNodes_Entry._last); | 3755 mtctr->add_req(0, loadConLNodes_Entry._last); |
3741 | 3756 |
3742 mtctr->_opnds[0] = new (C) iRegLdstOper(); | 3757 mtctr->_opnds[0] = new (C) iRegLdstOper(); |
3743 mtctr->_opnds[1] = new (C) iRegLdstOper(); | 3758 mtctr->_opnds[1] = new (C) iRegLdstOper(); |
3744 | 3759 |
3745 // call node | 3760 // call node |
3746 call = new (C) CallLeafDirectNode(); | 3761 MachCallLeafNode *call = new (C) CallLeafDirectNode(); |
3747 | 3762 |
3748 call->_opnds[0] = _opnds[0]; | 3763 call->_opnds[0] = _opnds[0]; |
3749 call->_opnds[1] = new (C) methodOper((intptr_t) fd->entry()); // may get set later | 3764 call->_opnds[1] = new (C) methodOper((intptr_t) entry_address); // May get set later. |
3750 | 3765 |
3751 // Make the new call node look like the old one. | 3766 // Make the new call node look like the old one. |
3752 call->_name = _name; | 3767 call->_name = _name; |
3753 call->_tf = _tf; | 3768 call->_tf = _tf; |
3754 call->_entry_point = _entry_point; | 3769 call->_entry_point = _entry_point; |
3771 } | 3786 } |
3772 | 3787 |
3773 // These must be reqired edges, as the registers are live up to | 3788 // These must be reqired edges, as the registers are live up to |
3774 // the call. Else the constants are handled as kills. | 3789 // the call. Else the constants are handled as kills. |
3775 call->add_req(mtctr); | 3790 call->add_req(mtctr); |
3791 #if !defined(ABI_ELFv2) | |
3776 call->add_req(loadConLNodes_Env._last); | 3792 call->add_req(loadConLNodes_Env._last); |
3777 call->add_req(loadConLNodes_Toc._last); | 3793 call->add_req(loadConLNodes_Toc._last); |
3794 #endif | |
3778 | 3795 |
3779 // ...as well as prec | 3796 // ...as well as prec |
3780 for (uint i = req(); i < len(); ++i) { | 3797 for (uint i = req(); i < len(); ++i) { |
3781 call->add_prec(in(i)); | 3798 call->add_prec(in(i)); |
3782 } | 3799 } |
3785 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); | 3802 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); |
3786 | 3803 |
3787 // Insert the new nodes. | 3804 // Insert the new nodes. |
3788 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); | 3805 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); |
3789 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); | 3806 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); |
3807 #if !defined(ABI_ELFv2) | |
3790 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); | 3808 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); |
3791 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); | 3809 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); |
3792 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); | 3810 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); |
3793 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); | 3811 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); |
3812 #endif | |
3794 nodes->push(mtctr); | 3813 nodes->push(mtctr); |
3795 nodes->push(call); | 3814 nodes->push(call); |
3796 %} | 3815 %} |
3797 %} | 3816 %} |
3798 | 3817 |
3835 | 3854 |
3836 // Number of outgoing stack slots killed above the | 3855 // Number of outgoing stack slots killed above the |
3837 // out_preserve_stack_slots for calls to C. Supports the var-args | 3856 // out_preserve_stack_slots for calls to C. Supports the var-args |
3838 // backing area for register parms. | 3857 // backing area for register parms. |
3839 // | 3858 // |
3840 varargs_C_out_slots_killed(((frame::abi_112_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); | 3859 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); |
3841 | 3860 |
3842 // The after-PROLOG location of the return address. Location of | 3861 // The after-PROLOG location of the return address. Location of |
3843 // return address specifies a type (REG or STACK) and a number | 3862 // return address specifies a type (REG or STACK) and a number |
3844 // representing the register number (i.e. - use a register name) or | 3863 // representing the register number (i.e. - use a register name) or |
3845 // stack slot. | 3864 // stack slot. |