Bitcast all the bits of a floating point value, not just one. The zero
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / Execution.cpp
index 091b8e553160d7969de4de4b12e07f6eb66c3e9d..4d6c0db10540412be066eade101fb29a0ff17402 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/CodeGen/IntrinsicLowering.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/ADT/APInt.h"
@@ -844,8 +845,8 @@ void Interpreter::visitCallSite(CallSite CS) {
   ExecutionContext &SF = ECStack.back();
 
   // Check to see if this is an intrinsic function call...
-  if (Function *F = CS.getCalledFunction())
-   if (F->isDeclaration ())
+  Function *F = CS.getCalledFunction();
+  if (F && F->isDeclaration ())
     switch (F->getIntrinsicID()) {
     case Intrinsic::not_intrinsic:
       break;
@@ -865,36 +866,46 @@ void Interpreter::visitCallSite(CallSite CS) {
       // If it is an unknown intrinsic function, use the intrinsic lowering
       // class to transform it into hopefully tasty LLVM code.
       //
-      Instruction *Prev = CS.getInstruction()->getPrev();
+      BasicBlock::iterator me(CS.getInstruction());
       BasicBlock *Parent = CS.getInstruction()->getParent();
+      bool atBegin(Parent->begin() == me);
+      if (!atBegin)
+        --me;
       IL->LowerIntrinsicCall(cast<CallInst>(CS.getInstruction()));
 
       // Restore the CurInst pointer to the first instruction newly inserted, if
       // any.
-      if (!Prev) {
+      if (atBegin) {
         SF.CurInst = Parent->begin();
       } else {
-        SF.CurInst = Prev;
+        SF.CurInst = me;
         ++SF.CurInst;
       }
       return;
     }
 
+
   SF.Caller = CS;
   std::vector<GenericValue> ArgVals;
   const unsigned NumArgs = SF.Caller.arg_size();
   ArgVals.reserve(NumArgs);
+  uint16_t pNum = 1;
   for (CallSite::arg_iterator i = SF.Caller.arg_begin(),
-         e = SF.Caller.arg_end(); i != e; ++i) {
+         e = SF.Caller.arg_end(); i != e; ++i, ++pNum) {
     Value *V = *i;
     ArgVals.push_back(getOperandValue(V, SF));
-    // Promote all integral types whose size is < sizeof(int) into ints.  We do
-    // this by zero or sign extending the value as appropriate according to the
-    // source type.
-    const Type *Ty = V->getType();
-    if (Ty->isInteger())
-      if (ArgVals.back().IntVal.getBitWidth() < 32)
-        ArgVals.back().IntVal = ArgVals.back().IntVal.sext(32);
+    if (F) {
+     // Promote all integral types whose size is < sizeof(i32) into i32.  
+     // We do this by zero or sign extending the value as appropriate 
+     // according to the parameter attributes
+      const Type *Ty = V->getType();
+      if (Ty->isInteger() && (ArgVals.back().IntVal.getBitWidth() < 32))
+        if (const ParamAttrsList *PA = F->getParamAttrs())
+          if (PA->paramHasAttr(pNum, ParamAttr::ZExt))
+            ArgVals.back().IntVal = ArgVals.back().IntVal.zext(32);
+          else if (PA->paramHasAttr(pNum, ParamAttr::SExt))
+            ArgVals.back().IntVal = ArgVals.back().IntVal.sext(32);
+     }
   }
 
   // To handle indirect calls, we must get the pointer value from the argument
@@ -1062,7 +1073,7 @@ GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, const Type *DstTy,
   if (PtrSize != Src.IntVal.getBitWidth())
     Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
 
-  Dest.PointerVal = (PointerTy) Src.IntVal.getZExtValue();
+  Dest.PointerVal = PointerTy(intptr_t(Src.IntVal.getZExtValue()));
   return Dest;
 }
 
@@ -1076,8 +1087,10 @@ GenericValue Interpreter::executeBitCastInst(Value *SrcVal, const Type *DstTy,
     Dest.PointerVal = Src.PointerVal;
   } else if (DstTy->isInteger()) {
     if (SrcTy == Type::FloatTy) {
+      Dest.IntVal.zext(sizeof(Src.FloatVal) * 8);
       Dest.IntVal.floatToBits(Src.FloatVal);
     } else if (SrcTy == Type::DoubleTy) {
+      Dest.IntVal.zext(sizeof(Src.DoubleVal) * 8);
       Dest.IntVal.doubleToBits(Src.DoubleVal);
     } else if (SrcTy->isInteger()) {
       Dest.IntVal = Src.IntVal;
@@ -1317,7 +1330,8 @@ void Interpreter::callFunction(Function *F,
 
   // Handle non-varargs arguments...
   unsigned i = 0;
-  for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI, ++i)
+  for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); 
+       AI != E; ++AI, ++i)
     SetValue(AI, ArgVals[i], StackFrame);
 
   // Handle varargs arguments...