duke@435: /* mikael@4153: * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "c1/c1_FrameMap.hpp" stefank@2314: #include "c1/c1_LIR.hpp" stefank@2314: #include "runtime/sharedRuntime.hpp" stefank@2314: #include "vmreg_x86.inline.hpp" duke@435: duke@435: const int FrameMap::pd_c_runtime_reserved_arg_size = 0; duke@435: duke@435: LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { duke@435: LIR_Opr opr = LIR_OprFact::illegalOpr; duke@435: VMReg r_1 = reg->first(); duke@435: VMReg r_2 = reg->second(); duke@435: if (r_1->is_stack()) { duke@435: // Convert stack slot to an SP offset duke@435: // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value duke@435: // so we must add it in here. duke@435: int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; duke@435: opr = LIR_OprFact::address(new LIR_Address(rsp_opr, st_off, type)); duke@435: } else if (r_1->is_Register()) { duke@435: Register reg = r_1->as_Register(); never@739: if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { duke@435: Register reg2 = r_2->as_Register(); never@739: #ifdef _LP64 never@739: assert(reg2 == reg, "must be same register"); never@739: opr = as_long_opr(reg); never@739: #else duke@435: opr = as_long_opr(reg2, reg); never@739: #endif // _LP64 never@739: } else if (type == T_OBJECT || type == T_ARRAY) { duke@435: opr = as_oop_opr(reg); iveresov@5994: } else if (type == T_METADATA) { iveresov@5994: opr = as_metadata_opr(reg); duke@435: } else { duke@435: opr = as_opr(reg); duke@435: } duke@435: } else if (r_1->is_FloatRegister()) { duke@435: assert(type == T_DOUBLE || type == T_FLOAT, "wrong type"); duke@435: int num = r_1->as_FloatRegister()->encoding(); duke@435: if (type == T_FLOAT) { duke@435: opr = LIR_OprFact::single_fpu(num); duke@435: } else { duke@435: opr = LIR_OprFact::double_fpu(num); duke@435: } duke@435: } else if (r_1->is_XMMRegister()) { duke@435: assert(type == T_DOUBLE || type == T_FLOAT, "wrong type"); duke@435: int num = r_1->as_XMMRegister()->encoding(); duke@435: if (type == T_FLOAT) { duke@435: opr = LIR_OprFact::single_xmm(num); duke@435: } else { duke@435: opr = LIR_OprFact::double_xmm(num); duke@435: } duke@435: } else { duke@435: ShouldNotReachHere(); duke@435: } duke@435: return opr; duke@435: } duke@435: duke@435: duke@435: LIR_Opr FrameMap::rsi_opr; duke@435: LIR_Opr FrameMap::rdi_opr; duke@435: LIR_Opr FrameMap::rbx_opr; duke@435: LIR_Opr FrameMap::rax_opr; duke@435: LIR_Opr FrameMap::rdx_opr; duke@435: LIR_Opr FrameMap::rcx_opr; duke@435: LIR_Opr FrameMap::rsp_opr; duke@435: LIR_Opr FrameMap::rbp_opr; duke@435: duke@435: LIR_Opr FrameMap::receiver_opr; duke@435: duke@435: LIR_Opr FrameMap::rsi_oop_opr; duke@435: LIR_Opr FrameMap::rdi_oop_opr; duke@435: LIR_Opr FrameMap::rbx_oop_opr; duke@435: LIR_Opr FrameMap::rax_oop_opr; duke@435: LIR_Opr FrameMap::rdx_oop_opr; duke@435: LIR_Opr FrameMap::rcx_oop_opr; duke@435: roland@4051: LIR_Opr FrameMap::rsi_metadata_opr; roland@4051: LIR_Opr FrameMap::rdi_metadata_opr; roland@4051: LIR_Opr FrameMap::rbx_metadata_opr; roland@4051: LIR_Opr FrameMap::rax_metadata_opr; roland@4051: LIR_Opr FrameMap::rdx_metadata_opr; roland@4051: LIR_Opr FrameMap::rcx_metadata_opr; roland@4051: never@739: LIR_Opr FrameMap::long0_opr; never@739: LIR_Opr FrameMap::long1_opr; duke@435: LIR_Opr FrameMap::fpu0_float_opr; duke@435: LIR_Opr FrameMap::fpu0_double_opr; duke@435: LIR_Opr FrameMap::xmm0_float_opr; duke@435: LIR_Opr FrameMap::xmm0_double_opr; duke@435: never@739: #ifdef _LP64 never@739: never@739: LIR_Opr FrameMap::r8_opr; never@739: LIR_Opr FrameMap::r9_opr; never@739: LIR_Opr FrameMap::r10_opr; never@739: LIR_Opr FrameMap::r11_opr; never@739: LIR_Opr FrameMap::r12_opr; never@739: LIR_Opr FrameMap::r13_opr; never@739: LIR_Opr FrameMap::r14_opr; never@739: LIR_Opr FrameMap::r15_opr; never@739: never@739: // r10 and r15 can never contain oops since they aren't available to never@739: // the allocator never@739: LIR_Opr FrameMap::r8_oop_opr; never@739: LIR_Opr FrameMap::r9_oop_opr; never@739: LIR_Opr FrameMap::r11_oop_opr; never@739: LIR_Opr FrameMap::r12_oop_opr; never@739: LIR_Opr FrameMap::r13_oop_opr; never@739: LIR_Opr FrameMap::r14_oop_opr; roland@4051: roland@4051: LIR_Opr FrameMap::r8_metadata_opr; roland@4051: LIR_Opr FrameMap::r9_metadata_opr; roland@4051: LIR_Opr FrameMap::r11_metadata_opr; roland@4051: LIR_Opr FrameMap::r12_metadata_opr; roland@4051: LIR_Opr FrameMap::r13_metadata_opr; roland@4051: LIR_Opr FrameMap::r14_metadata_opr; never@739: #endif // _LP64 never@739: duke@435: LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, }; duke@435: LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, }; duke@435: LIR_Opr FrameMap::_caller_save_xmm_regs[] = { 0, }; duke@435: never@739: XMMRegister FrameMap::_xmm_regs [] = { 0, }; duke@435: duke@435: XMMRegister FrameMap::nr2xmmreg(int rnr) { duke@435: assert(_init_done, "tables not initialized"); duke@435: return _xmm_regs[rnr]; duke@435: } duke@435: duke@435: //-------------------------------------------------------- duke@435: // FrameMap duke@435: //-------------------------------------------------------- duke@435: iveresov@1939: void FrameMap::initialize() { iveresov@1939: assert(!_init_done, "once"); duke@435: never@739: assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers"); never@739: map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); never@739: map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); never@739: map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); never@739: map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); never@739: map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); never@739: map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); duke@435: never@739: #ifndef _LP64 never@739: // The unallocatable registers are at the end never@739: map_register(6, rsp); never@739: map_register(7, rbp); never@739: #else never@739: map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); never@739: map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); never@739: map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); iveresov@2344: map_register( 9, r13); r13_opr = LIR_OprFact::single_cpu(9); iveresov@2344: map_register(10, r14); r14_opr = LIR_OprFact::single_cpu(10); iveresov@2344: // r12 is allocated conditionally. With compressed oops it holds iveresov@2344: // the heapbase value and is not visible to the allocator. iveresov@2344: map_register(11, r12); r12_opr = LIR_OprFact::single_cpu(11); never@739: // The unallocatable registers are at the end never@739: map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); never@739: map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); never@739: map_register(14, rsp); never@739: map_register(15, rbp); never@739: #endif // _LP64 never@739: never@739: #ifdef _LP64 never@739: long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 3 /*eax*/); never@739: long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 2 /*ebx*/); never@739: #else never@739: long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); never@739: long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); never@739: #endif // _LP64 duke@435: fpu0_float_opr = LIR_OprFact::single_fpu(0); duke@435: fpu0_double_opr = LIR_OprFact::double_fpu(0); duke@435: xmm0_float_opr = LIR_OprFact::single_xmm(0); duke@435: xmm0_double_opr = LIR_OprFact::double_xmm(0); duke@435: duke@435: _caller_save_cpu_regs[0] = rsi_opr; duke@435: _caller_save_cpu_regs[1] = rdi_opr; duke@435: _caller_save_cpu_regs[2] = rbx_opr; duke@435: _caller_save_cpu_regs[3] = rax_opr; duke@435: _caller_save_cpu_regs[4] = rdx_opr; duke@435: _caller_save_cpu_regs[5] = rcx_opr; duke@435: never@739: #ifdef _LP64 never@739: _caller_save_cpu_regs[6] = r8_opr; never@739: _caller_save_cpu_regs[7] = r9_opr; never@739: _caller_save_cpu_regs[8] = r11_opr; iveresov@2344: _caller_save_cpu_regs[9] = r13_opr; iveresov@2344: _caller_save_cpu_regs[10] = r14_opr; iveresov@2344: _caller_save_cpu_regs[11] = r12_opr; never@739: #endif // _LP64 never@739: duke@435: duke@435: _xmm_regs[0] = xmm0; duke@435: _xmm_regs[1] = xmm1; duke@435: _xmm_regs[2] = xmm2; duke@435: _xmm_regs[3] = xmm3; duke@435: _xmm_regs[4] = xmm4; duke@435: _xmm_regs[5] = xmm5; duke@435: _xmm_regs[6] = xmm6; duke@435: _xmm_regs[7] = xmm7; duke@435: never@739: #ifdef _LP64 never@739: _xmm_regs[8] = xmm8; never@739: _xmm_regs[9] = xmm9; never@739: _xmm_regs[10] = xmm10; never@739: _xmm_regs[11] = xmm11; never@739: _xmm_regs[12] = xmm12; never@739: _xmm_regs[13] = xmm13; never@739: _xmm_regs[14] = xmm14; never@739: _xmm_regs[15] = xmm15; never@739: #endif // _LP64 never@739: duke@435: for (int i = 0; i < 8; i++) { duke@435: _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); never@739: } never@739: never@739: for (int i = 0; i < nof_caller_save_xmm_regs ; i++) { duke@435: _caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i); duke@435: } duke@435: duke@435: _init_done = true; duke@435: never@739: rsi_oop_opr = as_oop_opr(rsi); never@739: rdi_oop_opr = as_oop_opr(rdi); never@739: rbx_oop_opr = as_oop_opr(rbx); never@739: rax_oop_opr = as_oop_opr(rax); never@739: rdx_oop_opr = as_oop_opr(rdx); never@739: rcx_oop_opr = as_oop_opr(rcx); never@739: roland@4051: rsi_metadata_opr = as_metadata_opr(rsi); roland@4051: rdi_metadata_opr = as_metadata_opr(rdi); roland@4051: rbx_metadata_opr = as_metadata_opr(rbx); roland@4051: rax_metadata_opr = as_metadata_opr(rax); roland@4051: rdx_metadata_opr = as_metadata_opr(rdx); roland@4051: rcx_metadata_opr = as_metadata_opr(rcx); roland@4051: never@739: rsp_opr = as_pointer_opr(rsp); never@739: rbp_opr = as_pointer_opr(rbp); never@739: never@739: #ifdef _LP64 never@739: r8_oop_opr = as_oop_opr(r8); never@739: r9_oop_opr = as_oop_opr(r9); never@739: r11_oop_opr = as_oop_opr(r11); never@739: r12_oop_opr = as_oop_opr(r12); never@739: r13_oop_opr = as_oop_opr(r13); never@739: r14_oop_opr = as_oop_opr(r14); roland@4051: roland@4051: r8_metadata_opr = as_metadata_opr(r8); roland@4051: r9_metadata_opr = as_metadata_opr(r9); roland@4051: r11_metadata_opr = as_metadata_opr(r11); roland@4051: r12_metadata_opr = as_metadata_opr(r12); roland@4051: r13_metadata_opr = as_metadata_opr(r13); roland@4051: r14_metadata_opr = as_metadata_opr(r14); never@739: #endif // _LP64 never@739: duke@435: VMRegPair regs; duke@435: BasicType sig_bt = T_OBJECT; duke@435: SharedRuntime::java_calling_convention(&sig_bt, ®s, 1, true); duke@435: receiver_opr = as_oop_opr(regs.first()->as_Register()); never@739: duke@435: } duke@435: duke@435: duke@435: Address FrameMap::make_new_address(ByteSize sp_offset) const { duke@435: // for rbp, based address use this: duke@435: // return Address(rbp, in_bytes(sp_offset) - (framesize() - 2) * 4); duke@435: return Address(rsp, in_bytes(sp_offset)); duke@435: } duke@435: duke@435: duke@435: // ----------------mapping----------------------- duke@435: // all mapping is based on rbp, addressing, except for simple leaf methods where we access duke@435: // the locals rsp based (and no frame is built) duke@435: duke@435: duke@435: // Frame for simple leaf methods (quick entries) duke@435: // duke@435: // +----------+ duke@435: // | ret addr | <- TOS duke@435: // +----------+ duke@435: // | args | duke@435: // | ...... | duke@435: duke@435: // Frame for standard methods duke@435: // duke@435: // | .........| <- TOS duke@435: // | locals | duke@435: // +----------+ duke@435: // | old rbp, | <- EBP duke@435: // +----------+ duke@435: // | ret addr | duke@435: // +----------+ duke@435: // | args | duke@435: // | .........| duke@435: duke@435: duke@435: // For OopMaps, map a local variable or spill index to an VMRegImpl name. duke@435: // This is the offset from sp() in the frame of the slot for the index, duke@435: // skewed by VMRegImpl::stack0 to indicate a stack location (vs.a register.) duke@435: // duke@435: // framesize + duke@435: // stack0 stack0 0 <- VMReg duke@435: // | | | duke@435: // ...........|..............|.............| duke@435: // 0 1 2 3 x x 4 5 6 ... | <- local indices duke@435: // ^ ^ sp() ( x x indicate link duke@435: // | | and return addr) duke@435: // arguments non-argument locals duke@435: duke@435: duke@435: VMReg FrameMap::fpu_regname (int n) { duke@435: // Return the OptoReg name for the fpu stack slot "n" duke@435: // A spilled fpu stack slot comprises to two single-word OptoReg's. duke@435: return as_FloatRegister(n)->as_VMReg(); duke@435: } duke@435: duke@435: LIR_Opr FrameMap::stack_pointer() { duke@435: return FrameMap::rsp_opr; duke@435: } duke@435: duke@435: twisti@1919: // JSR 292 twisti@1919: LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() { twisti@1919: assert(rbp == rbp_mh_SP_save, "must be same register"); twisti@1919: return rbp_opr; twisti@1919: } twisti@1919: twisti@1919: duke@435: bool FrameMap::validate_frame() { duke@435: return true; duke@435: }