Skip to content

Commit

Permalink
Support for new condition operands in LIR2MIR conversion.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian Rogers committed Apr 28, 2009
1 parent 618305b commit 8d40e38
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 126 deletions.
15 changes: 9 additions & 6 deletions rvm/src-generated/opt-burs/ia32/IA32.rules
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,9 @@ BOOLEAN_CMP_INT(P(p), BooleanCmp.getResult(P(p)), \\
boolcmp: BOOLEAN_CMP_INT(r,riv)
13
EMIT_INSTRUCTION
pushCOND(BooleanCmp.getCond(P(p))); \\
EMIT(MIR_Compare.mutate(P(p), IA32_CMP, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal2(P(p))));
ConditionOperand cond = BooleanCmp.getCond(P(p)); \\
pushCOND(cond); \\
EMIT_Compare(P(p), cond, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal2(P(p)));

r: BOOLEAN_CMP_INT(r,INT_CONSTANT)
VR(p) == 0 && CMP_TO_TEST(BooleanCmp.getCond(P(p))) ? 37:INFINITE
Expand Down Expand Up @@ -630,8 +631,9 @@ BOOLEAN_CMP_INT(PL(p), BooleanCmp.getResult(P(p)), \\
boolcmp: BOOLEAN_CMP_INT(load32,riv)
15
EMIT_INSTRUCTION
pushCOND(BooleanCmp.getCond(P(p))); \\
EMIT(MIR_Compare.mutate(PL(p), IA32_CMP, consumeMO(), BooleanCmp.getVal2(P(p))));
ConditionOperand cond = BooleanCmp.getCond(P(p)); \\
pushCOND(cond); \\
EMIT_Compare(P(p), cond, consumeMO(), BooleanCmp.getVal2(P(p)));

r: BOOLEAN_CMP_INT(r,load32)
41
Expand All @@ -643,8 +645,9 @@ BOOLEAN_CMP_INT(PR(p), BooleanCmp.getResult(P(p)), \\
boolcmp: BOOLEAN_CMP_INT(riv,load32)
15
EMIT_INSTRUCTION
pushCOND(BooleanCmp.getCond(P(p)).flipOperands()); \\
EMIT(MIR_Compare.mutate(PR(p), IA32_CMP, consumeMO(), BooleanCmp.getVal1(P(p))));
ConditionOperand cond = BooleanCmp.getCond(P(p)); \\
pushCOND(cond); \\
EMIT_Compare(P(p), cond, BooleanCmp.getVal1(P(p)), consumeMO());

stm: BYTE_STORE(boolcmp, OTHER_OPERAND(riv,riv))
15
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,56 +49,24 @@ public boolean similar(Operand op) {
*/
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();
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;
}
Expand All @@ -109,32 +77,16 @@ public IA32ConditionOperand flipCode() {
*/
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();
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;
}
Expand Down Expand Up @@ -209,50 +161,72 @@ private IA32ConditionOperand(byte 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();
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();
}
}

Expand Down
63 changes: 63 additions & 0 deletions rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDNPS;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDPD;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDPS;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_BT;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CALL;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CDQ;
import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMOV;
Expand Down Expand Up @@ -2856,6 +2857,68 @@ protected final void threeValueFPCmp(Instruction s) {
EMIT(MIR_Unary.mutate(s, IA32_MOVSX__B, res.copyRO(), res.copyRO()));
}

/**
* Does the given condition operand need its operands flipping as its
* non-commutative?
*/
private boolean getCMP_needsSwap(ConditionOperand cond) {
switch (cond.value) {
case ConditionOperand.BORROW_FROM_RSUB:
case ConditionOperand.NO_BORROW_FROM_RSUB:
case ConditionOperand.OVERFLOW_FROM_RSUB:
case ConditionOperand.NO_OVERFLOW_FROM_RSUB:
case ConditionOperand.RBIT_TEST:
case ConditionOperand.NO_RBIT_TEST:
return true;
default:
return false;
}
}
/**
* Give the MIR condition operator appropriate for the given condition
*/
void EMIT_Compare(Instruction s, ConditionOperand cond,
Operand val1, Operand val2) {
// Swap operands for non-commutative operators
if (getCMP_needsSwap(cond)) {
Operand temp = val1;
val2 = val1;
val1 = temp;
}
switch (cond.value) {
case ConditionOperand.CARRY_FROM_ADD:
case ConditionOperand.NO_CARRY_FROM_ADD:
case ConditionOperand.OVERFLOW_FROM_ADD:
case ConditionOperand.NO_OVERFLOW_FROM_ADD: {
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val1.copy())));
EMIT(MIR_BinaryAcc.mutate(s, IA32_ADD, temp.copyRO(), val2));
break;
}
case ConditionOperand.BIT_TEST:
case ConditionOperand.NO_BIT_TEST:
case ConditionOperand.RBIT_TEST:
case ConditionOperand.NO_RBIT_TEST:
if (val2 instanceof MemoryOperand) {
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val2.copy())));
val2 = temp;
}
EMIT(MIR_Compare.mutate(s, IA32_BT, val1.copy(), val2.copy()));
break;
case ConditionOperand.OVERFLOW_FROM_MUL:
case ConditionOperand.NO_OVERFLOW_FROM_MUL: {
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val1.copy())));
EMIT(MIR_BinaryAcc.mutate(s, IA32_IMUL2, temp.copyRO(), val2));
break;
}
default:
EMIT(MIR_Compare.mutate(s, IA32_CMP, val1.copy(), val2.copy()));
break;
}
}

/**
* Expansion of BOOLEAN_CMP_INT
*
Expand Down

0 comments on commit 8d40e38

Please sign in to comment.