From c12d618640ee9c35b8325d86a75d0c083e0a2aa5 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 22 Apr 2009 12:32:02 +0100 Subject: [PATCH] Introduce condition operations based on the results of integer arithmetic operations. --- .../opt/ir/operand/ConditionOperand.java | 1052 ++++++++++------- 1 file changed, 639 insertions(+), 413 deletions(-) diff --git a/rvm/src/org/jikesrvm/compilers/opt/ir/operand/ConditionOperand.java b/rvm/src/org/jikesrvm/compilers/opt/ir/operand/ConditionOperand.java index d8d21fce7..6f4fd184b 100644 --- a/rvm/src/org/jikesrvm/compilers/opt/ir/operand/ConditionOperand.java +++ b/rvm/src/org/jikesrvm/compilers/opt/ir/operand/ConditionOperand.java @@ -24,42 +24,105 @@ public final class ConditionOperand extends Operand { /* signed integer arithmetic */ - public static final int EQUAL = 0; - public static final int NOT_EQUAL = 1; - public static final int LESS = 2; - public static final int GREATER_EQUAL = 3; - public static final int GREATER = 4; - public static final int LESS_EQUAL = 5; + /** Integer equal == */ + public static final int EQUAL = 0; + /** Integer not equal != */ + public static final int NOT_EQUAL = 1; + /** Signed integer < */ + public static final int LESS = 2; + /** Signed integer >= */ + public static final int GREATER_EQUAL = 3; + /** Signed integer > */ + public static final int GREATER = 4; + /** Signed integer <= */ + public static final int LESS_EQUAL = 5; /* unsigned integer arithmetic */ - public static final int HIGHER = 6; - public static final int LOWER = 7; - public static final int HIGHER_EQUAL = 8; - public static final int LOWER_EQUAL = 9; + /** Unsigned integer > - >U */ + public static final int HIGHER = 6; + /** Unsigned integer < - <U */ + public static final int LOWER = 7; + /** Unsigned integer >= - >=U */ + public static final int HIGHER_EQUAL = 8; + /** Unsigned integer <= - <=U */ + public static final int LOWER_EQUAL = 9; /* floating-point arithmethic */ // branches that fall through when unordered - /** Branch if == (equivalent to CMPG_EQUAL) */ - public static final int CMPL_EQUAL = 10; - /** Branch if > */ - public static final int CMPL_GREATER = 11; - /** Branch if < */ - public static final int CMPG_LESS = 12; - /** Branch if >= */ + /** Branch if == (equivalent to CMPG_EQUAL) - ==F */ + public static final int CMPL_EQUAL = 10; + /** Branch if > - >F */ + public static final int CMPL_GREATER = 11; + /** Branch if < - <F */ + public static final int CMPG_LESS = 12; + /** Branch if >= - >=F */ public static final int CMPL_GREATER_EQUAL = 13; - /** Branch if <= */ - public static final int CMPG_LESS_EQUAL = 14; + /** Branch if <= - <=F */ + public static final int CMPG_LESS_EQUAL = 14; + // branches that are taken when unordered - /** Branch if != (equivalent to CMPG_NOT_EQUAL) */ - public static final int CMPL_NOT_EQUAL = 17; - /** Branch if < or unordered */ - public static final int CMPL_LESS = 18; - /** Branch if >= or unordered */ - public static final int CMPG_GREATER_EQUAL = 19; - /** Branch if > or unordered */ - public static final int CMPG_GREATER = 20; - /** Branch if <= or unordered */ - public static final int CMPL_LESS_EQUAL = 21; + /** Branch if != (equivalent to CMPG_NOT_EQUAL) - !=FU */ + public static final int CMPL_NOT_EQUAL = 15; + /** Branch if < or unordered - <FU */ + public static final int CMPL_LESS = 16; + /** Brach if >= or unordered - >=FU */ + public static final int CMPG_GREATER_EQUAL = 17; + /** Branch if > or unordered - >FU */ + public static final int CMPG_GREATER = 18; + /** Branch if <= or unordered - <=FU */ + public static final int CMPL_LESS_EQUAL = 19; + + + /* integer arithmetic flag operations */ + /** Would a+b produce a carry? */ + public static final int CARRY_FROM_ADD = 20; + /** Would a+b not produce a carry? */ + public static final int NO_CARRY_FROM_ADD = 21; + + /** Would a+b cause an overflow? */ + public static final int OVERFLOW_FROM_ADD = 22; + /** Would a+b not cause an overflow? */ + public static final int NO_OVERFLOW_FROM_ADD = 23; + + /** Would a-b produce a borrow? */ + public static final int BORROW_FROM_SUB = 24; + /** Would a-b not produce a borrow? */ + public static final int NO_BORROW_FROM_SUB = 25; + /** Would b-a produce a borrow? */ + public static final int BORROW_FROM_RSUB = 26; + /** Would b-a not produce a borrow? */ + public static final int NO_BORROW_FROM_RSUB = 27; + + /** Would a-b cause an overflow? */ + public static final int OVERFLOW_FROM_SUB = 28; + /** Would a-b not cause an overflow? */ + public static final int NO_OVERFLOW_FROM_SUB = 29; + /** Would b-a cause an overflow? */ + public static final int OVERFLOW_FROM_RSUB = 30; + /** Would b-a not cause an overflow? */ + public static final int NO_OVERFLOW_FROM_RSUB = 31; + + /** Would is bit b set in a? */ + public static final int BIT_TEST = 32; + /** Would is bit b not set in a? */ + public static final int NO_BIT_TEST = 33; + /** Would is bit a set in b? */ + public static final int RBIT_TEST = 34; + /** Would is bit a not set in b? */ + public static final int NO_RBIT_TEST = 35; + + /** Would a*b cause an overflow? */ + public static final int OVERFLOW_FROM_MUL = 36; + /** Would a*b not cause an overflow? */ + public static final int NO_OVERFLOW_FROM_MUL = 37; + + /* Results from evaluations */ + /** Evaluation result is false */ + public static final int FALSE = 0; + /** Evaluation result is true */ + public static final int TRUE = 1; + /** Evaluation result is unknown */ + public static final int UNKNOWN = 2; /** * Value of this operand. @@ -163,6 +226,139 @@ public static ConditionOperand LOWER_EQUAL() { return new ConditionOperand(LOWER_EQUAL); } + /** + * Create the condition code operand for CARRY_FROM_ADD + * + * @return a newly created condition code operand + */ + public static ConditionOperand CARRY_FROM_ADD() { + return new ConditionOperand(CARRY_FROM_ADD); + } + + /** + * Create the condition code operand for OVERFLOW_FROM_ADD + * + * @return a newly created condition code operand + */ + public static ConditionOperand OVERFLOW_FROM_ADD() { + return new ConditionOperand(OVERFLOW_FROM_ADD); + } + + /** + * Create the condition code operand for BORROW_FROM_SUB + * + * @return a newly created condition code operand + */ + public static ConditionOperand BORROW_FROM_SUB() { + return new ConditionOperand(BORROW_FROM_SUB); + } + + /** + * Create the condition code operand for OVERFLOW_FROM_SUB + * + * @return a newly created condition code operand + */ + public static ConditionOperand OVERFLOW_FROM_SUB() { + return new ConditionOperand(OVERFLOW_FROM_SUB); + } + + /** + * Create the condition code operand for BIT_TEST + * + * @return a newly created condition code operand + */ + public static ConditionOperand BIT_TEST() { + return new ConditionOperand(BIT_TEST); + } + + /** + * Create the condition code operand for OVERFLOW_FROM_ADD + * + * @return a newly created condition code operand + */ + public static ConditionOperand OVERFLOW_FROM_MUL() { + return new ConditionOperand(OVERFLOW_FROM_MUL); + } + + /** + * Is x higher (unsigned >) than y? + */ + private static boolean higher(int x, int y) { + return ((long)x & 0xFFFFFFFFL) > ((long)y & 0xFFFFFFFF); + } + + /** + * Is x lower (unsigned <) than y? + */ + private static boolean lower(int x, int y) { + return ((long)x & 0xFFFFFFFFL) < ((long)y & 0xFFFFFFFF); + } + + /** + * Is x higher equal (unsigned >=) than y? + */ + private static boolean higher_equal(int x, int y) { + return ((long)x & 0xFFFFFFFFL) >= ((long)y & 0xFFFFFFFF); + } + + /** + * Is x lower equal (unsigned <=) than y? + */ + private static boolean lower_equal(int x, int y) { + return ((long)x & 0xFFFFFFFFL) <= ((long)y & 0xFFFFFFFF); + } + + /** + * Would x+y produce a carry? + */ + private static boolean carry_from_add(int x, int y) { + int sum = x + y; + return lower(sum, x); + } + + /** + * Would x-y produce a borrow? + */ + private static boolean borrow_from_sub(int x, int y) { + return lower(x, y); + } + + /** + * Would x+y overflow a register? + */ + private static boolean overflow_from_add(int x, int y) { + if (y >= 0) + return x > (Integer.MAX_VALUE - y); + else + return x < (Integer.MIN_VALUE - y); + } + + /** + * Would x-y overflow a register? + */ + private static boolean overflow_from_sub(int x, int y) { + if (y >= 0) + return x < (Integer.MIN_VALUE + y); + else + return x > (Integer.MAX_VALUE + y); + } + + /** + * Would x*y overflow a register? + */ + private static boolean overflow_from_mul(int x, int y) { + int z = x * y; + long z2 = ((long)x) * ((long)y); + return (long)z != z2; + } + + /** + * Would is bit y of x set? + */ + private static boolean bit_test(int x, int y) { + return (x & (1 << y)) != 0; + } + /** * Is the condition code EQUAL? * @@ -259,13 +455,119 @@ public boolean isLOWER_EQUAL() { */ public boolean isUNSIGNED() { switch (value) { - case HIGHER: - case LOWER: - case HIGHER_EQUAL: - case LOWER_EQUAL: - return true; - default: - return false; + case HIGHER: + case LOWER: + case HIGHER_EQUAL: + case LOWER_EQUAL: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation? + * @return true if it is or false if it is not + */ + public boolean isFLAG_OPERATION() { + switch (value) { + case CARRY_FROM_ADD: + case NO_CARRY_FROM_ADD: + case OVERFLOW_FROM_ADD: + case NO_OVERFLOW_FROM_ADD: + case BORROW_FROM_SUB: + case NO_BORROW_FROM_SUB: + case OVERFLOW_FROM_SUB: + case NO_OVERFLOW_FROM_SUB: + case BORROW_FROM_RSUB: + case NO_BORROW_FROM_RSUB: + case OVERFLOW_FROM_RSUB: + case NO_OVERFLOW_FROM_RSUB: + case BIT_TEST: + case NO_BIT_TEST: + case RBIT_TEST: + case NO_RBIT_TEST: + case OVERFLOW_FROM_MUL: + case NO_OVERFLOW_FROM_MUL: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation following an add? + * @return true if it is or false if it is not + */ + public boolean isFLAG_OPERATION_FROM_ADD() { + switch (value) { + case CARRY_FROM_ADD: + case NO_CARRY_FROM_ADD: + case OVERFLOW_FROM_ADD: + case NO_OVERFLOW_FROM_ADD: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation following a subtract? + * @return true if it is or false if it is not + */ + public boolean isFLAG_OPERATION_FROM_SUB() { + switch (value) { + case BORROW_FROM_SUB: + case NO_BORROW_FROM_SUB: + case OVERFLOW_FROM_SUB: + case NO_OVERFLOW_FROM_SUB: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation following a reversed subtract? + * @return true if it is or false if it is not + */ + public boolean isFLAG_OPERATION_FROM_RSUB() { + switch (value) { + case BORROW_FROM_RSUB: + case NO_BORROW_FROM_RSUB: + case OVERFLOW_FROM_RSUB: + case NO_OVERFLOW_FROM_RSUB: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation following a bit test? + * @return true if it is or false if it is not + */ + public boolean isBIT_TEST() { + switch (value) { + case BIT_TEST: + case NO_BIT_TEST: + return true; + default: + return false; + } + } + + /** + * Is the condition code a flag operation following a reversed bit test? + * @return true if it is or false if it is not + */ + public boolean isRBIT_TEST() { + switch (value) { + case RBIT_TEST: + case NO_RBIT_TEST: + return true; + default: + return false; } } @@ -320,27 +622,27 @@ public boolean branchIfUnordered() { * compare. Used during bc2ir. */ public void translateCMPL() { - switch (value) { - case EQUAL: - value = CMPL_EQUAL; - break; - case NOT_EQUAL: - value = CMPL_NOT_EQUAL; - break; - case LESS: - value = CMPL_LESS; - break; - case GREATER_EQUAL: - value = CMPL_GREATER_EQUAL; - break; - case GREATER: - value = CMPL_GREATER; - break; - case LESS_EQUAL: - value = CMPL_LESS_EQUAL; - break; - default: - throw new OptimizingCompilerException("invalid condition " + this); + switch(value) { + case EQUAL: + value = CMPL_EQUAL; + break; + case NOT_EQUAL: + value = CMPL_NOT_EQUAL; + break; + case LESS: + value = CMPL_LESS; + break; + case GREATER_EQUAL: + value = CMPL_GREATER_EQUAL; + break; + case GREATER: + value = CMPL_GREATER; + break; + case LESS_EQUAL: + value = CMPL_LESS_EQUAL; + break; + default: + throw new OptimizingCompilerException("invalid condition " + this); } } @@ -349,27 +651,27 @@ public void translateCMPL() { * compare. Used during bc2ir. */ public void translateCMPG() { - switch (value) { - case EQUAL: - value = CMPL_EQUAL; - break; - case NOT_EQUAL: - value = CMPL_NOT_EQUAL; - break; - case LESS: - value = CMPG_LESS; - break; - case GREATER_EQUAL: - value = CMPG_GREATER_EQUAL; - break; - case GREATER: - value = CMPG_GREATER; - break; - case LESS_EQUAL: - value = CMPG_LESS_EQUAL; - break; - default: - throw new OptimizingCompilerException("invalid condition " + this); + switch(value) { + case EQUAL: + value = CMPL_EQUAL; + break; + case NOT_EQUAL: + value = CMPL_NOT_EQUAL; + break; + case LESS: + value = CMPG_LESS; + break; + case GREATER_EQUAL: + value = CMPG_GREATER_EQUAL; + break; + case GREATER: + value = CMPG_GREATER; + break; + case LESS_EQUAL: + value = CMPG_LESS_EQUAL; + break; + default: + throw new OptimizingCompilerException("invalid condition " + this); } } @@ -380,39 +682,19 @@ public void translateCMPG() { * safe to. */ public ConditionOperand translateUNSIGNED() { - switch (value) { - case CMPL_EQUAL: - value = EQUAL; - break; - case CMPL_GREATER: - value = HIGHER; - break; - case CMPG_LESS: - value = LOWER; - break; - case CMPL_GREATER_EQUAL: - value = HIGHER_EQUAL; - break; - case CMPG_LESS_EQUAL: - value = LOWER_EQUAL; - break; - case CMPL_NOT_EQUAL: - value = NOT_EQUAL; - break; - case CMPL_LESS: - value = LOWER; - break; - case CMPG_GREATER_EQUAL: - value = HIGHER_EQUAL; - break; - case CMPG_GREATER: - value = HIGHER; - break; - case CMPL_LESS_EQUAL: - value = LOWER_EQUAL; - break; - default: - throw new OptimizingCompilerException("invalid condition " + this); + switch(value) { + case CMPL_EQUAL: value = EQUAL; break; + case CMPL_GREATER: value = HIGHER; break; + case CMPG_LESS: value = LOWER; break; + case CMPL_GREATER_EQUAL: value = HIGHER_EQUAL; break; + case CMPG_LESS_EQUAL: value = LOWER_EQUAL; break; + case CMPL_NOT_EQUAL: value = NOT_EQUAL; break; + case CMPL_LESS: value = LOWER; break; + case CMPG_GREATER_EQUAL: value = HIGHER_EQUAL; break; + case CMPG_GREATER: value = HIGHER; break; + case CMPL_LESS_EQUAL: value = LOWER_EQUAL; break; + default: + throw new OptimizingCompilerException("invalid condition " + this); } return this; } @@ -438,10 +720,6 @@ public boolean similar(Operand op) { return (op instanceof ConditionOperand) && (((ConditionOperand) op).value == value); } - public static final int FALSE = 0; - public static final int TRUE = 1; - public static final int UNKNOWN = 2; - /** * Given two operands, evaluate the condition on them. * @@ -533,20 +811,39 @@ public int evaluate(Operand v1, Operand v2) { // comparisons of identical operands can be evaluated, except // for floating point NaN cases switch (value) { - case EQUAL: - case GREATER_EQUAL: - case LESS_EQUAL: - case HIGHER_EQUAL: - case LOWER_EQUAL: - return TRUE; - case NOT_EQUAL: - case LESS: - case GREATER: - case HIGHER: - case LOWER: - return FALSE; - default: - throw new OptimizingCompilerException("invalid condition " + this); + case EQUAL: + case GREATER_EQUAL: + case LESS_EQUAL: + case HIGHER_EQUAL: + case LOWER_EQUAL: + return TRUE; + case NOT_EQUAL: + case LESS: + case GREATER: + case HIGHER: + case LOWER: + case BORROW_FROM_SUB: + case NO_BORROW_FROM_SUB: + case BORROW_FROM_RSUB: + case NO_BORROW_FROM_RSUB: + case OVERFLOW_FROM_SUB: + case NO_OVERFLOW_FROM_SUB: + case OVERFLOW_FROM_RSUB: + case NO_OVERFLOW_FROM_RSUB: + return FALSE; + case CARRY_FROM_ADD: + case NO_CARRY_FROM_ADD: + case OVERFLOW_FROM_ADD: + case NO_OVERFLOW_FROM_ADD: + case BIT_TEST: + case NO_BIT_TEST: + case RBIT_TEST: + case NO_RBIT_TEST: + case OVERFLOW_FROM_MUL: + case NO_OVERFLOW_FROM_MUL: + return UNKNOWN; + default: + throw new OptimizingCompilerException("invalid condition " + this); } } return UNKNOWN; @@ -563,50 +860,34 @@ public int evaluate(Operand v1, Operand v2) { */ public int evaluate(int v1, int v2) { switch (value) { - case EQUAL: - return (v1 == v2) ? TRUE : FALSE; - case NOT_EQUAL: - return (v1 != v2) ? TRUE : FALSE; - case GREATER: - return (v1 > v2) ? TRUE : FALSE; - case LESS: - return (v1 < v2) ? TRUE : FALSE; - case GREATER_EQUAL: - return (v1 >= v2) ? TRUE : FALSE; - case LESS_EQUAL: - return (v1 <= v2) ? TRUE : FALSE; - case LOWER: - if ((v1 >= 0 && v2 >= 0) || (v1 < 0 && v2 < 0)) { - return (v1 < v2) ? TRUE : FALSE; - } else if (v1 < 0) { - return FALSE; - } else { - return TRUE; - } - case LOWER_EQUAL: - if ((v1 >= 0 && v2 >= 0) || (v1 < 0 && v2 < 0)) { - return (v1 <= v2) ? TRUE : FALSE; - } else if (v1 < 0) { - return FALSE; - } else { - return TRUE; - } - case HIGHER: - if ((v1 >= 0 && v2 >= 0) || (v1 < 0 && v2 < 0)) { - return (v1 > v2) ? TRUE : FALSE; - } else if (v1 < 0) { - return TRUE; - } else { - return FALSE; - } - case HIGHER_EQUAL: - if ((v1 >= 0 && v2 >= 0) || (v1 < 0 && v2 < 0)) { - return (v1 >= v2) ? TRUE : FALSE; - } else if (v1 < 0) { - return TRUE; - } else { - return FALSE; - } + case EQUAL: return (v1 == v2) ? TRUE : FALSE; + case NOT_EQUAL: return (v1 != v2) ? TRUE : FALSE; + case GREATER: return (v1 > v2) ? TRUE : FALSE; + case LESS: return (v1 < v2) ? TRUE : FALSE; + case GREATER_EQUAL: return (v1 >= v2) ? TRUE : FALSE; + case LESS_EQUAL: return (v1 <= v2) ? TRUE : FALSE; + case LOWER: return lower(v1, v2) ? TRUE : FALSE; + case LOWER_EQUAL: return lower_equal(v1, v2) ? TRUE : FALSE; + case HIGHER: return higher(v1, v2) ? TRUE : FALSE; + case HIGHER_EQUAL: return higher_equal(v1, v2) ? TRUE : FALSE; + case CARRY_FROM_ADD: return carry_from_add(v1, v2) ? TRUE : FALSE; + case NO_CARRY_FROM_ADD: return carry_from_add(v1, v2) ? FALSE : TRUE; + case OVERFLOW_FROM_ADD: return overflow_from_add(v1, v2) ? TRUE : FALSE; + case NO_OVERFLOW_FROM_ADD: return overflow_from_add(v1, v2) ? FALSE : TRUE; + case BORROW_FROM_SUB: return borrow_from_sub(v1, v2) ? TRUE : FALSE; + case NO_BORROW_FROM_SUB: return borrow_from_sub(v1, v2) ? FALSE : TRUE; + case BORROW_FROM_RSUB: return borrow_from_sub(v2, v1) ? TRUE : FALSE; + case NO_BORROW_FROM_RSUB: return borrow_from_sub(v2, v1) ? FALSE : TRUE; + case OVERFLOW_FROM_SUB: return overflow_from_sub(v1, v2) ? TRUE : FALSE; + case NO_OVERFLOW_FROM_SUB: return overflow_from_sub(v1, v2) ? FALSE : TRUE; + case OVERFLOW_FROM_RSUB: return overflow_from_sub(v2, v1) ? TRUE : FALSE; + case NO_OVERFLOW_FROM_RSUB: return overflow_from_sub(v2, v1) ? FALSE : TRUE; + case BIT_TEST: return bit_test(v1, v2) ? TRUE : FALSE; + case NO_BIT_TEST: return bit_test(v1, v2) ? FALSE : TRUE; + case RBIT_TEST: return bit_test(v2, v1) ? TRUE : FALSE; + case NO_RBIT_TEST: return bit_test(v2, v1) ? FALSE : TRUE; + case OVERFLOW_FROM_MUL: return overflow_from_mul(v1, v2) ? TRUE : FALSE; + case NO_OVERFLOW_FROM_MUL: return overflow_from_mul(v1, v2) ? FALSE : TRUE; } throw new OptimizingCompilerException("invalid condition " + this); } @@ -622,18 +903,12 @@ public int evaluate(int v1, int v2) { */ public int evaluate(long v1, long v2) { switch (value) { - case EQUAL: - return (v1 == v2) ? TRUE : FALSE; - case NOT_EQUAL: - return (v1 != v2) ? TRUE : FALSE; - case GREATER: - return (v1 > v2) ? TRUE : FALSE; - case LESS: - return (v1 < v2) ? TRUE : FALSE; - case GREATER_EQUAL: - return (v1 >= v2) ? TRUE : FALSE; - case LESS_EQUAL: - return (v1 <= v2) ? TRUE : FALSE; + case EQUAL: return (v1 == v2) ? TRUE : FALSE; + case NOT_EQUAL: return (v1 != v2) ? TRUE : FALSE; + case GREATER: return (v1 > v2) ? TRUE : FALSE; + case LESS: return (v1 < v2) ? TRUE : FALSE; + case GREATER_EQUAL: return (v1 >= v2) ? TRUE : FALSE; + case LESS_EQUAL: return (v1 <= v2) ? TRUE : FALSE; } throw new OptimizingCompilerException("invalid condition " + this); } @@ -649,27 +924,17 @@ public int evaluate(long v1, long v2) { public int evaluate(float v1, float v2) { switch (value) { // Return FALSE when UNORDERED - case CMPL_EQUAL: - return (v1 == v2) ? TRUE : FALSE; - case CMPL_GREATER: - return (v1 > v2) ? TRUE : FALSE; - case CMPG_LESS: - return (v1 < v2) ? TRUE : FALSE; - case CMPL_GREATER_EQUAL: - return (v1 >= v2) ? TRUE : FALSE; - case CMPG_LESS_EQUAL: - return (v1 <= v2) ? TRUE : FALSE; - // Return TRUE when UNORDERED - case CMPL_NOT_EQUAL: - return (v1 == v2) ? FALSE : TRUE; - case CMPL_LESS: - return (v1 >= v2) ? FALSE : TRUE; - case CMPG_GREATER_EQUAL: - return (v1 < v2) ? FALSE : TRUE; - case CMPG_GREATER: - return (v1 <= v2) ? FALSE : TRUE; - case CMPL_LESS_EQUAL: - return (v1 > v2) ? FALSE : TRUE; + case CMPL_EQUAL: return (v1 == v2) ? TRUE : FALSE; + case CMPL_GREATER: return (v1 > v2) ? TRUE : FALSE; + case CMPG_LESS: return (v1 < v2) ? TRUE : FALSE; + case CMPL_GREATER_EQUAL: return (v1 >= v2) ? TRUE : FALSE; + case CMPG_LESS_EQUAL: return (v1 <= v2) ? TRUE : FALSE; + // Return TRUE when UNORDERED + case CMPL_NOT_EQUAL: return (v1 == v2) ? FALSE : TRUE; + case CMPL_LESS: return (v1 >= v2) ? FALSE : TRUE; + case CMPG_GREATER_EQUAL: return (v1 < v2) ? FALSE : TRUE; + case CMPG_GREATER: return (v1 <= v2) ? FALSE : TRUE; + case CMPL_LESS_EQUAL: return (v1 > v2) ? FALSE : TRUE; } throw new OptimizingCompilerException("invalid condition " + this); } @@ -685,27 +950,17 @@ public int evaluate(float v1, float v2) { public int evaluate(double v1, double v2) { switch (value) { // Return FALSE when UNORDERED - case CMPL_EQUAL: - return (v1 == v2) ? TRUE : FALSE; - case CMPL_GREATER: - return (v1 > v2) ? TRUE : FALSE; - case CMPG_LESS: - return (v1 < v2) ? TRUE : FALSE; - case CMPL_GREATER_EQUAL: - return (v1 >= v2) ? TRUE : FALSE; - case CMPG_LESS_EQUAL: - return (v1 <= v2) ? TRUE : FALSE; - // Return TRUE when UNORDERED - case CMPL_NOT_EQUAL: - return (v1 == v2) ? FALSE : TRUE; - case CMPL_LESS: - return (v1 >= v2) ? FALSE : TRUE; - case CMPG_GREATER_EQUAL: - return (v1 < v2) ? FALSE : TRUE; - case CMPG_GREATER: - return (v1 <= v2) ? FALSE : TRUE; - case CMPL_LESS_EQUAL: - return (v1 > v2) ? FALSE : TRUE; + case CMPL_EQUAL: return (v1 == v2) ? TRUE : FALSE; + case CMPL_GREATER: return (v1 > v2) ? TRUE : FALSE; + case CMPG_LESS: return (v1 < v2) ? TRUE : FALSE; + case CMPL_GREATER_EQUAL: return (v1 >= v2) ? TRUE : FALSE; + case CMPG_LESS_EQUAL: return (v1 <= v2) ? TRUE : FALSE; + // Return TRUE when UNORDERED + case CMPL_NOT_EQUAL: return (v1 == v2) ? FALSE : TRUE; + case CMPL_LESS: return (v1 >= v2) ? FALSE : TRUE; + case CMPG_GREATER_EQUAL: return (v1 < v2) ? FALSE : TRUE; + case CMPG_GREATER: return (v1 <= v2) ? FALSE : TRUE; + case CMPL_LESS_EQUAL: return (v1 > v2) ? FALSE : TRUE; } throw new OptimizingCompilerException("invalid condition " + this); } @@ -721,26 +976,16 @@ public int evaluate(double v1, double v2) { */ public int evaluate(Address v1, Address v2) { switch (value) { - case EQUAL: - return (v1.EQ(v2)) ? TRUE : FALSE; - case NOT_EQUAL: - return (v1.NE(v2)) ? TRUE : FALSE; - case GREATER: - return (v1.toWord().toOffset().sGT(v2.toWord().toOffset())) ? TRUE : FALSE; - case LESS: - return (v1.toWord().toOffset().sLT(v2.toWord().toOffset())) ? TRUE : FALSE; - case GREATER_EQUAL: - return (v1.toWord().toOffset().sGE(v2.toWord().toOffset())) ? TRUE : FALSE; - case LESS_EQUAL: - return (v1.toWord().toOffset().sLE(v2.toWord().toOffset())) ? TRUE : FALSE; - case LOWER: - return (v1.LT(v2)) ? TRUE : FALSE; - case LOWER_EQUAL: - return (v1.LE(v2)) ? TRUE : FALSE; - case HIGHER: - return (v1.GT(v2)) ? TRUE : FALSE; - case HIGHER_EQUAL: - return (v1.GE(v2)) ? TRUE : FALSE; + case EQUAL: return (v1.EQ(v2)) ? TRUE : FALSE; + case NOT_EQUAL: return (v1.NE(v2)) ? TRUE : FALSE; + case GREATER: return (v1.toWord().toOffset().sGT(v2.toWord().toOffset())) ? TRUE : FALSE; + case LESS: return (v1.toWord().toOffset().sLT(v2.toWord().toOffset())) ? TRUE : FALSE; + case GREATER_EQUAL: return (v1.toWord().toOffset().sGE(v2.toWord().toOffset())) ? TRUE : FALSE; + case LESS_EQUAL: return (v1.toWord().toOffset().sLE(v2.toWord().toOffset())) ? TRUE : FALSE; + case LOWER: return (v1.LT(v2)) ? TRUE : FALSE; + case LOWER_EQUAL: return (v1.LE(v2)) ? TRUE : FALSE; + case HIGHER: return (v1.GT(v2)) ? TRUE : FALSE; + case HIGHER_EQUAL: return (v1.GE(v2)) ? TRUE : FALSE; } throw new OptimizingCompilerException("invalid condition " + this); } @@ -762,68 +1007,55 @@ public int evaluate(Address v1, Address v2) { */ public ConditionOperand 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 HIGHER: - value = LOWER_EQUAL; - break; - case LOWER: - value = HIGHER_EQUAL; - break; - case HIGHER_EQUAL: - value = LOWER; - break; - case LOWER_EQUAL: - value = HIGHER; - break; - case CMPL_EQUAL: - value = CMPL_NOT_EQUAL; - break; - case CMPL_GREATER: - value = CMPL_LESS_EQUAL; - break; - case CMPG_LESS: - value = CMPG_GREATER_EQUAL; - break; - case CMPL_GREATER_EQUAL: - value = CMPL_LESS; - break; - case CMPG_LESS_EQUAL: - value = CMPG_GREATER; - break; - case CMPL_NOT_EQUAL: - value = CMPL_EQUAL; - break; - case CMPL_LESS: - value = CMPL_GREATER_EQUAL; - break; - case CMPG_GREATER_EQUAL: - value = CMPG_LESS; - break; - case CMPG_GREATER: - value = CMPG_LESS_EQUAL; - break; - case CMPL_LESS_EQUAL: - value = CMPL_GREATER; - break; - default: - OptimizingCompilerException.UNREACHABLE(); + 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 HIGHER: value = LOWER_EQUAL; break; + case LOWER: value = HIGHER_EQUAL; break; + case HIGHER_EQUAL: value = LOWER; break; + case LOWER_EQUAL: value = HIGHER; break; + + case CMPL_EQUAL: value = CMPL_NOT_EQUAL; break; + case CMPL_GREATER: value = CMPL_LESS_EQUAL; break; + case CMPG_LESS: value = CMPG_GREATER_EQUAL; break; + case CMPL_GREATER_EQUAL: value = CMPL_LESS; break; + case CMPG_LESS_EQUAL: value = CMPG_GREATER; break; + case CMPL_NOT_EQUAL: value = CMPL_EQUAL; break; + case CMPL_LESS: value = CMPL_GREATER_EQUAL; break; + case CMPG_GREATER_EQUAL: value = CMPG_LESS; break; + case CMPG_GREATER: value = CMPG_LESS_EQUAL; break; + case CMPL_LESS_EQUAL: value = CMPL_GREATER; break; + + case CARRY_FROM_ADD: value = NO_CARRY_FROM_ADD; break; + case NO_CARRY_FROM_ADD: value = CARRY_FROM_ADD; break; + + case OVERFLOW_FROM_ADD: value = NO_OVERFLOW_FROM_ADD; break; + case NO_OVERFLOW_FROM_ADD: value = OVERFLOW_FROM_ADD; break; + + case BORROW_FROM_SUB: value = NO_BORROW_FROM_SUB; break; + case NO_BORROW_FROM_SUB: value = BORROW_FROM_SUB; break; + case BORROW_FROM_RSUB: value = NO_BORROW_FROM_RSUB; break; + case NO_BORROW_FROM_RSUB: value = BORROW_FROM_RSUB; break; + + case OVERFLOW_FROM_SUB: value = NO_OVERFLOW_FROM_SUB; break; + case NO_OVERFLOW_FROM_SUB: value = OVERFLOW_FROM_SUB; break; + case OVERFLOW_FROM_RSUB: value = NO_OVERFLOW_FROM_RSUB; break; + case NO_OVERFLOW_FROM_RSUB: value = OVERFLOW_FROM_RSUB; break; + + case BIT_TEST: value = NO_BIT_TEST; break; + case NO_BIT_TEST: value = BIT_TEST; break; + case RBIT_TEST: value = NO_RBIT_TEST; break; + case NO_RBIT_TEST: value = RBIT_TEST; break; + + case OVERFLOW_FROM_MUL: value = NO_OVERFLOW_FROM_MUL; break; + case NO_OVERFLOW_FROM_MUL: value = OVERFLOW_FROM_MUL; break; + + default: + OptimizingCompilerException.UNREACHABLE(); } return this; } @@ -842,68 +1074,55 @@ public ConditionOperand flipCode() { */ public ConditionOperand flipOperands() { switch (value) { - case EQUAL: - value = EQUAL; - break; - case NOT_EQUAL: - value = NOT_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 HIGHER: - value = LOWER; - break; - case LOWER: - value = HIGHER; - break; - case HIGHER_EQUAL: - value = LOWER_EQUAL; - break; - case LOWER_EQUAL: - value = HIGHER_EQUAL; - break; - case CMPL_EQUAL: - value = CMPL_EQUAL; - break; - case CMPL_GREATER: - value = CMPG_LESS; - break; - case CMPG_LESS: - value = CMPL_GREATER; - break; - case CMPL_GREATER_EQUAL: - value = CMPG_LESS_EQUAL; - break; - case CMPG_LESS_EQUAL: - value = CMPL_GREATER_EQUAL; - break; - case CMPL_NOT_EQUAL: - value = CMPL_NOT_EQUAL; - break; - case CMPL_LESS: - value = CMPG_GREATER; - break; - case CMPG_GREATER_EQUAL: - value = CMPL_LESS_EQUAL; - break; - case CMPG_GREATER: - value = CMPL_LESS; - break; - case CMPL_LESS_EQUAL: - value = CMPG_GREATER_EQUAL; - break; - default: - OptimizingCompilerException.UNREACHABLE(); + case EQUAL: value = EQUAL; break; + case NOT_EQUAL: value = NOT_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 HIGHER: value = LOWER; break; + case LOWER: value = HIGHER; break; + case HIGHER_EQUAL: value = LOWER_EQUAL; break; + case LOWER_EQUAL: value = HIGHER_EQUAL; break; + + case CMPL_EQUAL: value = CMPL_EQUAL; break; + case CMPL_GREATER: value = CMPG_LESS; break; + case CMPG_LESS: value = CMPL_GREATER; break; + case CMPL_GREATER_EQUAL: value = CMPG_LESS_EQUAL; break; + case CMPG_LESS_EQUAL: value = CMPL_GREATER_EQUAL; break; + case CMPL_NOT_EQUAL: value = CMPL_NOT_EQUAL; break; + case CMPL_LESS: value = CMPG_GREATER; break; + case CMPG_GREATER_EQUAL: value = CMPL_LESS_EQUAL; break; + case CMPG_GREATER: value = CMPL_LESS; break; + case CMPL_LESS_EQUAL: value = CMPG_GREATER_EQUAL; break; + + case CARRY_FROM_ADD: break; // add is commutative + case NO_CARRY_FROM_ADD: break; + + case OVERFLOW_FROM_ADD: break; + case NO_OVERFLOW_FROM_ADD: break; + + case BORROW_FROM_SUB: value = BORROW_FROM_RSUB; break; + case NO_BORROW_FROM_SUB: value = NO_BORROW_FROM_RSUB; break; + case BORROW_FROM_RSUB: value = BORROW_FROM_SUB; break; + case NO_BORROW_FROM_RSUB: value = NO_BORROW_FROM_SUB; break; + + case OVERFLOW_FROM_SUB: value = OVERFLOW_FROM_RSUB; break; + case NO_OVERFLOW_FROM_SUB: value = NO_OVERFLOW_FROM_RSUB; break; + case OVERFLOW_FROM_RSUB: value = OVERFLOW_FROM_SUB; break; + case NO_OVERFLOW_FROM_RSUB: value = NO_OVERFLOW_FROM_SUB; break; + + case BIT_TEST: value = RBIT_TEST; break; + case NO_BIT_TEST: value = NO_RBIT_TEST; break; + case RBIT_TEST: value = BIT_TEST; break; + case NO_RBIT_TEST: value = NO_BIT_TEST; break; + + case OVERFLOW_FROM_MUL: break; // mul is commutative + case NO_OVERFLOW_FROM_MUL: break; + + default: + OptimizingCompilerException.UNREACHABLE(); } return this; } @@ -922,48 +1141,55 @@ public ConditionOperand flipOperands() { */ public String toString() { switch (value) { - case EQUAL: - return "=="; - case NOT_EQUAL: - return "!="; - case LESS: - return "<"; - case LESS_EQUAL: - return "<="; - case GREATER: - return ">"; - case GREATER_EQUAL: - return ">="; - case HIGHER: - return ">U"; - case LOWER: - return "=U"; - case LOWER_EQUAL: - return "<=U"; - case CMPL_EQUAL: - return "==F"; - case CMPL_GREATER: - return ">F"; - case CMPG_LESS: - return "=F"; - case CMPG_LESS_EQUAL: - return "<=F"; - case CMPL_NOT_EQUAL: - return "!=FU"; - case CMPL_LESS: - return "=FU"; - case CMPG_GREATER: - return ">FU"; - case CMPL_LESS_EQUAL: - return "<=FU"; - default: - return "UNKNOWN"; + case EQUAL: return "=="; + case NOT_EQUAL: return "!="; + case LESS: return "<"; + case LESS_EQUAL: return "<="; + case GREATER: return ">"; + case GREATER_EQUAL: return ">="; + + case HIGHER: return ">U"; + case LOWER: return "=U"; + case LOWER_EQUAL: return "<=U"; + + case CMPL_EQUAL: return "==F"; + case CMPL_GREATER: return ">F"; + case CMPG_LESS: return "=F"; + case CMPG_LESS_EQUAL: return "<=F"; + + case CMPL_NOT_EQUAL: return "!=FU"; + case CMPL_LESS: return "=FU"; + case CMPG_GREATER: return ">FU"; + case CMPL_LESS_EQUAL: return "<=FU"; + + case CARRY_FROM_ADD: return "carry(+)"; + case NO_CARRY_FROM_ADD: return "nocarry(+)"; + + case OVERFLOW_FROM_ADD: return "overflow(+)"; + case NO_OVERFLOW_FROM_ADD: return "nooverflow(+)"; + + case BORROW_FROM_SUB: return "borrow(-)"; + case NO_BORROW_FROM_SUB: return "noborrow(-)"; + case BORROW_FROM_RSUB: return "borrow(r-)"; + case NO_BORROW_FROM_RSUB: return "noborrow(r-)"; + + case OVERFLOW_FROM_SUB: return "overflow(-)"; + case NO_OVERFLOW_FROM_SUB: return "nooverflow(-)"; + case OVERFLOW_FROM_RSUB: return "overflow(r-)"; + case NO_OVERFLOW_FROM_RSUB: return "nooverflow(r-)"; + + case BIT_TEST: return "bt"; + case NO_BIT_TEST: return "!bt"; + case RBIT_TEST: return "rbt"; + case NO_RBIT_TEST: return "!rbt"; + + case OVERFLOW_FROM_MUL: return "overflow(*)"; + case NO_OVERFLOW_FROM_MUL: return "nooverflow(*)"; + + default: return "UNKNOWN"; } } }