Added support for unsigned comparisons
Rationale: even though not directly supported in input graph,
having the ability to express unsigned comparisons
in HIR is useful for all sorts of optimizations.
Change-Id: I4543c96a8c1895c3d33aaf85685afbf80fe27d72
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index f8be21a..f385afa 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -428,7 +428,7 @@
#undef __
#define __ down_cast<X86Assembler*>(GetAssembler())->
-inline Condition X86SignedCondition(IfCondition cond) {
+inline Condition X86Condition(IfCondition cond) {
switch (cond) {
case kCondEQ: return kEqual;
case kCondNE: return kNotEqual;
@@ -436,19 +436,30 @@
case kCondLE: return kLessEqual;
case kCondGT: return kGreater;
case kCondGE: return kGreaterEqual;
+ case kCondB: return kBelow;
+ case kCondBE: return kBelowEqual;
+ case kCondA: return kAbove;
+ case kCondAE: return kAboveEqual;
}
LOG(FATAL) << "Unreachable";
UNREACHABLE();
}
+// Maps signed condition to unsigned condition and FP condition to x86 name.
inline Condition X86UnsignedOrFPCondition(IfCondition cond) {
switch (cond) {
case kCondEQ: return kEqual;
case kCondNE: return kNotEqual;
+ // Signed to unsigned, and FP to x86 name.
case kCondLT: return kBelow;
case kCondLE: return kBelowEqual;
case kCondGT: return kAbove;
case kCondGE: return kAboveEqual;
+ // Unsigned remain unchanged.
+ case kCondB: return kBelow;
+ case kCondBE: return kBelowEqual;
+ case kCondA: return kAbove;
+ case kCondAE: return kAboveEqual;
}
LOG(FATAL) << "Unreachable";
UNREACHABLE();
@@ -1067,7 +1078,7 @@
Register left_low = left.AsRegisterPairLow<Register>();
IfCondition true_high_cond = if_cond;
IfCondition false_high_cond = cond->GetOppositeCondition();
- Condition final_condition = X86UnsignedOrFPCondition(if_cond);
+ Condition final_condition = X86UnsignedOrFPCondition(if_cond); // unsigned on lower part
// Set the conditions for the test, remembering that == needs to be
// decided using the low words.
@@ -1088,6 +1099,18 @@
case kCondGE:
true_high_cond = kCondGT;
break;
+ case kCondB:
+ false_high_cond = kCondA;
+ break;
+ case kCondBE:
+ true_high_cond = kCondB;
+ break;
+ case kCondA:
+ false_high_cond = kCondB;
+ break;
+ case kCondAE:
+ true_high_cond = kCondA;
+ break;
}
if (right.IsConstant()) {
@@ -1101,12 +1124,12 @@
__ cmpl(left_high, Immediate(val_high));
}
if (if_cond == kCondNE) {
- __ j(X86SignedCondition(true_high_cond), true_label);
+ __ j(X86Condition(true_high_cond), true_label);
} else if (if_cond == kCondEQ) {
- __ j(X86SignedCondition(false_high_cond), false_label);
+ __ j(X86Condition(false_high_cond), false_label);
} else {
- __ j(X86SignedCondition(true_high_cond), true_label);
- __ j(X86SignedCondition(false_high_cond), false_label);
+ __ j(X86Condition(true_high_cond), true_label);
+ __ j(X86Condition(false_high_cond), false_label);
}
// Must be equal high, so compare the lows.
if (val_low == 0) {
@@ -1120,12 +1143,12 @@
__ cmpl(left_high, right_high);
if (if_cond == kCondNE) {
- __ j(X86SignedCondition(true_high_cond), true_label);
+ __ j(X86Condition(true_high_cond), true_label);
} else if (if_cond == kCondEQ) {
- __ j(X86SignedCondition(false_high_cond), false_label);
+ __ j(X86Condition(false_high_cond), false_label);
} else {
- __ j(X86SignedCondition(true_high_cond), true_label);
- __ j(X86SignedCondition(false_high_cond), false_label);
+ __ j(X86Condition(true_high_cond), true_label);
+ __ j(X86Condition(false_high_cond), false_label);
}
// Must be equal high, so compare the lows.
__ cmpl(left_low, right_low);
@@ -1214,7 +1237,7 @@
}
__ j(kNotEqual, true_target);
} else {
- __ j(X86SignedCondition(cond->AsCondition()->GetCondition()), true_target);
+ __ j(X86Condition(cond->AsCondition()->GetCondition()), true_target);
}
} else {
// Condition has not been materialized, use its inputs as the
@@ -1247,7 +1270,7 @@
} else {
__ cmpl(lhs.AsRegister<Register>(), Address(ESP, rhs.GetStackIndex()));
}
- __ j(X86SignedCondition(cond->AsCondition()->GetCondition()), true_target);
+ __ j(X86Condition(cond->AsCondition()->GetCondition()), true_target);
}
}
if (false_target != nullptr) {
@@ -1405,7 +1428,7 @@
} else {
__ cmpl(lhs.AsRegister<Register>(), Address(ESP, rhs.GetStackIndex()));
}
- __ setb(X86SignedCondition(cond->GetCondition()), reg);
+ __ setb(X86Condition(cond->GetCondition()), reg);
return;
}
case Primitive::kPrimLong:
@@ -1483,6 +1506,38 @@
VisitCondition(comp);
}
+void LocationsBuilderX86::VisitBelow(HBelow* comp) {
+ VisitCondition(comp);
+}
+
+void InstructionCodeGeneratorX86::VisitBelow(HBelow* comp) {
+ VisitCondition(comp);
+}
+
+void LocationsBuilderX86::VisitBelowOrEqual(HBelowOrEqual* comp) {
+ VisitCondition(comp);
+}
+
+void InstructionCodeGeneratorX86::VisitBelowOrEqual(HBelowOrEqual* comp) {
+ VisitCondition(comp);
+}
+
+void LocationsBuilderX86::VisitAbove(HAbove* comp) {
+ VisitCondition(comp);
+}
+
+void InstructionCodeGeneratorX86::VisitAbove(HAbove* comp) {
+ VisitCondition(comp);
+}
+
+void LocationsBuilderX86::VisitAboveOrEqual(HAboveOrEqual* comp) {
+ VisitCondition(comp);
+}
+
+void InstructionCodeGeneratorX86::VisitAboveOrEqual(HAboveOrEqual* comp) {
+ VisitCondition(comp);
+}
+
void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(constant, LocationSummary::kNoCall);