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

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

/*
* $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.X86Register;
import org.jnode.vm.facade.Vm;
import org.jnode.vm.facade.VmUtils;

/**
* This class is the base of all virtual stack items. To improve performance and
* avoid type casts, all accessor methods are defined here (as abstract),
* subclasses shall only implement those that make sense to them and throw an
* exception otherwise (i.e. a reference item cannot implement load64 in any
* meaningful way). The compiler knows about the various types and must access
* only the legal methods.
*
* @author Patrik Reali
*         <p/>
*         TODO: make Item a subclass of operand
*/
abstract class Item {

    /**
     * Description of the virtual stack entry kind;
     * <p/>
     * An item has only one kind; flags are used for masking purposes (detect
     * multiple kinds in one operation)
     */
    static class Kind {

        /**
         * Item is constant
         */
        static final byte CONSTANT = 0x01;

        /**
         * Item is in a general purpose register
         */
        static final byte GPR = 0x02;

        /**
         * Item is in a SSE register
         */
        static final byte XMM = 0x04;

        /**
         * Item is on the FPU stack
         */
        static final byte FPUSTACK = 0x08;

        /**
         * Item is on the stack
         */
        static final byte STACK = 0x10;

        /**
         * Item is a local variable (EBP relative)
         */
        static final byte LOCAL = 0x20;

        public static String toString(int kind) {
            switch (kind) {
                case STACK:
                    return "STACK";
                case GPR:
                    return "GPR";
                case XMM:
                    return "XMM";
                case FPUSTACK:
                    return "FPU";
                case LOCAL:
                    return "LOCAL";
                case CONSTANT:
                    return "CONST";
                default:
                    return String.valueOf(kind);
            }
        }
    }

    /*
      * Virtual Stack Item
      */
    private byte kind; // entry kind

    /**
     * Only valid for (kind == local)
     */
    private short offsetToFP;

    /**
     * Only valid for (kind == xmm)
     */
    protected X86Register.XMM xmm;

    /**
     * The factory that created me
     */
    protected final ItemFactory factory;

    /**
     * Initialize a blank item.
     *
     * @param factory
     */
    protected Item(ItemFactory factory) {
        this.factory = factory;
        if (false) {
            final Vm vm = VmUtils.getVm();
            final String name = getClass().getName();
            vm.getCounterGroup(name).getCounter("new").inc();
        }
    }

    /**
     * Initialize this instance.
     *
     * @param kind
     * @param offsetToFP
     * @param xmm
     */
    protected final void initialize(byte kind, short offsetToFP, X86Register.XMM xmm) {
        if (VmUtils.verifyAssertions()) VmUtils._assert(kind > 0, "Invalid kind");
        this.kind = kind;
        this.offsetToFP = offsetToFP;
        this.xmm = xmm;
    }

    /**
     * Throw a not implemented error.
     */
    static void notImplemented() {
        throw new Error("NotImplemented");
    }

    /**
     * Get the JVM type of this item
     *
     * @return the JVM type
     */
    abstract int getType();

    /**
     * Get the item kind (STACK, GPR, ....)
     *
     * @return the item kind
     */
    final byte getKind() {
        return kind;
    }

    /**
     * Gets the weight of the item kind (STACK, GPR, ....).
     * Kind weight is sorted from constant, gpr, xmm, fp, stack to local.
     *
     * @return the item kind weight
     */
    final int getKindWeight() {
        return kind;
    }

    /**
     * Sets the kind of this item.
     *
     * @param kind
     */
    protected final void setKind(byte kind) {
        this.kind = kind;
    }

    /**
     * Is this item on the stack
     *
     * @return
     */
    final boolean isStack() {
        return (kind == Kind.STACK);
    }

    /**
     * Is this item in a general purpose register
     *
     * @return
     */
    final boolean isGPR() {
        return (kind == Kind.GPR);
    }

    /**
     * Is this item in a SSE register
     *
     * @return
     */
    final boolean isXMM() {
        return (kind == Kind.XMM);
    }

    /**
     * Is this item on the FPU stack
     *
     * @return
     */
    final boolean isFPUStack() {
        return (kind == Kind.FPUSTACK);
    }

    /**
     * Is this item a local variable
     *
     * @return
     */
    final boolean isLocal() {
        return (kind == Kind.LOCAL);
    }

    /**
     * Is this item a constant
     *
     * @return
     */
    final boolean isConstant() {
        return (kind == Kind.CONSTANT);
    }

    /**
     * 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
     */
    int getCategory() {
        return 1;
    }

    /**
     * Gets the offset from this item to the FramePointer register. This is only
     * valid if this item has a LOCAL kind.
     *
     * @param ec
     * @return
     */
    short getOffsetToFP(EmitterContext ec) {
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(isLocal(), "kind == Kind.LOCAL");
        }
        return offsetToFP;
    }

    /**
     * Gets the xmm register containing this item.
     * This is only valid if this item has a XMM kind.
     *
     * @return
     */
    final X86Register.XMM getXMM() {
        if (VmUtils.verifyAssertions()) {
            VmUtils._assert(isXMM(), "kind == Kind.XMM");
        }
        return xmm;
    }

    /**
     * Is this item located at the given FP offset.
     *
     * @param offset
     * @return
     */
    boolean isAtOffset(int offset) {
        if (VmUtils.verifyAssertions()) VmUtils._assert(kind == Kind.LOCAL, "kind == Kind.LOCAL");
        return (offsetToFP == offset);
    }

    /**
     * Load item into a register / two registers / an FPU register depending on
     * its type.
     *
     * @param ec the EmitterContext
     */
    abstract void load(EmitterContext ec);

    /**
     * Load this item to a general purpose register(s).
     *
     * @param ec
     */
    abstract void loadToGPR(EmitterContext ec);

    /**
     * Load this item to an XMM register.
     *
     * @param ec
     */
    abstract void loadToXMM(EmitterContext ec);

    /**
     * Load item into a register / two registers / an FPU register depending on
     * its type, if its kind matches the mask
     *
     * @param eContext
     * @param mask
     */
    final void loadIf(EmitterContext eContext, int mask) {
        if ((kind & mask) > 0) {
            load(eContext);
        }
    }

    /**
     * Load item into an XMM register if its kind matches the mask
     *
     * @param eContext
     * @param mask
     */
    final void loadToXMMIf(EmitterContext eContext, int mask) {
        if ((kind & mask) > 0) {
            loadToXMM(eContext);
        }
    }

    /**
     * Clone item
     *
     * @param ec the EmitterContext
     * @return a clone of the item
     */
    abstract Item clone(EmitterContext ec);

    /**
     * Push item onto the stack
     *
     * @param ec the EmitterContext
     */
    abstract void push(EmitterContext ec);

    /**
     * Push the value of this item on the FPU stack. The item itself is not
     * changed in any way.
     *
     * @param ec
     */
    abstract void pushToFPU(EmitterContext ec);

    /**
     * Release the registers associated to this item
     *
     * @param ec the EmitterContext
     */
    abstract void release(EmitterContext ec);

    /**
     * Is this obsolete?
     *
     * @param ec
     */
    final void release1(EmitterContext ec) {
        if (VirtualStack.checkOperandStack) {
            VirtualStack vs = ec.getVStack();
            vs.operandStack.pop(this);
        }
        release(ec);
    }

    /**
     * Spill the registers associated to this item
     *
     * @param ec  the EmitterContext
     * @param reg the register to be spilled
     */
    abstract void spill(EmitterContext ec, X86Register reg);

    /**
     * Spill this item if it uses the given register.
     *
     * @param ec
     * @param reg
     */
    final void spillIfUsing(EmitterContext ec, X86Register reg) {
        if (uses(reg)) {
            spill(ec, reg);
        }
    }

    /**
     * enquire whether the item uses this register
     *
     * @param reg
     * @return true, when reg is used by this item
     */
    abstract boolean uses(X86Register reg);

    /**
     * enquire whether the item uses a volatile register
     *
     * @param pool
     * @return true, when this item uses a volatile register.
     */
    abstract boolean usesVolatileRegister(X86RegisterPool pool);

    /**
     * Verify the consistency of the state of this item.
     * Throw an exception is the state is inconsistent.
     *
     * @param ec
     */
    protected abstract void verifyState(EmitterContext ec);

    public String toString() {
        return getType() + "," + getKind() + " ("
            + System.identityHashCode(this) + ')';
    }
}
TOP

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

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.