+static GenericValue executeFCMP_LE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(<=, Float);
+ IMPLEMENT_FCMP(<=, Double);
+ default:
+ cerr << "Unhandled type for SetLE instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+static GenericValue executeFCMP_GE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(>=, Float);
+ IMPLEMENT_FCMP(>=, Double);
+ default:
+ cerr << "Unhandled type for SetGE instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+static GenericValue executeFCMP_LT(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(<, Float);
+ IMPLEMENT_FCMP(<, Double);
+ default:
+ cerr << "Unhandled type for SetLT instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+static GenericValue executeFCMP_GT(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(>, Float);
+ IMPLEMENT_FCMP(>, Double);
+ default:
+ cerr << "Unhandled type for SetGT instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+void Interpreter::visitFCmpInst(FCmpInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ const Type *Ty = I.getOperand(0)->getType();
+ GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
+ GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+ GenericValue R; // Result
+
+ switch (I.getPredicate()) {
+ case FCmpInst::FCMP_FALSE: R.BoolVal = false;
+ case FCmpInst::FCMP_ORD: R = executeFCMP_EQ(Src1, Src2, Ty); break; ///???
+ case FCmpInst::FCMP_UNO: R = executeFCMP_NE(Src1, Src2, Ty); break; ///???
+ case FCmpInst::FCMP_OEQ:
+ case FCmpInst::FCMP_UEQ: R = executeFCMP_EQ(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ONE:
+ case FCmpInst::FCMP_UNE: R = executeFCMP_NE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLT:
+ case FCmpInst::FCMP_ULT: R = executeFCMP_LT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OGT:
+ case FCmpInst::FCMP_UGT: R = executeFCMP_GT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLE:
+ case FCmpInst::FCMP_ULE: R = executeFCMP_LE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OGE:
+ case FCmpInst::FCMP_UGE: R = executeFCMP_GE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_TRUE: R.BoolVal = true;
+ default:
+ cerr << "Don't know how to handle this FCmp predicate!\n-->" << I;
+ abort();
+ }
+
+ SetValue(&I, R, SF);
+}
+
+static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
+ GenericValue Src2, const Type *Ty) {
+ GenericValue Result;
+ switch (predicate) {
+ case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty);
+ case ICmpInst::ICMP_NE: return executeICMP_NE(Src1, Src2, Ty);
+ case ICmpInst::ICMP_UGT: return executeICMP_UGT(Src1, Src2, Ty);
+ case ICmpInst::ICMP_SGT: return executeICMP_SGT(Src1, Src2, Ty);
+ case ICmpInst::ICMP_ULT: return executeICMP_ULT(Src1, Src2, Ty);
+ case ICmpInst::ICMP_SLT: return executeICMP_SLT(Src1, Src2, Ty);
+ case ICmpInst::ICMP_UGE: return executeICMP_UGE(Src1, Src2, Ty);
+ case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty);
+ case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty);
+ case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_ORD: return executeFCMP_EQ(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UNO: return executeFCMP_NE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OEQ:
+ case FCmpInst::FCMP_UEQ: return executeFCMP_EQ(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ONE:
+ case FCmpInst::FCMP_UNE: return executeFCMP_NE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLT:
+ case FCmpInst::FCMP_ULT: return executeFCMP_LT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OGT:
+ case FCmpInst::FCMP_UGT: return executeFCMP_GT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLE:
+ case FCmpInst::FCMP_ULE: return executeFCMP_LE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OGE:
+ case FCmpInst::FCMP_UGE: return executeFCMP_GE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_FALSE: {
+ GenericValue Result;
+ Result.BoolVal = false;
+ return Result;
+ }
+ case FCmpInst::FCMP_TRUE: {
+ GenericValue Result;
+ Result.BoolVal = true;
+ return Result;
+ }
+ default:
+ cerr << "Unhandled Cmp predicate\n";
+ abort();
+ }
+}
+