Package org.jnode.vm.x86.compiler.l1a

Source Code of org.jnode.vm.x86.compiler.l1a.DoubleWordItem

/*
* $Id$
*
* Copyright (C) 2003-2014 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.l1a;

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.GPR32;
import org.jnode.assembler.x86.X86Register.GPR64;
import org.jnode.vm.JvmType;
import org.jnode.vm.facade.VmUtils;

import static org.jnode.vm.x86.compiler.X86CompilerConstants.BITS64;
import static org.jnode.vm.x86.compiler.X86CompilerConstants.INTSIZE;

/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public abstract class DoubleWordItem extends Item {

    /**
     * LSB Register in 32-bit mode
     */
    private X86Register.GPR32 lsb;

    /**
     * MSB Register in 32-bit mode
     */
    private X86Register.GPR32 msb;

    /**
     * Register in 64-bit mode
     */
    private X86Register.GPR64 reg;

    /**
     * Initialize a blank item.
     *
     * @param factory
     */
    protected DoubleWordItem(ItemFactory factory) {
        super(factory);
    }

    /**
     * @param ec
     * @param kind
     * @param offsetToFP
     * @param lsb
     * @param msb
     * @param reg
     * @param xmm
     */
    protected final void initialize(EmitterContext ec, byte kind, short offsetToFP,
                                    X86Register.GPR lsb, X86Register.GPR msb, X86Register.GPR64 reg,
                                    X86Register.XMM xmm) {
        super.initialize(kind, offsetToFP, xmm);
        this.lsb = (GPR32) lsb;
        this.msb = (GPR32) msb;
        this.reg = reg;
        if (VmUtils.verifyAssertions()) {
            if (isGPR()) {
                VmUtils._assert(((lsb != null) && (msb != null)) || (reg != null));
            }
            verifyState(ec);
        }
    }

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#clone()
     */
    protected final Item clone(EmitterContext ec) {
        final DoubleWordItem res;
        final X86Assembler os = ec.getStream();

        switch (getKind()) {
            case Kind.GPR:
                res = L1AHelper.requestDoubleWordRegisters(ec, getType());
                if (os.isCode32()) {
                    final GPR lsb = res.getLsbRegister(ec);
                    final GPR msb = res.getMsbRegister(ec);
                    os.writeMOV(INTSIZE, lsb, this.lsb);
                    os.writeMOV(INTSIZE, msb, this.msb);
                } else {
                    final GPR64 reg = res.getRegister(ec);
                    os.writeMOV(BITS64, reg, this.reg);
                }
                break;

            case Kind.LOCAL:
                res = (DoubleWordItem) factory.createLocal(getType(), super
                    .getOffsetToFP(ec));
                break;

            case Kind.CONSTANT:
                res = cloneConstant(ec);
                break;

            case Kind.FPUSTACK:
                // TODO
                notImplemented();
                res = null;
                break;

            case Kind.STACK:
                // TODO
                notImplemented();
                res = null;
                break;

            default:
                throw new IllegalArgumentException("Invalid item kind");
        }
        return res;
    }

    /**
     * Create a clone of this item, which must be a constant.
     *
     * @param ec
     * @return the clone
     */
    protected abstract DoubleWordItem cloneConstant(EmitterContext ec);

    /**
     * Return the current item's computational type category (JVM Spec, p. 83).
     * In practice, this is the number of double words needed by the item (1 or
     * 2)
     *
     * @return computational type category
     */
    final int getCategory() {
        return 2;
    }

    /**
     * Gets the offset from the LSB part of this item to the FramePointer
     * register. This is only valid if this item has a LOCAL kind.
     *
     * @param ec
     * @return the offset
     */
    final int getLsbOffsetToFP(EmitterContext ec) {
        return super.getOffsetToFP(ec);
    }

    /**
     * Gets the register holding the LSB part of this item in 32-bit mode.
     *
     * @param ec
     * @return the register
     */
    final X86Register.GPR getLsbRegister(EmitterContext ec) {
        if (!ec.getStream().isCode32()) {
            throw new Error("Can only be used in 32-bit mode");
        }
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(isGPR(), "kind == Kind.REGISTER");
            VmUtils._assert(lsb != null, "lsb != null");
        }
        return lsb;
    }

    /**
     * Gets the offset from the MSB part of this item to the FramePointer
     * register. This is only valid if this item has a LOCAL kind.
     *
     * @param ec
     * @return the offset
     */
    final int getMsbOffsetToFP(EmitterContext ec) {
        return super.getOffsetToFP(ec) + 4;
    }

    /**
     * Gets the register holding the MSB part of this item in 32-bit mode.
     *
     * @param ec
     * @return the register
     */
    final X86Register.GPR getMsbRegister(EmitterContext ec) {
        if (!ec.getStream().isCode32()) {
            throw new Error("Can only be used in 32-bit mode");
        }
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(isGPR(), "kind == Kind.GPR");
            VmUtils._assert(msb != null, "msb != null");
        }
        return msb;
    }

    /**
     * Gets the register holding this item in 64-bit mode.
     *
     * @param ec
     * @return the register
     */
    final X86Register.GPR64 getRegister(EmitterContext ec) {
        if (!ec.getStream().isCode64()) {
            throw new Error("Can only be used in 64-bit mode");
        }
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(isGPR(), "kind == Kind.REGISTER");
            VmUtils._assert(reg != null, "reg != null reg=" + reg + " lsb=" + lsb
                + " msb=" + msb);
        }
        return reg;
    }

    /**
     * Gets the offset from this item to the FramePointer register. This is only
     * valid if this item has a LOCAL kind.
     *
     * @return In 32-bit mode, use {@link #getLsbOffsetToFP(EmitterContext)} or
     *         {@link #getMsbOffsetToFP(EmitterContext)} instead.
     */
    final short getOffsetToFP(EmitterContext ec) {
        if (ec.getStream().isCode32()) {
            throw new Error("Do not use this");
        } else {
            return super.getOffsetToFP(ec);
        }
    }

    final void load(EmitterContext ec) {
        if (!isGPR()) {
            final X86RegisterPool pool = ec.getGPRPool();
            final X86Assembler os = ec.getStream();

            if (os.isCode32()) {
                X86Register.GPR l = (X86Register.GPR) pool.request(JvmType.INT,
                    this);
                if (l == null) {
                    final VirtualStack vstack = ec.getVStack();
                    vstack.push(ec);
                    l = (X86Register.GPR) pool.request(JvmType.INT, this);
                }
                X86Register.GPR r = (X86Register.GPR) pool.request(JvmType.INT,
                    this);
                if (r == null) {
                    final VirtualStack vstack = ec.getVStack();
                    vstack.push(ec);
                    r = (X86Register.GPR) pool.request(JvmType.INT, this);
                }
                if (VmUtils.verifyAssertions()) {
                    VmUtils._assert(r != null, "r != null");
                    VmUtils._assert(l != null, "l != null");
                }
                loadTo32(ec, l, r);
            } else {
                GPR64 r = (GPR64) pool.request(getType(), this);
                if (r == null) {
                    final VirtualStack vstack = ec.getVStack();
                    vstack.push(ec);
                    r = (GPR64) pool.request(getType(), this);
                }
                if (VmUtils.verifyAssertions()) {
                    VmUtils._assert(r != null, "r != null");
                }
                loadTo64(ec, r);
            }
        }
        if (VmUtils.verifyAssertions()) {
            verifyState(ec);
        }
    }

    /**
     * Load the value of this item into the given registers.
     *
     * @param ec
     * @param lsb
     * @param msb
     */
    final void loadTo32(EmitterContext ec, X86Register.GPR lsb,
                        X86Register.GPR msb) {
        final X86Assembler os = ec.getStream();
        final X86RegisterPool pool = ec.getGPRPool();
        final VirtualStack stack = ec.getVStack();
        if (!os.isCode32()) {
            throw new RuntimeException("Can only be used in 32-bit mode.");
        }

        // os.log("LongItem.log called "+Integer.toString(kind));
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(lsb != msb, "lsb != msb");
            VmUtils._assert(lsb != null, "lsb != null");
            VmUtils._assert(msb != null, "msb != null");
        }

        switch (getKind()) {
            case Kind.GPR:
                // invariant: (msb != lsb) && (this.msb != this.lsb)
                if (msb != this.lsb) {
                    // generic case; avoid only if msb is lsb' (value overwriting)
                    // invariant: (msb != this.lsb) && (msb != lsb) && (this.msb !=
                    // this.lsb)
                    // msb <- msb'
                    // lsb <- lsb'
                    if (msb != this.msb) {
                        os.writeMOV(INTSIZE, msb, this.msb);
                        if (lsb != this.msb) {
                            pool.release(this.msb);
                        }
                    }
                    if (lsb != this.lsb) {
                        // invariant: (msb != this.lsb) && (lsb != this.lsb) && (msb
                        // != lsb) && (this.msb != this.lsb)
                        os.writeMOV(INTSIZE, lsb, this.lsb);
                        // if (msb != this.lsb) { <- enforced by first if()
                        pool.release(this.lsb);
                        // }
                    }
                } else if (lsb != this.msb) {
                    // generic case, assignment sequence inverted; avoid only if lsb
                    // is msb' (overwriting)
                    // invariant: (msb == this.lsb) && (lsb != this.msb)
                    // lsb <- lsb'
                    // msb <- msb'
                    // if (lsb != this.lsb) { <- always true, because msb ==
                    // this.lsb
                    os.writeMOV(INTSIZE, lsb, this.lsb);
                    // if (msb != this.lsb) { <- always false, because of invariant
                    // pool.release(this.lsb);
                    // }
                    // }
                    // if (msb != this.msb) { <- always true, because of invariant
                    os.writeMOV(INTSIZE, msb, this.msb);
                    // if (lsb != this.msb) { <- always true, because of invariant
                    pool.release(this.msb);
                    // }
                    // }
                } else {
                    // invariant: (msb == this.lsb) && (lsb == this.msb)
                    // swap registers
                    os.writeXCHG(this.lsb, this.msb);
                }
                break;

            case Kind.LOCAL:
                final int ofs = super.getOffsetToFP(ec);
                os.writeMOV(INTSIZE, lsb, X86Register.EBP, ofs);
                os.writeMOV(INTSIZE, msb, X86Register.EBP, ofs + 4);
                break;

            case Kind.CONSTANT:
                loadToConstant32(ec, os, (GPR32) lsb, (GPR32) msb);
                break;

            case Kind.FPUSTACK:
                // Make sure this item is on top of the FPU stack
                stack.fpuStack.pop(this);
                // Convert & move to new space on normal stack
                os.writeLEA(X86Register.ESP, X86Register.ESP, -8);
                popFromFPU(os, X86Register.ESP, 0);
                os.writePOP(lsb);
                os.writePOP(msb);
                break;

            case Kind.STACK:
                if (VirtualStack.checkOperandStack) {
                    stack.operandStack.pop(this);
                }
                os.writePOP(lsb);
                os.writePOP(msb);
                break;

        }
        setKind(Kind.GPR);
        this.lsb = (GPR32) lsb;
        this.msb = (GPR32) msb;
    }

    /**
     * Load the value of this item into the given registers. Only valid in
     * 64-bit mode.
     *
     * @param ec
     * @param reg
     */
    final void loadTo64(EmitterContext ec, X86Register.GPR64 reg) {
        final X86Assembler os = ec.getStream();
//      final X86RegisterPool pool = ec.getGPRPool();
        final VirtualStack stack = ec.getVStack();
        if (!os.isCode64()) {
            throw new RuntimeException("Can only be used in 64-bit mode.");
        }

        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(reg != null, "reg != null");
        }

        switch (getKind()) {
            case Kind.GPR:
                if (this.reg != reg) {
                    os.writeMOV(BITS64, reg, this.reg);
                    cleanup(ec);
                }
                break;

            case Kind.LOCAL:
                os.writeMOV(BITS64, reg, X86Register.RBP, getOffsetToFP(ec));
                break;

            case Kind.CONSTANT:
                loadToConstant64(ec, os, reg);
                break;

            case Kind.FPUSTACK:
                // Make sure this item is on top of the FPU stack
                stack.fpuStack.pop(this);
                // Convert & move to new space on normal stack
                os.writeLEA(X86Register.RSP, X86Register.RSP, -8);
                popFromFPU(os, X86Register.RSP, 0);
                os.writePOP(reg);
                break;

            case Kind.STACK:
                if (VirtualStack.checkOperandStack) {
                    stack.operandStack.pop(this);
                }
                os.writePOP(reg);
                os.writeLEA(X86Register.RSP, X86Register.RSP, 8); // garbage
                break;

        }
        setKind(Kind.GPR);
        this.reg = reg;
    }

    /**
     * Load my constant to the given os in 32-bit mode.
     *
     * @param ec
     * @param os
     * @param lsb
     * @param msb
     */
    protected abstract void loadToConstant32(EmitterContext ec,
                                             X86Assembler os, GPR32 lsb, GPR32 msb);

    /**
     * Load my constant to the given os in 64-bit mode.
     *
     * @param ec
     * @param os
     * @param reg
     */
    protected abstract void loadToConstant64(EmitterContext ec,
                                             X86Assembler os, GPR64 reg);

    /**
     * Load this item to a general purpose register tuple.
     *
     * @param ec
     */
    final void loadToGPR(EmitterContext ec) {
        if (!isGPR()) {
            final X86Assembler os = ec.getStream();

            if (os.isCode32()) {
                X86Register.GPR lsb = (X86Register.GPR) ec.getGPRPool()
                    .request(JvmType.INT);
                if (lsb == null) {
                    ec.getVStack().push(ec);
                    lsb = (X86Register.GPR) ec.getGPRPool()
                        .request(JvmType.INT);
                }
                if (VmUtils.verifyAssertions())
                    VmUtils._assert(lsb != null, "lsb != null");
                X86Register.GPR msb = (X86Register.GPR) ec.getGPRPool()
                    .request(JvmType.INT);
                if (msb == null) {
                    ec.getVStack().push(ec);
                    msb = (X86Register.GPR) ec.getGPRPool()
                        .request(JvmType.INT);
                }
                if (VmUtils.verifyAssertions())
                    VmUtils._assert(msb != null, "msb != null");
                loadTo32(ec, lsb, msb);
            } else {
                GPR64 r = (GPR64) ec.getGPRPool().request(getType());
                if (r == null) {
                    ec.getVStack().push(ec);
                    r = (GPR64) ec.getGPRPool().request(getType());
                }
                if (VmUtils.verifyAssertions()) {
                    VmUtils._assert(r != null, "r != null");
                }
                loadTo64(ec, r);
            }
        }
    }

    /**
     * Load this item to an XMM register.
     *
     * @param ec
     */
    final void loadToXMM(EmitterContext ec) {
        throw new Error("Not implemented yet");
    }

    /**
     * Pop the top of the FPU stack into the given memory location.
     *
     * @param os
     * @param reg
     * @param disp
     */
    protected abstract void popFromFPU(X86Assembler os, GPR reg, int disp);

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#push(EmitterContext)
     */
    final void push(EmitterContext ec) {
        final X86Assembler os = ec.getStream();
        final VirtualStack stack = ec.getVStack();
        // os.log("LongItem.push "+Integer.toString(getKind()));

        switch (getKind()) {
            case Kind.GPR:
                if (os.isCode32()) {
                    os.writePUSH(msb);
                    os.writePUSH(lsb);
                } else {
                    os.writeLEA(X86Register.RSP, X86Register.RSP, -8); // garbage
                    os.writePUSH(reg);
                }
                break;

            case Kind.LOCAL:
                if (os.isCode32()) {
                    os.writePUSH(X86Register.EBP, getMsbOffsetToFP(ec));
                    os.writePUSH(X86Register.EBP, getLsbOffsetToFP(ec));
                } else {
                    os.writeLEA(X86Register.RSP, X86Register.RSP, -8); // garbage
                    os.writePUSH(X86Register.RBP, getOffsetToFP(ec));
                }
                break;

            case Kind.CONSTANT:
                if (os.isCode64()) {
                    os.writeLEA(X86Register.RSP, X86Register.RSP, -8); // garbage
                }
                pushConstant(ec, os);
                break;

            case Kind.FPUSTACK:
                // Make sure this item is on top of the FPU stack
                final FPUStack fpuStack = stack.fpuStack;
                if (!fpuStack.isTos(this)) {
                    FPUHelper.fxch(os, fpuStack, fpuStack.getRegister(this));
                }
                stack.fpuStack.pop(this);
                // Convert & move to new space on normal stack
                if (os.isCode32()) {
                    os.writeLEA(X86Register.ESP, X86Register.ESP, -8);
                    popFromFPU(os, X86Register.ESP, 0);
                } else {
                    os.writeLEA(X86Register.RSP, X86Register.RSP, -8); // garbage
                    os.writeLEA(X86Register.RSP, X86Register.RSP, -8); // Still 8
                    // bytes
                    popFromFPU(os, X86Register.RSP, 0);
                }
                break;

            case Kind.STACK:
                // nothing to do
                if (VirtualStack.checkOperandStack) {
                    // the item is not really pushed and popped
                    // but this checks that it is really the top
                    // element
                    stack.operandStack.pop(this);
                }
                break;
        }

        cleanup(ec);
        setKind(Kind.STACK);

        if (VirtualStack.checkOperandStack) {
            stack.operandStack.push(this);
        }
    }

    /**
     * Push my constant on the stack using the given os.
     *
     * @param ec
     * @param os
     */
    protected abstract void pushConstant(EmitterContext ec, X86Assembler os);

    /**
     * Push the value at the given memory location on the FPU stack.
     *
     * @param os
     * @param reg
     * @param disp
     */
    protected abstract void pushToFPU(X86Assembler os, GPR reg, int disp);

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#pushToFPU(EmitterContext)
     */
    final void pushToFPU(EmitterContext ec) {
        final X86Assembler os = ec.getStream();
        final VirtualStack stack = ec.getVStack();

        // os.log("LongItem.push "+Integer.toString(getKind()));
        switch (getKind()) {
            case Kind.GPR:
                if (os.isCode32()) {
                    os.writePUSH(msb);
                    os.writePUSH(lsb);
                    pushToFPU(os, X86Register.ESP, 0);
                    os.writeLEA(X86Register.ESP, X86Register.ESP, 8);
                } else {
                    os.writePUSH(reg);
                    pushToFPU(os, X86Register.RSP, 0);
                    os.writeLEA(X86Register.RSP, X86Register.RSP, 8);
                }
                break;

            case Kind.LOCAL:
                if (os.isCode32()) {
                    pushToFPU(os, X86Register.EBP, getLsbOffsetToFP(ec));
                } else {
                    pushToFPU(os, X86Register.RBP, getOffsetToFP(ec));
                }
                break;

            case Kind.CONSTANT:
                pushConstant(ec, os);
                if (os.isCode32()) {
                    pushToFPU(os, X86Register.ESP, 0);
                    os.writeLEA(X86Register.ESP, X86Register.ESP, 8);
                } else {
                    pushToFPU(os, X86Register.RSP, 0);
                    os.writeLEA(X86Register.RSP, X86Register.RSP, 8);
                }
                break;

            case Kind.FPUSTACK:
                // Assert this item is at the top of the stack
                stack.fpuStack.pop(this);
                stack.fpuStack.push(this);
                return;
            // break;

            case Kind.STACK:
                if (VirtualStack.checkOperandStack) {
                    stack.operandStack.pop(this);
                }
                if (os.isCode32()) {
                    pushToFPU(os, X86Register.ESP, 0);
                    os.writeLEA(X86Register.ESP, X86Register.ESP, 8);
                } else {
                    pushToFPU(os, X86Register.RSP, 0);
                    os.writeLEA(X86Register.RSP, X86Register.RSP, 16); // 8-byte + garbage
                }
                break;
        }

        cleanup(ec);
        setKind(Kind.FPUSTACK);
        stack.fpuStack.push(this);
    }

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#release(EmitterContext)
     */
    final void release(EmitterContext ec) {
        cleanup(ec);
        factory.release(this);
    }

    /**
     * @param ec
     * @see org.jnode.vm.x86.compiler.l1a.Item#release(EmitterContext)
     */
    private void cleanup(EmitterContext ec) {
        // assertCondition(!ec.getVStack().contains(this), "Cannot release while
        // on vstack");
        final X86RegisterPool pool = ec.getGPRPool();
        final X86Assembler os = ec.getStream();

        switch (getKind()) {
            case Kind.GPR:
                if (os.isCode32()) {
                    pool.release(lsb);
                    pool.release(msb);
                } else {
                    pool.release(reg);
                }
                break;

            case Kind.LOCAL:
                // nothing to do
                break;

            case Kind.CONSTANT:
                // nothing to do
                break;

            case Kind.FPUSTACK:
                // nothing to do
                break;

            case Kind.STACK:
                // nothing to do
                break;
        }

        this.lsb = null;
        this.msb = null;
        this.reg = null;
        setKind((byte) 0);
    }

    private X86Register request(EmitterContext ec, X86RegisterPool pool) {
        final X86Assembler os = ec.getStream();
        final X86Register r;
        if (os.isCode32()) {
            r = pool.request(JvmType.INT);
        } else {
            r = pool.request(getType());
        }
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(r != null, "r != null");
        }
        return r;
    }

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#spill(EmitterContext, org.jnode.assembler.x86.X86Register)
     */
    final void spill(EmitterContext ec, X86Register reg) {
        final X86Assembler os = ec.getStream();
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(getKind() == Kind.GPR);
            if (os.isCode32()) {
                VmUtils._assert((this.lsb == reg) || (this.msb == reg), "spill1");
            } else {
                VmUtils._assert((this.reg.getNr() == reg.getNr()), "spill1");
            }
        }
        ec.getVStack().push(ec);
        if (isStack()) {
            return;
        }

        final X86RegisterPool pool = ec.getGPRPool();
        if (os.isCode32()) {
            final X86Register.GPR newLsb = (X86Register.GPR) request(ec, pool);
            final X86Register.GPR newMsb = (X86Register.GPR) request(ec, pool);
            loadTo32(ec, newLsb, newMsb);
            pool.transferOwnerTo(newLsb, this);
            pool.transferOwnerTo(newMsb, this);
        } else {
            final GPR64 newReg = (GPR64) request(ec, pool);
            loadTo64(ec, newReg);
            pool.transferOwnerTo(newReg, this);
        }
        if (VmUtils.verifyAssertions()) {
            verifyState(ec);
        }
    }

    /**
     * @see org.jnode.vm.x86.compiler.l1a.Item#uses(org.jnode.assembler.x86.X86Register)
     */
    final boolean uses(X86Register reg) {
        return (isGPR() && ((this.msb == reg) || (this.lsb == reg) || (this.reg == reg)));
    }

    /**
     * enquire whether the item uses a volatile register
     *
     * @param pool
     * @return true, when this item uses a volatile register.
     */
    final boolean usesVolatileRegister(X86RegisterPool pool) {
        if (isGPR()) {
            if (reg == null) {
                // 32-bit
                return (!(pool.isCallerSaved(lsb) && pool.isCallerSaved(msb)));
            } else {
                // 64-bit
                return (!(pool.isCallerSaved(reg)));
            }
        }
        return false;
    }

    /**
     * Verify the consistency of the state of this item. Throw an exception is
     * the state is inconsistent.
     */
    protected void verifyState(EmitterContext ec) {
        switch (getKind()) {
            case Kind.GPR:
                if (ec.getStream().isCode32()) {
                    if (lsb == null) {
                        throw new IllegalStateException("lsb cannot be null");
                    }
                    if (msb == null) {
                        throw new IllegalStateException("msb cannot be null");
                    }
                } else {
                    if (reg == null) {
                        throw new IllegalStateException("reg cannot be null");
                    }
                }
                break;
        }
    }
}
TOP

Related Classes of org.jnode.vm.x86.compiler.l1a.DoubleWordItem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.