#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"
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;
// 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
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;
}
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;
// 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...