+static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_ICMP(>=, Int8, uint8_t);
+ IMPLEMENT_ICMP(>=, Int16, uint16_t);
+ IMPLEMENT_ICMP(>=, Int32, uint32_t);
+ IMPLEMENT_ICMP(>=, Int64, uint64_t);
+ IMPLEMENT_POINTERCMP(>=);
+ default:
+ cerr << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_ICMP(>=, Int8, int8_t);
+ IMPLEMENT_ICMP(>=, Int16, int16_t);
+ IMPLEMENT_ICMP(>=, Int32, int32_t);
+ IMPLEMENT_ICMP(>=, Int64, int64_t);
+ IMPLEMENT_POINTERCMP(>=);
+ default:
+ cerr << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+void Interpreter::visitICmpInst(ICmpInst &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 ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
+ default:
+ cerr << "Don't know how to handle this ICmp predicate!\n-->" << I;
+ abort();
+ }
+
+ SetValue(&I, R, SF);
+}
+
+#define IMPLEMENT_FCMP(OP, TY) \
+ case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break
+
+static GenericValue executeFCMP_EQ(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(==, Float);
+ IMPLEMENT_FCMP(==, Double);
+ default:
+ cerr << "Unhandled type for SetEQ instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_FCMP(!=, Float);
+ IMPLEMENT_FCMP(!=, Double);
+
+ default:
+ cerr << "Unhandled type for SetNE instruction: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
+
+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();
+ }
+}
+