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