/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.vm.x86.compiler.l1b; import org.jnode.assembler.x86.X86Assembler; import org.jnode.assembler.x86.X86Register; import org.jnode.assembler.x86.X86Register.GPR; import org.jnode.assembler.x86.X86Register.GPR64; import org.jnode.vm.JvmType; import org.jnode.vm.compiler.IllegalModeException; /** * @author Ewout Prangsma (epr@users.sourceforge.net) */ final class L1AHelper { static final void assertCondition(boolean cond, String message) { if (!cond) throw new Error("assert failed: " + message); } static final void assertCondition(boolean cond, String message, Object param) { if (!cond) { throw new Error("assert failed: " + message + param); } } /** * Gets the 64-bit equivalent of the given 32-bit register. * * @param src * @return the 64-bit register. */ static final GPR64 get64BitReg(EmitterContext eContext, GPR src) { return (GPR64) eContext.getGPRPool().getRegisterInSameGroup(src, JvmType.LONG); } /** * Release a register. * * @param reg */ static final void releaseRegister(EmitterContext eContext, X86Register reg) { final X86RegisterPool pool = eContext.getGPRPool(); pool.release(reg); } /** * Request two register for a 8-byte item. */ static final DoubleWordItem requestDoubleWordRegisters( EmitterContext eContext, int jvmType) { final X86RegisterPool pool = eContext.getGPRPool(); final X86Assembler os = eContext.getStream(); final ItemFactory ifac = eContext.getItemFactory(); final DoubleWordItem result; if (os.isCode32()) { final X86Register.GPR lsb = (X86Register.GPR) requestRegister(eContext, JvmType.INT, false); final X86Register.GPR msb = (X86Register.GPR) requestRegister(eContext, JvmType.INT, false); result = ifac.createReg(eContext, jvmType, lsb, msb); pool.transferOwnerTo(lsb, result); pool.transferOwnerTo(msb, result); } else { final GPR64 reg = (GPR64) requestRegister(eContext, jvmType, false); result = ifac.createReg(eContext, jvmType, reg); pool.transferOwnerTo(reg, result); } return result; } /** * Request two register for a 8-byte item. */ static final DoubleWordItem requestDoubleWordRegisters( EmitterContext eContext, int jvmType, X86Register.GPR lsb, X86Register.GPR msb) { if (!eContext.getStream().isCode32()) { throw new IllegalModeException("Only support in 32-bit mode"); } final X86RegisterPool pool = eContext.getGPRPool(); final ItemFactory ifac = eContext.getItemFactory(); requestRegister(eContext, lsb); requestRegister(eContext, msb); final DoubleWordItem result = ifac.createReg(eContext, jvmType, lsb, msb); pool.transferOwnerTo(lsb, result); pool.transferOwnerTo(msb, result); return result; } /** * Request a 64-bit register for a 8-byte item. */ static final DoubleWordItem requestDoubleWordRegister( EmitterContext eContext, int jvmType, GPR64 reg) { if (!eContext.getStream().isCode64()) { throw new IllegalModeException("Only support in 64-bit mode"); } final X86RegisterPool pool = eContext.getGPRPool(); final ItemFactory ifac = eContext.getItemFactory(); requestRegister(eContext, reg); final DoubleWordItem result = ifac.createReg(eContext, jvmType, reg); pool.transferOwnerTo(reg, result); return result; } /** * Request a register for calcuation, not tied to an item. Make sure to * release the register afterwards. * * @param reg */ static final void requestRegister(EmitterContext eContext, X86Register reg) { final X86RegisterPool pool = eContext.getGPRPool(); if (!pool.isFree(reg)) { final Item i = (Item) pool.getOwner(reg); i.spill(eContext, reg); assertCondition(pool.isFree(reg), "register is not free after spill"); } assertCondition(pool.request(reg), "Request of register failed: ", reg); } /** * Request a register of a given type, not tied to an item. Make sure to * release the register afterwards. */ static final X86Register requestRegister(EmitterContext eContext, int type, boolean supportsBits8) { final X86RegisterPool pool = eContext.getGPRPool(); X86Register r = pool.request(type, supportsBits8); if (r == null) { eContext.getVStack().push(eContext); r = pool.request(type, supportsBits8); } assertCondition(r != null, "failed to request register"); return r; } /** * reserve a register for an item. The item is not loaded with the register. * The register is spilled if another item holds it. * * @param reg the register to reserve * @param it the item requiring the register */ static final void requestRegister(EmitterContext eContext, X86Register reg, Item it) { final X86RegisterPool pool = eContext.getGPRPool(); // check item doesn't already use register if (!it.uses(reg)) { if (!pool.isFree(reg)) { //TODO: spill register; make sure that the stack items // and floating items are handled correctly final Item i = (Item) pool.getOwner(reg); i.spill(eContext, reg); assertCondition(pool.isFree(reg), "register is not free after spill"); } assertCondition(pool.request(reg, it), "Request of register failed: ", reg); } } /** * Request one register for a single word item. */ static final WordItem requestWordRegister(EmitterContext eContext, int jvmType, boolean supportsBits8) { final X86RegisterPool pool = eContext.getGPRPool(); final ItemFactory ifac = eContext.getItemFactory(); final X86Register reg = requestRegister(eContext, jvmType, supportsBits8); final WordItem result = ifac.createReg(eContext, jvmType, reg); pool.transferOwnerTo(reg, result); return result; } /** * Request specific one register for a single word item. */ static final WordItem requestWordRegister(EmitterContext eContext, int jvmType, X86Register reg) { final X86RegisterPool pool = eContext.getGPRPool(); final ItemFactory ifac = eContext.getItemFactory(); assertCondition(pool.request(reg), "Request of register failed: ", reg); final WordItem result = ifac.createReg(eContext, jvmType, reg); pool.transferOwnerTo(reg, result); return result; } }