/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt.ir.operand.ia32; import org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants; import org.jikesrvm.compilers.opt.OptimizingCompilerException; import org.jikesrvm.compilers.opt.ir.operand.ConditionOperand; import org.jikesrvm.compilers.opt.ir.operand.Operand; /** * An IA32 condition operand */ public final class IA32ConditionOperand extends Operand implements AssemblerConstants { /** * Value of this operand (one of the ConditionCode constants operands * defined in AssemblerConstants) */ public byte value; /** * Returns a copy of the current operand. */ public Operand copy() { return new IA32ConditionOperand(value); } /** * Returns if this operand is the 'same' as another operand. * * @param op other operand */ public boolean similar(Operand op) { return (op instanceof IA32ConditionOperand) && ((IA32ConditionOperand) op).value == value; } /** * flip the direction of the condition (return this, mutated to flip value) */ public IA32ConditionOperand flipCode() { switch (value) { case O: value = NO; break; case NO: value = O; break; case LLT: value = LGE; break; case LGE: value = LLT; break; case EQ: value = NE; break; case NE: value = EQ; break; case LLE: value = LGT; break; case LGT: value = LLE; break; case S: value = NS; break; case NS: value = S; break; case PE: value = PO; break; case PO: value = PE; break; case LT: value = GE; break; case GE: value = LT; break; case LE: value = GT; break; case GT: value = LE; break; default: OptimizingCompilerException.UNREACHABLE(); } return this; } /** * change the condition when operands are flipped * (return this mutated to change value) */ public IA32ConditionOperand flipOperands() { switch (value) { case LLT: value = LGT; break; case LGE: value = LLE; break; case LLE: value = LGE; break; case LGT: value = LLT; break; case LT: value = GT; break; case GE: value = LE; break; case LE: value = GE; break; case GT: value = LT; break; default: OptimizingCompilerException.TODO(); } return this; } /** * Construct the IA32 Condition Operand that corresponds to the * argument ConditionOperand */ public IA32ConditionOperand(ConditionOperand c) { translate(c); } public static IA32ConditionOperand EQ() { return new IA32ConditionOperand(EQ); } public static IA32ConditionOperand NE() { return new IA32ConditionOperand(NE); } public static IA32ConditionOperand LT() { return new IA32ConditionOperand(LT); } public static IA32ConditionOperand LE() { return new IA32ConditionOperand(LE); } public static IA32ConditionOperand GT() { return new IA32ConditionOperand(GT); } public static IA32ConditionOperand GE() { return new IA32ConditionOperand(GE); } public static IA32ConditionOperand O() { return new IA32ConditionOperand(O); } public static IA32ConditionOperand NO() { return new IA32ConditionOperand(NO); } public static IA32ConditionOperand LGT() { return new IA32ConditionOperand(LGT); } public static IA32ConditionOperand LLT() { return new IA32ConditionOperand(LLT); } public static IA32ConditionOperand LGE() { return new IA32ConditionOperand(LGE); } public static IA32ConditionOperand LLE() { return new IA32ConditionOperand(LLE); } public static IA32ConditionOperand PE() { return new IA32ConditionOperand(PE); } public static IA32ConditionOperand PO() { return new IA32ConditionOperand(PO); } private IA32ConditionOperand(byte c) { value = c; } // translate from ConditionOperand: used during LIR => MIR translation private void translate(ConditionOperand c) { switch (c.value) { case ConditionOperand.EQUAL: value = EQ; break; case ConditionOperand.NOT_EQUAL: value = NE; break; case ConditionOperand.LESS: value = LT; break; case ConditionOperand.LESS_EQUAL: value = LE; break; case ConditionOperand.GREATER: value = GT; break; case ConditionOperand.GREATER_EQUAL: value = GE; break; case ConditionOperand.HIGHER: value = LGT; break; case ConditionOperand.LOWER: value = LLT; break; case ConditionOperand.HIGHER_EQUAL: value = LGE; break; case ConditionOperand.LOWER_EQUAL: value = LLE; break; case ConditionOperand.CMPL_EQUAL: case ConditionOperand.CMPL_GREATER: case ConditionOperand.CMPG_LESS: case ConditionOperand.CMPL_GREATER_EQUAL: case ConditionOperand.CMPG_LESS_EQUAL: case ConditionOperand.CMPL_NOT_EQUAL: case ConditionOperand.CMPL_LESS: case ConditionOperand.CMPG_GREATER_EQUAL: case ConditionOperand.CMPG_GREATER: case ConditionOperand.CMPL_LESS_EQUAL: throw new Error("IA32ConditionOperand.translate: Complex operand can't be directly translated " + c); default: OptimizingCompilerException.UNREACHABLE(); } } // Returns the string representation of this operand. public String toString() { return CONDITION[value]; } }