/* * 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 static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.CONDITION; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.EQ; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.GE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.GT; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LGE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LGT; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LLE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LLT; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.LT; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.NE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.NO; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.NS; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.O; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.PE; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.PO; import static org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants.S; 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 { /** * Value of this operand (one of the ConditionCode constants operands * defined in AssemblerConstants) */ public byte value; @Override public Operand copy() { return new IA32ConditionOperand(value); } @Override 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; } /** * Constructs the IA32 Condition Operand that corresponds to the * argument ConditionOperand. * * @param c the template */ 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: case ConditionOperand.CARRY_FROM_ADD: case ConditionOperand.BORROW_FROM_SUB: case ConditionOperand.BORROW_FROM_RSUB: case ConditionOperand.BIT_TEST: case ConditionOperand.RBIT_TEST: value = LLT; break; case ConditionOperand.HIGHER_EQUAL: case ConditionOperand.NO_CARRY_FROM_ADD: case ConditionOperand.NO_BORROW_FROM_SUB: case ConditionOperand.NO_BORROW_FROM_RSUB: case ConditionOperand.NO_BIT_TEST: case ConditionOperand.NO_RBIT_TEST: value = LGE; break; case ConditionOperand.LOWER_EQUAL: value = LLE; break; case ConditionOperand.OVERFLOW_FROM_ADD: case ConditionOperand.OVERFLOW_FROM_SUB: case ConditionOperand.OVERFLOW_FROM_RSUB: case ConditionOperand.OVERFLOW_FROM_MUL: value = O; break; case ConditionOperand.NO_OVERFLOW_FROM_ADD: case ConditionOperand.NO_OVERFLOW_FROM_SUB: case ConditionOperand.NO_OVERFLOW_FROM_RSUB: case ConditionOperand.NO_OVERFLOW_FROM_MUL: value = NO; 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. @Override public String toString() { return CONDITION[value]; } }