aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/JSBackend/JSBackend.cpp
diff options
context:
space:
mode:
authorDan Gohman <sunfish@mozilla.com>2014-01-29 16:33:10 -0800
committerDan Gohman <sunfish@mozilla.com>2014-01-31 12:45:16 -0800
commitb4814d1155650a681822bad96d4bd0d660e65fd6 (patch)
tree059e91178c433be59c5c618cf8d5c3afbd86927b /lib/Target/JSBackend/JSBackend.cpp
parentb8c6d7658d89d53acaae44e8f4359578a7fa5dba (diff)
Implement FNeg operators.
Diffstat (limited to 'lib/Target/JSBackend/JSBackend.cpp')
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index fccdb52bf7..8231af4f25 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -876,7 +876,6 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi
switch (I->getOpcode()) {
default: dumpIR(I); error("invalid vector instr"); break;
case Instruction::FAdd: Code << "SIMD.float32x4.add(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
- case Instruction::FSub: Code << "SIMD.float32x4.sub(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
case Instruction::FMul: Code << "SIMD.float32x4.mul(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
case Instruction::FDiv: Code << "SIMD.float32x4.div(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
case Instruction::Add: Code << "SIMD.int32x4.add(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
@@ -885,6 +884,14 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi
case Instruction::And: Code << "SIMD.int32x4.and(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
case Instruction::Or: Code << "SIMD.int32x4.or(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
case Instruction::Xor: Code << "SIMD.int32x4.xor(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break;
+ case Instruction::FSub:
+ // LLVM represents an fneg(x) as -0.0 - x.
+ if (BinaryOperator::isFNeg(I)) {
+ Code << "SIMD.float32x4.neg(" + getValueAsStr(BinaryOperator::getFNegArgument(I)) + ")";
+ } else {
+ Code << "SIMD.float32x4.sub(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")";
+ }
+ break;
case Instruction::BitCast: {
if (cast<VectorType>(I->getType())->getElementType()->isIntegerTy()) {
Code << "SIMD.float32x4.bitsToInt32x4(" + getValueAsStr(I->getOperand(0)) + ')';
@@ -1071,10 +1078,17 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod
break;
}
case Instruction::FAdd: Code << getValueAsStr(I->getOperand(0)) + " + " + getValueAsStr(I->getOperand(1)); break; // TODO: ensurefloat here
- case Instruction::FSub: Code << getValueAsStr(I->getOperand(0)) + " - " + getValueAsStr(I->getOperand(1)); break;
case Instruction::FMul: Code << getValueAsStr(I->getOperand(0)) + " * " + getValueAsStr(I->getOperand(1)); break;
case Instruction::FDiv: Code << getValueAsStr(I->getOperand(0)) + " / " + getValueAsStr(I->getOperand(1)); break;
case Instruction::FRem: Code << getValueAsStr(I->getOperand(0)) + " % " + getValueAsStr(I->getOperand(1)); break;
+ case Instruction::FSub:
+ // LLVM represents an fneg(x) as -0.0 - x.
+ if (BinaryOperator::isFNeg(I)) {
+ Code << "-" + getValueAsStr(BinaryOperator::getFNegArgument(I));
+ } else {
+ Code << getValueAsStr(I->getOperand(0)) + " - " + getValueAsStr(I->getOperand(1));
+ }
+ break;
default: error("bad icmp"); break;
}
Code << ';';