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.