binaryquad.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 513 行 · 第 1/2 页

JAVA
513
字号
/*
 * $Id: BinaryQuad.java,v 1.8 2004/02/19 17:28:59 lsantha Exp $
 *
 * mailto:madhu@madhu.com
 */
package org.jnode.vm.compiler.ir.quad;

import org.jnode.util.BootableHashMap;
import org.jnode.vm.compiler.ir.CodeGenerator;
import org.jnode.vm.compiler.ir.Constant;
import org.jnode.vm.compiler.ir.IRBasicBlock;
import org.jnode.vm.compiler.ir.Operand;
import org.jnode.vm.compiler.ir.RegisterLocation;
import org.jnode.vm.compiler.ir.StackLocation;
import org.jnode.vm.compiler.ir.Variable;

/**
 *
 * This class represents binary operations of the form:
 *
 *   lhs = operand1 operation operand2, where operation is +, -, <<, |, && etc.
 *
 * The left hand side (lhs) is a Variable inherited from AssignQuad.
 *
 * @author Madhu Siddalingaiah
 * @author Levente S醤tha
 */
public class BinaryQuad extends AssignQuad {
	private static final String[] OP_MAP = {
		"+", "+", "+", "+",
		"-", "-", "-", "-",
		"*", "*", "*", "*",
		"/", "/", "/", "/",
		"%", "%", "%", "%",
		"<<", "<<",
		">>", ">>",
		">>>", ">>>",
		"&", "&",
		"|", "|",
		"^", "^",
	};
	public static final int IADD = 1;
	public static final int LADD = 2;
	public static final int FADD = 3;
	public static final int DADD = 4;
	public static final int ISUB = 5;
	public static final int LSUB = 6;
	public static final int FSUB = 7;
	public static final int DSUB = 8;
	public static final int IMUL = 9;
	public static final int LMUL = 10;
	public static final int FMUL = 11;
	public static final int DMUL = 12;
	public static final int IDIV = 13;
	public static final int LDIV = 14;
	public static final int FDIV = 15;
	public static final int DDIV = 16;
	public static final int IREM = 17;
	public static final int LREM = 18;
	public static final int FREM = 19;
	public static final int DREM = 20;
	public static final int ISHL = 21;
	public static final int LSHL = 22;
	public static final int ISHR = 23;
	public static final int LSHR = 24;
	public static final int IUSHR = 25;
	public static final int LUSHR = 26;
	public static final int IAND = 27;
	public static final int LAND = 28;
	public static final int IOR = 29;
	public static final int LOR = 30;
	public static final int IXOR = 31;
	public static final int LXOR = 32;

	/*
	 * These are used to simplify addressing mode testing
	 */
	private static final int MODE_RCC = (Operand.MODE_REGISTER << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_RCR = (Operand.MODE_REGISTER << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_REGISTER;
	private static final int MODE_RCS = (Operand.MODE_REGISTER << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_STACK;
	private static final int MODE_RRC = (Operand.MODE_REGISTER << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_RRR = (Operand.MODE_REGISTER << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_REGISTER;
	private static final int MODE_RRS = (Operand.MODE_REGISTER << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_STACK;
	private static final int MODE_RSC = (Operand.MODE_REGISTER << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_RSR = (Operand.MODE_REGISTER << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_REGISTER;
	private static final int MODE_RSS = (Operand.MODE_REGISTER << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_STACK;
	private static final int MODE_SCC = (Operand.MODE_STACK << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_SCR = (Operand.MODE_STACK << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_REGISTER;
	private static final int MODE_SCS = (Operand.MODE_STACK << 16) | (Operand.MODE_CONSTANT << 8) | Operand.MODE_STACK;
	private static final int MODE_SRC = (Operand.MODE_STACK << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_SRR = (Operand.MODE_STACK << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_REGISTER;
	private static final int MODE_SRS = (Operand.MODE_STACK << 16) | (Operand.MODE_REGISTER << 8) | Operand.MODE_STACK;
	private static final int MODE_SSC = (Operand.MODE_STACK << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_CONSTANT;
	private static final int MODE_SSR = (Operand.MODE_STACK << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_REGISTER;
	private static final int MODE_SSS = (Operand.MODE_STACK << 16) | (Operand.MODE_STACK << 8) | Operand.MODE_STACK;

	private Operand operand1, operand2;
	private int operation;
	private Operand refs[];
	private boolean commutative;

	/**
	 * @param address
	 * @param block
	 * @param lhsIndex
	 */
	public BinaryQuad(int address, IRBasicBlock block, int lhsIndex,
		int varIndex1, int operation, int varIndex2) {

		super(address, block, lhsIndex);
		this.operand1 = getOperand(varIndex1);
		this.operation = operation;
		this.operand2 = getOperand(varIndex2);
		refs = new Operand[] { operand1, operand2 };
		doSSA();
		this.commutative =
			operation == IADD || operation == IMUL ||
			operation == LADD || operation == LMUL ||
			operation == FADD || operation == FMUL ||
			operation == DADD || operation == DMUL ||
			operation == IAND || operation == LAND ||
			operation == IOR  || operation == LOR  ||
			operation == IXOR || operation == LXOR;
	}

	public BinaryQuad(int address, IRBasicBlock block, int lhsIndex,
		int varIndex1, int operation, Operand op2) {

		super(address, block, lhsIndex);
		this.operand1 = getOperand(varIndex1);
		this.operation = operation;
		this.operand2 = op2;
		refs = new Operand[] { operand1, operand2 };
		doSSA();
		this.commutative =
			operation == IADD || operation == IMUL ||
			operation == LADD || operation == LMUL ||
			operation == FADD || operation == FMUL ||
			operation == DADD || operation == DMUL ||
			operation == IAND || operation == LAND ||
			operation == IOR  || operation == LOR  ||
			operation == IXOR || operation == LXOR;
	}

	/**
	 * @see org.jnode.vm.compiler.ir.quad.Quad#getReferencedOps()
	 */
	public Operand[] getReferencedOps() {
		return refs;
	}

	/**
	 * @return
	 */
	public Operand getOperand1() {
		return operand1;
	}

	/**
	 * @return
	 */
	public Operand getOperand2() {
		return operand2;
	}

	/**
	 * @return
	 */
	public int getOperation() {
		return operation;
	}

	public String toString() {
		return getAddress() + ": " + getLHS().toString() + " = " +
			operand1.toString() + " " + OP_MAP[operation - IADD] +
			" " + operand2.toString();
	}

	/**
	 * If operand1 and operand2 are both Constants, then fold them.
	 *
	 * @return resulting Quad after folding
	 */
	public Quad foldConstants() {
		if (operand1 instanceof Constant && operand2 instanceof Constant) {
			Constant c1 = (Constant) operand1;
			Constant c2 = (Constant) operand2;
			switch (operation) {
				case IADD:
					return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
						this.getLHS().getIndex(), c1.iAdd(c2));

				case ISUB:
					return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
						this.getLHS().getIndex(), c1.iSub(c2));

				case IMUL:
					return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
						this.getLHS().getIndex(), c1.iMul(c2));

				case IDIV:
					return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
						this.getLHS().getIndex(), c1.iDiv(c2));

                case IREM:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iRem(c2));

                case IAND:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iAnd(c2));

                case IOR:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iOr(c2));

                case IXOR:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iXor(c2));

                case ISHL:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iShl(c2));

                case ISHR:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iShr(c2));

                case IUSHR:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.iUshr(c2));

                case LADD:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lAdd(c2));

                case LSUB:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lSub(c2));

                case LMUL:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lMul(c2));

                case LDIV:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lDiv(c2));

                case LREM:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lRem(c2));

                case LAND:
                    return new ConstantRefAssignQuad(this.getAddress(), this.getBasicBlock(),
                        this.getLHS().getIndex(), c1.lAnd(c2));

                case LOR:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?