aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/JSBackend/JSBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/JSBackend/JSBackend.cpp')
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index 8231af4f25..df9c7ebc21 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -1097,24 +1097,50 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod
case Instruction::FCmp: {
Code << getAssign(iName, I->getType());
switch (cast<FCmpInst>(I)->getPredicate()) {
- case FCmpInst::FCMP_OEQ:
- case FCmpInst::FCMP_UEQ: Code << getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(1)); break;
- case FCmpInst::FCMP_ONE:
+ // Comparisons which are simple JS operators.
+ case FCmpInst::FCMP_OEQ: Code << getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(1)); break;
case FCmpInst::FCMP_UNE: Code << getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(1)); break;
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_UGT: Code << getValueAsStr(I->getOperand(0)) + " > " + getValueAsStr(I->getOperand(1)); break;
- case FCmpInst::FCMP_OGE:
- case FCmpInst::FCMP_UGE: Code << getValueAsStr(I->getOperand(0)) + " >= " + getValueAsStr(I->getOperand(1)); break;
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_ULT: Code << getValueAsStr(I->getOperand(0)) + " < " + getValueAsStr(I->getOperand(1)); break;
- case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_ULE: Code << getValueAsStr(I->getOperand(0)) + " <= " + getValueAsStr(I->getOperand(1)); break;
+ case FCmpInst::FCMP_OGT: Code << getValueAsStr(I->getOperand(0)) + " > " + getValueAsStr(I->getOperand(1)); break;
+ case FCmpInst::FCMP_OGE: Code << getValueAsStr(I->getOperand(0)) + " >= " + getValueAsStr(I->getOperand(1)); break;
+ case FCmpInst::FCMP_OLT: Code << getValueAsStr(I->getOperand(0)) + " < " + getValueAsStr(I->getOperand(1)); break;
+ case FCmpInst::FCMP_OLE: Code << getValueAsStr(I->getOperand(0)) + " <= " + getValueAsStr(I->getOperand(1)); break;
+
+ // Comparisons which are inverses of JS operators.
+ case FCmpInst::FCMP_UGT:
+ Code << "!(" + getValueAsStr(I->getOperand(0)) + " <= " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+ case FCmpInst::FCMP_UGE:
+ Code << "!(" + getValueAsStr(I->getOperand(0)) + " < " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+ case FCmpInst::FCMP_ULT:
+ Code << "!(" + getValueAsStr(I->getOperand(0)) + " >= " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+ case FCmpInst::FCMP_ULE:
+ Code << "!(" + getValueAsStr(I->getOperand(0)) + " > " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+
+ // Comparisons which require explicit NaN checks.
+ case FCmpInst::FCMP_UEQ:
+ Code << "(" + getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(0)) + ") | " +
+ "(" + getValueAsStr(I->getOperand(1)) + " != " + getValueAsStr(I->getOperand(1)) + ") |" +
+ "(" + getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+ case FCmpInst::FCMP_ONE:
+ Code << "(" + getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(0)) + ") & " +
+ "(" + getValueAsStr(I->getOperand(1)) + " == " + getValueAsStr(I->getOperand(1)) + ") &" +
+ "(" + getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(1)) + ")";
+ break;
+
+ // Simple NaN checks.
case FCmpInst::FCMP_ORD: Code << "(" + getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(0)) + ") & " +
"(" + getValueAsStr(I->getOperand(1)) + " == " + getValueAsStr(I->getOperand(1)) + ")"; break;
case FCmpInst::FCMP_UNO: Code << "(" + getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(0)) + ") | " +
"(" + getValueAsStr(I->getOperand(1)) + " != " + getValueAsStr(I->getOperand(1)) + ")"; break;
+
+ // Simple constants.
case FCmpInst::FCMP_FALSE: Code << "0"; break;
case FCmpInst::FCMP_TRUE : Code << "1"; break;
+
default: error("bad fcmp"); break;
}
Code << ";";