aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CBackend/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/CBackend/Writer.cpp')
-rw-r--r--lib/Target/CBackend/Writer.cpp140
1 files changed, 98 insertions, 42 deletions
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index 3969ca0886..c59dd60adc 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -732,7 +732,6 @@ void CWriter::printConstant(Constant *CPV) {
case Instruction::Or:
case Instruction::Xor:
case Instruction::ICmp:
- case Instruction::FCmp:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@@ -771,25 +770,6 @@ void CWriter::printConstant(Constant *CPV) {
default: assert(0 && "Illegal ICmp predicate");
}
break;
- case Instruction::FCmp:
- switch (CE->getPredicate()) {
- case FCmpInst::FCMP_ORD:
- case FCmpInst::FCMP_UEQ:
- case FCmpInst::FCMP_OEQ: Out << " == "; break;
- case FCmpInst::FCMP_UNO:
- case FCmpInst::FCMP_UNE:
- case FCmpInst::FCMP_ONE: Out << " != "; break;
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_ULT: Out << " < "; break;
- case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_ULE: Out << " <= "; break;
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_UGT: Out << " > "; break;
- case FCmpInst::FCMP_OGE:
- case FCmpInst::FCMP_UGE: Out << " >= "; break;
- default: assert(0 && "Illegal FCmp predicate");
- }
- break;
default: assert(0 && "Illegal opcode here!");
}
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
@@ -798,7 +778,42 @@ void CWriter::printConstant(Constant *CPV) {
Out << ')';
return;
}
-
+ case Instruction::FCmp: {
+ Out << '(';
+ bool NeedsClosingParens = printConstExprCast(CE);
+ if (CE->getPredicate() == FCmpInst::FCMP_FALSE)
+ Out << "0";
+ else if (CE->getPredicate() == FCmpInst::FCMP_TRUE)
+ Out << "1";
+ else {
+ const char* op = 0;
+ switch (CE->getPredicate()) {
+ default: assert(0 && "Illegal FCmp predicate");
+ case FCmpInst::FCMP_ORD: op = "ord"; break;
+ case FCmpInst::FCMP_UNO: op = "uno"; break;
+ case FCmpInst::FCMP_UEQ: op = "ueq"; break;
+ case FCmpInst::FCMP_UNE: op = "une"; break;
+ case FCmpInst::FCMP_ULT: op = "ult"; break;
+ case FCmpInst::FCMP_ULE: op = "ule"; break;
+ case FCmpInst::FCMP_UGT: op = "ugt"; break;
+ case FCmpInst::FCMP_UGE: op = "uge"; break;
+ case FCmpInst::FCMP_OEQ: op = "oeq"; break;
+ case FCmpInst::FCMP_ONE: op = "one"; break;
+ case FCmpInst::FCMP_OLT: op = "olt"; break;
+ case FCmpInst::FCMP_OLE: op = "ole"; break;
+ case FCmpInst::FCMP_OGT: op = "ogt"; break;
+ case FCmpInst::FCMP_OGE: op = "oge"; break;
+ }
+ Out << "llvm_fcmp_" << op << "(";
+ printConstantWithCast(CE->getOperand(0), CE->getOpcode());
+ Out << ", ";
+ printConstantWithCast(CE->getOperand(1), CE->getOpcode());
+ Out << ")";
+ }
+ if (NeedsClosingParens)
+ Out << "))";
+ Out << ')';
+ }
default:
cerr << "CWriter Error: Unhandled constant expression: "
<< *CE << "\n";
@@ -1563,6 +1578,37 @@ bool CWriter::doInitialization(Module &M) {
if (!M.empty())
Out << "\n\n/* Function Bodies */\n";
+
+ // Emit some helper functions for dealing with FCMP instruction's
+ // predicates
+ Out << "static inline int llvm_fcmp_ord(double X, double Y) { ";
+ Out << "return X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_uno(double X, double Y) { ";
+ Out << "return X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_ueq(double X, double Y) { ";
+ Out << "return X == Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_une(double X, double Y) { ";
+ Out << "return X != Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_ult(double X, double Y) { ";
+ Out << "return X < Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_ugt(double X, double Y) { ";
+ Out << "return X > Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_ule(double X, double Y) { ";
+ Out << "return X <= Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_uge(double X, double Y) { ";
+ Out << "return X >= Y || X != X || Y != Y; }\n";
+ Out << "static inline int llvm_fcmp_oeq(double X, double Y) { ";
+ Out << "return X == Y && X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_one(double X, double Y) { ";
+ Out << "return X != Y && X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_olt(double X, double Y) { ";
+ Out << "return X < Y && X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_ogt(double X, double Y) { ";
+ Out << "return X > Y && X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_ole(double X, double Y) { ";
+ Out << "return X <= Y && X == X && Y == Y; }\n";
+ Out << "static inline int llvm_fcmp_oge(double X, double Y) { ";
+ Out << "return X >= Y && X == X && Y == Y; }\n";
return false;
}
@@ -2147,31 +2193,41 @@ void CWriter::visitICmpInst(ICmpInst &I) {
}
void CWriter::visitFCmpInst(FCmpInst &I) {
- // Write the first operand
- writeOperand(I.getOperand(0));
+ if (I.getPredicate() == FCmpInst::FCMP_FALSE) {
+ Out << "0";
+ return;
+ }
+ if (I.getPredicate() == FCmpInst::FCMP_TRUE) {
+ Out << "1";
+ return;
+ }
- // Write the predicate
+ const char* op = 0;
switch (I.getPredicate()) {
- case FCmpInst::FCMP_FALSE: Out << " 0 "; break;
- case FCmpInst::FCMP_ORD:
- case FCmpInst::FCMP_OEQ:
- case FCmpInst::FCMP_UEQ: Out << " == "; break;
- case FCmpInst::FCMP_UNO:
- case FCmpInst::FCMP_ONE:
- case FCmpInst::FCMP_UNE: Out << " != "; break;
- case FCmpInst::FCMP_ULE:
- case FCmpInst::FCMP_OLE: Out << " <= "; break;
- case FCmpInst::FCMP_UGE:
- case FCmpInst::FCMP_OGE: Out << " >= "; break;
- case FCmpInst::FCMP_ULT:
- case FCmpInst::FCMP_OLT: Out << " < "; break;
- case FCmpInst::FCMP_UGT:
- case FCmpInst::FCMP_OGT: Out << " > "; break;
- case FCmpInst::FCMP_TRUE: Out << " 1 "; break;
- default: cerr << "Invalid fcmp predicate!" << I; abort();
- }
+ default: assert(0 && "Illegal FCmp predicate");
+ case FCmpInst::FCMP_ORD: op = "ord"; break;
+ case FCmpInst::FCMP_UNO: op = "uno"; break;
+ case FCmpInst::FCMP_UEQ: op = "ueq"; break;
+ case FCmpInst::FCMP_UNE: op = "une"; break;
+ case FCmpInst::FCMP_ULT: op = "ult"; break;
+ case FCmpInst::FCMP_ULE: op = "ule"; break;
+ case FCmpInst::FCMP_UGT: op = "ugt"; break;
+ case FCmpInst::FCMP_UGE: op = "uge"; break;
+ case FCmpInst::FCMP_OEQ: op = "oeq"; break;
+ case FCmpInst::FCMP_ONE: op = "one"; break;
+ case FCmpInst::FCMP_OLT: op = "olt"; break;
+ case FCmpInst::FCMP_OLE: op = "ole"; break;
+ case FCmpInst::FCMP_OGT: op = "ogt"; break;
+ case FCmpInst::FCMP_OGE: op = "oge"; break;
+ }
+
+ Out << "llvm_fcmp_" << op << "(";
+ // Write the first operand
+ writeOperand(I.getOperand(0));
+ Out << ", ";
// Write the second operand
writeOperand(I.getOperand(1));
+ Out << ")";
}
static const char * getFloatBitCastField(const Type *Ty) {