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