aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/JSBackend/JSBackend.cpp
diff options
context:
space:
mode:
authorDan Gohman <sunfish@mozilla.com>2014-01-29 16:33:24 -0800
committerDan Gohman <sunfish@mozilla.com>2014-01-31 12:45:19 -0800
commit2f16ca666cd7696b65fde602400150734dd314fa (patch)
tree791075eafbb99cb640be09e88f230669b205c5d8 /lib/Target/JSBackend/JSBackend.cpp
parentb4814d1155650a681822bad96d4bd0d660e65fd6 (diff)
Implement unordered comparisons.
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 << ";";