/* * 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.ppc; import org.jikesrvm.compilers.opt.ir.operand.ConditionOperand; import org.jikesrvm.compilers.opt.ir.operand.Operand; /** * Encodes the BO & BI condition fields for PowerPC * * @see Operand */ public final class PowerPCConditionOperand extends Operand { public static final int ALWAYS = (20 << 5); public static final int EQUAL = (12 << 5) | 2; public static final int NOT_EQUAL = (4 << 5) | 2; public static final int LESS = (12 << 5) | 0; public static final int GREATER_EQUAL = (4 << 5) | 0; public static final int GREATER = (12 << 5) | 1; public static final int LESS_EQUAL = (4 << 5) | 1; public static final int OVERFLOW = (12 << 5) | 3; public static final int NOT_OVERFLOW = (4 << 5) | 3; /* interpretation for floating-point values */ public static final int UNORDERED = (12 << 5) | 3; public static final int NOT_UNORDERED = (4 << 5) | 3; // --CTR == 0 public static final int CTRZ = (17 << 5) | 0; // --CTR != 0 public static final int CTRNZ = (16 << 5) | 0; // (--CTR == 0) & condition public static final int CTRZ_EQUAL = (10 << 5) | 2; public static final int CTRZ_NOT_EQUAL = (2 << 5) | 2; public static final int CTRZ_LESS = (10 << 5) | 0; public static final int CTRZ_GREATER_EQUAL = (2 << 5) | 0; public static final int CTRZ_GREATER = (10 << 5) | 1; public static final int CTRZ_LESS_EQUAL = (2 << 5) | 1; public static final int CTRZ_OVERFLOW = (10 << 5) | 3; public static final int CTRZ_NOT_OVERFLOW = (2 << 5) | 3; // (--CTR != 0) & condition public static final int CTRNZ_EQUAL = (8 << 5) | 2; public static final int CTRNZ_NOT_EQUAL = (0 << 5) | 2; public static final int CTRNZ_LESS = (8 << 5) | 0; public static final int CTRNZ_GREATER_EQUAL = (0 << 5) | 0; public static final int CTRNZ_GREATER = (8 << 5) | 1; public static final int CTRNZ_LESS_EQUAL = (0 << 5) | 1; public static final int CTRNZ_OVERFLOW = (8 << 5) | 3; public static final int CTRNZ_NOT_OVERFLOW = (0 << 5) | 3; /** * Value of this operand. */ public int value; // TODO: add the things with the CTR register also. public PowerPCConditionOperand(int Code) { value = Code; } public static PowerPCConditionOperand EQUAL() { return new PowerPCConditionOperand(EQUAL); } public static PowerPCConditionOperand NOT_EQUAL() { return new PowerPCConditionOperand(NOT_EQUAL); } public static PowerPCConditionOperand LESS() { return new PowerPCConditionOperand(LESS); } public static PowerPCConditionOperand LESS_EQUAL() { return new PowerPCConditionOperand(LESS_EQUAL); } public static PowerPCConditionOperand GREATER() { return new PowerPCConditionOperand(GREATER); } public static PowerPCConditionOperand GREATER_EQUAL() { return new PowerPCConditionOperand(GREATER_EQUAL); } public static PowerPCConditionOperand UNORDERED() { return new PowerPCConditionOperand(UNORDERED); } public static PowerPCConditionOperand get(ConditionOperand cond) { return new PowerPCConditionOperand(cond); } public Operand copy() { return new PowerPCConditionOperand(value); } public boolean similar(Operand op) { return (op instanceof PowerPCConditionOperand) && (((PowerPCConditionOperand) op).value == value); } /** * flips the direction of the condition */ public PowerPCConditionOperand flipCode() { switch (value) { case EQUAL: value = NOT_EQUAL; break; case NOT_EQUAL: value = EQUAL; break; case LESS: value = GREATER_EQUAL; break; case LESS_EQUAL: value = GREATER; break; case GREATER: value = LESS_EQUAL; break; case GREATER_EQUAL: value = LESS; break; case OVERFLOW: value = NOT_OVERFLOW; break; case NOT_OVERFLOW: value = OVERFLOW; break; case CTRZ: value = CTRNZ; break; case CTRNZ: value = CTRZ; break; default: throw new org.jikesrvm.compilers.opt.OptimizingCompilerException("Unhandled case in flipCode"); } return this; } /** * this could be used if you want to flip the order of the operands * you will notice that there are some differences */ public PowerPCConditionOperand flipOperands() { switch (value) { case EQUAL: value = NOT_EQUAL; break; case NOT_EQUAL: value = EQUAL; break; case LESS: value = GREATER; break; case LESS_EQUAL: value = GREATER_EQUAL; break; case GREATER: value = LESS; break; case GREATER_EQUAL: value = LESS_EQUAL; break; case OVERFLOW: value = NOT_OVERFLOW; break; case NOT_OVERFLOW: value = OVERFLOW; break; // TODO remaining } return this; } public PowerPCConditionOperand(ConditionOperand c) { translate(c); } /** * translate from ConditionOperand: used by BURS */ public void translate(ConditionOperand c) { switch (c.value) { case ConditionOperand.EQUAL: case ConditionOperand.CMPL_EQUAL: value = EQUAL; break; case ConditionOperand.NOT_EQUAL: case ConditionOperand.CMPL_NOT_EQUAL: // Extra unordered test required value = NOT_EQUAL; break; case ConditionOperand.LESS: case ConditionOperand.LOWER: case ConditionOperand.CMPG_LESS: case ConditionOperand.CMPL_LESS: // Extra unordered test required value = LESS; break; case ConditionOperand.LESS_EQUAL: case ConditionOperand.LOWER_EQUAL: case ConditionOperand.CMPG_LESS_EQUAL: case ConditionOperand.CMPL_LESS_EQUAL: // Extra unordered test required value = LESS_EQUAL; break; case ConditionOperand.GREATER: case ConditionOperand.HIGHER: case ConditionOperand.CMPL_GREATER: case ConditionOperand.CMPG_GREATER: // Extra unordered test required value = GREATER; break; case ConditionOperand.GREATER_EQUAL: case ConditionOperand.HIGHER_EQUAL: case ConditionOperand.CMPL_GREATER_EQUAL: case ConditionOperand.CMPG_GREATER_EQUAL: // Extra unordered test required value = GREATER_EQUAL; break; default: org.jikesrvm.compilers.opt.OptimizingCompilerException.UNREACHABLE(); } } /** * Returns the string representation of this operand. */ public String toString() { String result = "ppc "; if ((value & 0x1C0) == 0) { result = result + "--ctr!=0 && "; } if ((value & 0x1C0) == 0x40) { result = result + "--ctr==0 && "; } String temp = null; if ((value & 0x300) == 0x100) { // true switch (value & 0x3) { case 0: temp = "<"; break; case 1: temp = ">"; break; case 2: temp = "=="; break; case 3: temp = "overflow"; break; } } if ((value & 0x300) == 0x000) { // false switch (value & 0x3) { case 0: temp = ">="; break; case 1: temp = "<="; break; case 2: temp = "!="; break; case 3: temp = "not_overflow"; break; } } return result + temp; } }