duke@435: /* duke@435: * Copyright 1999-2006 Sun Microsystems, Inc. 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: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: # include "incls/_precompiled.incl" duke@435: # include "incls/_c1_FrameMap_x86.cpp.incl" 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(); duke@435: if (r_2->is_Register()) { duke@435: Register reg2 = r_2->as_Register(); duke@435: opr = as_long_opr(reg2, reg); duke@435: } else if (type == T_OBJECT) { duke@435: opr = as_oop_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: duke@435: LIR_Opr FrameMap::rax_rdx_long_opr; duke@435: LIR_Opr FrameMap::rbx_rcx_long_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: 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: duke@435: XMMRegister FrameMap::_xmm_regs [8] = { 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: duke@435: void FrameMap::init() { duke@435: if (_init_done) return; duke@435: duke@435: assert(nof_cpu_regs == 8, "wrong number of CPU registers"); duke@435: map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); rsi_oop_opr = LIR_OprFact::single_cpu_oop(0); duke@435: map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); rdi_oop_opr = LIR_OprFact::single_cpu_oop(1); duke@435: map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); rbx_oop_opr = LIR_OprFact::single_cpu_oop(2); duke@435: map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); rax_oop_opr = LIR_OprFact::single_cpu_oop(3); duke@435: map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); rdx_oop_opr = LIR_OprFact::single_cpu_oop(4); duke@435: map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); rcx_oop_opr = LIR_OprFact::single_cpu_oop(5); duke@435: map_register(6, rsp); rsp_opr = LIR_OprFact::single_cpu(6); duke@435: map_register(7, rbp); rbp_opr = LIR_OprFact::single_cpu(7); duke@435: duke@435: rax_rdx_long_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); duke@435: rbx_rcx_long_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); 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: 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: duke@435: for (int i = 0; i < 8; i++) { duke@435: _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); duke@435: _caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i); duke@435: } duke@435: duke@435: _init_done = true; duke@435: 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()); duke@435: assert(receiver_opr == rcx_oop_opr, "rcvr ought to be rcx"); 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: duke@435: bool FrameMap::validate_frame() { duke@435: return true; duke@435: }