Mercurial > hg > truffle
comparison src/cpu/ppc/vm/ppc.ad @ 17791:ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
Summary: Add ConstantTableBase node edge after parameters and before jvms. Adapt jvms offsets.
Reviewed-by: kvn
author | goetz |
---|---|
date | Fri, 20 Dec 2013 13:51:14 +0100 |
parents | 67fa91961822 |
children | b858620b0081 |
comparison
equal
deleted
inserted
replaced
17790:5da8bb64b370 | 17791:ad3b94907eed |
---|---|
3561 __ bl((address) __ pc()); | 3561 __ bl((address) __ pc()); |
3562 %} | 3562 %} |
3563 | 3563 |
3564 // postalloc expand emitter for virtual calls. | 3564 // postalloc expand emitter for virtual calls. |
3565 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ | 3565 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ |
3566 // Toc is in return address field, though not accessible via postalloc_expand | |
3567 // functionaliy. | |
3568 Node *toc = in(TypeFunc::ReturnAdr); | |
3569 | 3566 |
3570 // Create the nodes for loading the IC from the TOC. | 3567 // Create the nodes for loading the IC from the TOC. |
3571 loadConLNodesTuple loadConLNodes_IC = | 3568 loadConLNodesTuple loadConLNodes_IC = |
3572 loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong)Universe::non_oop_word()), | 3569 loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong)Universe::non_oop_word()), |
3573 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); | 3570 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); |
3590 call->_nesting = _nesting; | 3587 call->_nesting = _nesting; |
3591 | 3588 |
3592 // New call needs all inputs of old call. | 3589 // New call needs all inputs of old call. |
3593 // Req... | 3590 // Req... |
3594 for (uint i = 0; i < req(); ++i) { | 3591 for (uint i = 0; i < req(); ++i) { |
3595 if (i != TypeFunc::ReturnAdr) { | 3592 // The expanded node does not need toc any more. |
3593 // Add the inline cache constant here instead. This expresses the | |
3594 // register of the inline cache must be live at the call. | |
3595 // Else we would have to adapt JVMState by -1. | |
3596 if (i == mach_constant_base_node_input()) { | |
3597 call->add_req(loadConLNodes_IC._last); | |
3598 } else { | |
3596 call->add_req(in(i)); | 3599 call->add_req(in(i)); |
3597 } else { | |
3598 // The expanded node does not need toc any more. | |
3599 call->add_req(C->top()); | |
3600 } | 3600 } |
3601 } | 3601 } |
3602 // ...as well as prec | 3602 // ...as well as prec |
3603 for (uint i = req(); i < len() ; ++i) { | 3603 for (uint i = req(); i < len(); ++i) { |
3604 call->add_prec(in(i)); | 3604 call->add_prec(in(i)); |
3605 } | 3605 } |
3606 | 3606 |
3607 // The cache must come before the call, but it's not a req edge. | |
3608 // GL: actually it should be a req edge to express that the | |
3609 // register must be live in the Call. But as R19 is declared to be | |
3610 // the inline_cache_reg that's fine. | |
3611 call->add_prec(loadConLNodes_IC._last); | |
3612 // Remember nodes loading the inline cache into r19. | 3607 // Remember nodes loading the inline cache into r19. |
3613 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; | 3608 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; |
3614 call->_load_ic_node = loadConLNodes_IC._small; | 3609 call->_load_ic_node = loadConLNodes_IC._small; |
3615 | 3610 |
3616 // Operands for new nodes. | 3611 // Operands for new nodes. |
3636 #if 0 | 3631 #if 0 |
3637 if (_vtable_index < 0) { | 3632 if (_vtable_index < 0) { |
3638 // Must be invalid_vtable_index, not nonvirtual_vtable_index. | 3633 // Must be invalid_vtable_index, not nonvirtual_vtable_index. |
3639 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); | 3634 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); |
3640 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); | 3635 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); |
3641 AddressLiteral oop = __ allocate_metadata_address((Metadata *)Universe::non_oop_word()); | 3636 AddressLiteral meta = __ allocate_metadata_address((Metadata *)Universe::non_oop_word()); |
3642 | 3637 |
3643 address virtual_call_oop_addr = __ pc(); | 3638 address virtual_call_meta_addr = __ pc(); |
3644 __ load_const_from_method_toc(ic_reg, oop, Rtoc); | 3639 __ load_const_from_method_toc(ic_reg, meta, Rtoc); |
3645 // CALL to fixup routine. Fixup routine uses ScopeDesc info | 3640 // CALL to fixup routine. Fixup routine uses ScopeDesc info |
3646 // to determine who we intended to call. | 3641 // to determine who we intended to call. |
3647 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr)); | 3642 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); |
3648 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); | 3643 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); |
3649 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, | 3644 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, |
3650 "Fix constant in ret_addr_offset()"); | 3645 "Fix constant in ret_addr_offset()"); |
3651 } else { | 3646 } else { |
3652 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); | 3647 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); |
3672 } | 3667 } |
3673 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, | 3668 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, |
3674 "Fix constant in ret_addr_offset()"); | 3669 "Fix constant in ret_addr_offset()"); |
3675 } | 3670 } |
3676 #endif | 3671 #endif |
3672 guarantee(0, "Fix handling of toc edge: messes up derived/base pairs."); | |
3677 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). | 3673 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). |
3678 %} | 3674 %} |
3679 | 3675 |
3680 // a runtime call | 3676 // a runtime call |
3681 enc_class enc_java_to_runtime_call (method meth) %{ | 3677 enc_class enc_java_to_runtime_call (method meth) %{ |
3773 | 3769 |
3774 | 3770 |
3775 // New call needs all inputs of old call. | 3771 // New call needs all inputs of old call. |
3776 // Req... | 3772 // Req... |
3777 for (uint i = 0; i < req(); ++i) { | 3773 for (uint i = 0; i < req(); ++i) { |
3778 if (i != TypeFunc::ReturnAdr) { | 3774 if (i != mach_constant_base_node_input()) { |
3779 call->add_req(in(i)); | 3775 call->add_req(in(i)); |
3780 } else { | |
3781 // put the mtctr where ReturnAdr would be | |
3782 call->add_req(mtctr); | |
3783 } | 3776 } |
3784 } | 3777 } |
3785 | 3778 |
3786 // These must be reqired edges, as the registers are live up to | 3779 // These must be reqired edges, as the registers are live up to |
3787 // the call. Else the constants are handled as kills. | 3780 // the call. Else the constants are handled as kills. |
3781 call->add_req(mtctr); | |
3788 call->add_req(loadConLNodes_Env._last); | 3782 call->add_req(loadConLNodes_Env._last); |
3789 call->add_req(loadConLNodes_Toc._last); | 3783 call->add_req(loadConLNodes_Toc._last); |
3790 | 3784 |
3791 // ...as well as prec | 3785 // ...as well as prec |
3792 for (uint i = req(); i < len(); ++i) { | 3786 for (uint i = req(); i < len(); ++i) { |
3816 stack_direction(TOWARDS_LOW); | 3810 stack_direction(TOWARDS_LOW); |
3817 | 3811 |
3818 // These two registers define part of the calling convention between | 3812 // These two registers define part of the calling convention between |
3819 // compiled code and the interpreter. | 3813 // compiled code and the interpreter. |
3820 | 3814 |
3821 // Inline Cache Register or methodOop for I2C. | 3815 // Inline Cache Register or method for I2C. |
3822 inline_cache_reg(R19); // R19_method | 3816 inline_cache_reg(R19); // R19_method |
3823 | 3817 |
3824 // Method Oop Register when calling interpreter. | 3818 // Method Oop Register when calling interpreter. |
3825 interpreter_method_oop_reg(R19); // R19_method | 3819 interpreter_method_oop_reg(R19); // R19_method |
3826 | 3820 |
6147 | 6141 |
6148 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} | 6142 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} |
6149 size(4); | 6143 size(4); |
6150 ins_encode %{ | 6144 ins_encode %{ |
6151 // TODO: PPC port $archOpcode(ppc64Opcode_ld); | 6145 // TODO: PPC port $archOpcode(ppc64Opcode_ld); |
6152 int offset = ra_->C->in_scratch_emit_size() ? 0 : MacroAssembler::largeoffset_si16_si16_lo(_const_toc_offset_hi_node->_const_toc_offset); | 6146 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; |
6153 __ ld($dst$$Register, offset, $base$$Register); | 6147 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); |
6154 %} | 6148 %} |
6155 ins_pipe(pipe_class_memory); | 6149 ins_pipe(pipe_class_memory); |
6156 %} | 6150 %} |
6157 | 6151 |
6158 // Load pointer constant from constant table. Expand in case an | 6152 // Load pointer constant from constant table. Expand in case an |
6782 ins_encode %{ | 6776 ins_encode %{ |
6783 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); | 6777 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); |
6784 Label done; | 6778 Label done; |
6785 __ beq($crx$$CondRegister, done); | 6779 __ beq($crx$$CondRegister, done); |
6786 __ add($dst$$Register, $src1$$Register, R30); | 6780 __ add($dst$$Register, $src1$$Register, R30); |
6787 // TODO PPC port __ endgroup_if_needed(_size == 12); | 6781 // TODO PPC port __ endgroup_if_needed(_size == 12); |
6788 __ bind(done); | 6782 __ bind(done); |
6789 %} | 6783 %} |
6790 ins_pipe(pipe_class_default); | 6784 ins_pipe(pipe_class_default); |
6791 %} | 6785 %} |
6792 | 6786 |