about summary refs log tree commit diff homepage
path: root/lib/Core/ExecutorUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Core/ExecutorUtil.cpp')
-rw-r--r--lib/Core/ExecutorUtil.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/Core/ExecutorUtil.cpp b/lib/Core/ExecutorUtil.cpp
new file mode 100644
index 00000000..3b11dd42
--- /dev/null
+++ b/lib/Core/ExecutorUtil.cpp
@@ -0,0 +1,144 @@
+//===-- ExecutorUtil.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Executor.h"
+
+#include "klee/Expr.h"
+#include "klee/Interpreter.h"
+#include "klee/Machine.h"
+#include "klee/Solver.h"
+
+#include "klee/Internal/Module/KModule.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Target/TargetData.h"
+#include <iostream>
+#include <cassert>
+
+using namespace klee;
+using namespace llvm;
+
+namespace klee {
+
+ref<Expr> 
+Executor::evalConstantExpr(llvm::ConstantExpr *ce) {
+  const llvm::Type *type = ce->getType();
+
+  ref<Expr> op1(0,Expr::Bool), op2(0,Expr::Bool), op3(0,Expr::Bool);
+  int numOperands = ce->getNumOperands();
+
+  if (numOperands > 0) op1 = evalConstant(ce->getOperand(0));
+  if (numOperands > 1) op2 = evalConstant(ce->getOperand(1));
+  if (numOperands > 2) op3 = evalConstant(ce->getOperand(2));
+  
+  switch (ce->getOpcode()) {
+    case Instruction::Trunc: return ExtractExpr::createByteOff(op1, 
+							       0,
+							       Expr::getWidthForLLVMType(type));
+    case Instruction::ZExt:  return  ZExtExpr::create(op1, 
+                                                      Expr::getWidthForLLVMType(type));
+    case Instruction::SExt:  return  SExtExpr::create(op1, 
+                                                      Expr::getWidthForLLVMType(type));
+    case Instruction::Add:   return   AddExpr::create(op1, op2);
+    case Instruction::Sub:   return   SubExpr::create(op1, op2);
+    case Instruction::Mul:   return   MulExpr::create(op1, op2);
+    case Instruction::SDiv:  return  SDivExpr::create(op1, op2);
+    case Instruction::UDiv:  return  UDivExpr::create(op1, op2);
+    case Instruction::SRem:  return  SRemExpr::create(op1, op2);
+    case Instruction::URem:  return  URemExpr::create(op1, op2);
+    case Instruction::And:   return   AndExpr::create(op1, op2);
+    case Instruction::Or:    return    OrExpr::create(op1, op2);
+    case Instruction::Xor:   return   XorExpr::create(op1, op2);
+    case Instruction::Shl:   return   ShlExpr::create(op1, op2);
+    case Instruction::LShr:  return  LShrExpr::create(op1, op2);
+    case Instruction::AShr:  return  AShrExpr::create(op1, op2);
+    case Instruction::BitCast:  return op1;
+
+    case Instruction::IntToPtr: {
+      return ZExtExpr::create(op1, Expr::getWidthForLLVMType(type));
+    } 
+
+    case Instruction::PtrToInt: {
+      return ZExtExpr::create(op1, Expr::getWidthForLLVMType(type));
+    }
+      
+    case Instruction::GetElementPtr: {
+      ref<Expr> base = op1;
+
+      for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce);
+           ii != ie; ++ii) {
+        ref<Expr> addend(0, kMachinePointerType);
+        
+        if (const StructType *st = dyn_cast<StructType>(*ii)) {
+          const StructLayout *sl = kmodule->targetData->getStructLayout(st);
+          const ConstantInt *ci = cast<ConstantInt>(ii.getOperand());
+          
+          addend = Expr::createPointer(sl->getElementOffset((unsigned)
+                                                            ci->getZExtValue()));
+        } else {
+          const SequentialType *st = cast<SequentialType>(*ii);
+          ref<Expr> index = evalConstant(cast<Constant>(ii.getOperand()));
+          unsigned elementSize = kmodule->targetData->getTypeStoreSize(st->getElementType());
+          
+          index = Expr::createCoerceToPointerType(index);
+          addend = MulExpr::create(index,
+                                   Expr::createPointer(elementSize));
+        }
+        
+        base = AddExpr::create(base, addend);
+      }
+      
+      return base;
+    }
+      
+    case Instruction::ICmp: {
+      switch(ce->getPredicate()) {
+        case ICmpInst::ICMP_EQ:  return  EqExpr::create(op1, op2);
+        case ICmpInst::ICMP_NE:  return  NeExpr::create(op1, op2);
+        case ICmpInst::ICMP_UGT: return UgtExpr::create(op1, op2);
+        case ICmpInst::ICMP_UGE: return UgeExpr::create(op1, op2);
+        case ICmpInst::ICMP_ULT: return UltExpr::create(op1, op2);
+        case ICmpInst::ICMP_ULE: return UleExpr::create(op1, op2);
+        case ICmpInst::ICMP_SGT: return SgtExpr::create(op1, op2);
+        case ICmpInst::ICMP_SGE: return SgeExpr::create(op1, op2);
+        case ICmpInst::ICMP_SLT: return SltExpr::create(op1, op2);
+        case ICmpInst::ICMP_SLE: return SleExpr::create(op1, op2);
+        default:
+          assert(0 && "unhandled ICmp predicate");
+      }
+    }
+      
+    case Instruction::Select: {
+      return SelectExpr::create(op1, op2, op3);
+    }
+
+    case Instruction::FDiv:
+    case Instruction::FRem:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+    case Instruction::FCmp:
+      assert(0 && "floating point ConstantExprs unsupported");
+
+    default :
+      assert(0 && "unknown ConstantExpr type");
+  }
+}
+
+}