30#define DEBUG_TYPE "interpreter"
32STATISTIC(NumDynamicInsts,
"Number of dynamic instructions executed");
35 cl::desc(
"make the interpreter print every volatile load and store"));
50 switch (Ty->getTypeID()) {
64 Type *Ty =
I.getOperand(0)->getType();
69 if (Ty->isVectorTy()) {
70 R.AggregateVal.resize(Src.AggregateVal.size());
72 switch(
I.getOpcode()) {
76 case Instruction::FNeg:
78 for (
unsigned i = 0; i < R.AggregateVal.size(); ++i)
79 R.AggregateVal[i].FloatVal = -Src.AggregateVal[i].FloatVal;
81 for (
unsigned i = 0; i < R.AggregateVal.size(); ++i)
82 R.AggregateVal[i].DoubleVal = -Src.AggregateVal[i].DoubleVal;
89 switch (
I.getOpcode()) {
103#define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
104 case Type::TY##TyID: \
105 Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
110 switch (Ty->getTypeID()) {
114 dbgs() <<
"Unhandled type for FAdd instruction: " << *Ty <<
"\n";
121 switch (Ty->getTypeID()) {
125 dbgs() <<
"Unhandled type for FSub instruction: " << *Ty <<
"\n";
132 switch (Ty->getTypeID()) {
136 dbgs() <<
"Unhandled type for FMul instruction: " << *Ty <<
"\n";
143 switch (Ty->getTypeID()) {
147 dbgs() <<
"Unhandled type for FDiv instruction: " << *Ty <<
"\n";
154 switch (Ty->getTypeID()) {
162 dbgs() <<
"Unhandled type for Rem instruction: " << *Ty <<
"\n";
167#define IMPLEMENT_INTEGER_ICMP(OP, TY) \
168 case Type::IntegerTyID: \
169 Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \
172#define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY) \
173 case Type::FixedVectorTyID: \
174 case Type::ScalableVectorTyID: { \
175 assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
176 Dest.AggregateVal.resize(Src1.AggregateVal.size()); \
177 for (uint32_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
178 Dest.AggregateVal[_i].IntVal = APInt( \
179 1, Src1.AggregateVal[_i].IntVal.OP(Src2.AggregateVal[_i].IntVal)); \
186#define IMPLEMENT_POINTER_ICMP(OP) \
187 case Type::PointerTyID: \
188 Dest.IntVal = APInt(1,(void*)(intptr_t)Src1.PointerVal OP \
189 (void*)(intptr_t)Src2.PointerVal); \
195 switch (Ty->getTypeID()) {
200 dbgs() <<
"Unhandled type for ICMP_EQ predicate: " << *Ty <<
"\n";
209 switch (Ty->getTypeID()) {
214 dbgs() <<
"Unhandled type for ICMP_NE predicate: " << *Ty <<
"\n";
223 switch (Ty->getTypeID()) {
228 dbgs() <<
"Unhandled type for ICMP_ULT predicate: " << *Ty <<
"\n";
237 switch (Ty->getTypeID()) {
242 dbgs() <<
"Unhandled type for ICMP_SLT predicate: " << *Ty <<
"\n";
251 switch (Ty->getTypeID()) {
256 dbgs() <<
"Unhandled type for ICMP_UGT predicate: " << *Ty <<
"\n";
265 switch (Ty->getTypeID()) {
270 dbgs() <<
"Unhandled type for ICMP_SGT predicate: " << *Ty <<
"\n";
279 switch (Ty->getTypeID()) {
284 dbgs() <<
"Unhandled type for ICMP_ULE predicate: " << *Ty <<
"\n";
293 switch (Ty->getTypeID()) {
298 dbgs() <<
"Unhandled type for ICMP_SLE predicate: " << *Ty <<
"\n";
307 switch (Ty->getTypeID()) {
312 dbgs() <<
"Unhandled type for ICMP_UGE predicate: " << *Ty <<
"\n";
321 switch (Ty->getTypeID()) {
326 dbgs() <<
"Unhandled type for ICMP_SGE predicate: " << *Ty <<
"\n";
334 Type *Ty =
I.getOperand(0)->getType();
339 switch (
I.getPredicate()) {
351 dbgs() <<
"Don't know how to handle this ICmp predicate!\n-->" <<
I;
358#define IMPLEMENT_FCMP(OP, TY) \
359 case Type::TY##TyID: \
360 Dest.IntVal = APInt(1,Src1.TY##Val OP Src2.TY##Val); \
363#define IMPLEMENT_VECTOR_FCMP_T(OP, TY) \
364 assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
365 Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
366 for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
367 Dest.AggregateVal[_i].IntVal = APInt(1, \
368 Src1.AggregateVal[_i].TY##Val OP Src2.AggregateVal[_i].TY##Val);\
371#define IMPLEMENT_VECTOR_FCMP(OP) \
372 case Type::FixedVectorTyID: \
373 case Type::ScalableVectorTyID: \
374 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
375 IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
377 IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
383 switch (Ty->getTypeID()) {
388 dbgs() <<
"Unhandled type for FCmp EQ instruction: " << *Ty <<
"\n";
394#define IMPLEMENT_SCALAR_NANS(TY, X,Y) \
395 if (TY->isFloatTy()) { \
396 if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
397 Dest.IntVal = APInt(1,false); \
401 if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
402 Dest.IntVal = APInt(1,false); \
407#define MASK_VECTOR_NANS_T(X,Y, TZ, FLAG) \
408 assert(X.AggregateVal.size() == Y.AggregateVal.size()); \
409 Dest.AggregateVal.resize( X.AggregateVal.size() ); \
410 for( uint32_t _i=0;_i<X.AggregateVal.size();_i++) { \
411 if (X.AggregateVal[_i].TZ##Val != X.AggregateVal[_i].TZ##Val || \
412 Y.AggregateVal[_i].TZ##Val != Y.AggregateVal[_i].TZ##Val) \
413 Dest.AggregateVal[_i].IntVal = APInt(1,FLAG); \
415 Dest.AggregateVal[_i].IntVal = APInt(1,!FLAG); \
419#define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
420 if (TY->isVectorTy()) { \
421 if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
422 MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
424 MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
439 switch (Ty->getTypeID()) {
444 dbgs() <<
"Unhandled type for FCmp NE instruction: " << *Ty <<
"\n";
448 if (Ty->isVectorTy())
459 switch (Ty->getTypeID()) {
464 dbgs() <<
"Unhandled type for FCmp LE instruction: " << *Ty <<
"\n";
473 switch (Ty->getTypeID()) {
478 dbgs() <<
"Unhandled type for FCmp GE instruction: " << *Ty <<
"\n";
487 switch (Ty->getTypeID()) {
492 dbgs() <<
"Unhandled type for FCmp LT instruction: " << *Ty <<
"\n";
501 switch (Ty->getTypeID()) {
506 dbgs() <<
"Unhandled type for FCmp GT instruction: " << *Ty <<
"\n";
512#define IMPLEMENT_UNORDERED(TY, X,Y) \
513 if (TY->isFloatTy()) { \
514 if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
515 Dest.IntVal = APInt(1,true); \
518 } else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
519 Dest.IntVal = APInt(1,true); \
523#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
524 if (TY->isVectorTy()) { \
525 GenericValue DestMask = Dest; \
526 Dest = FUNC(Src1, Src2, Ty); \
527 for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
528 if (DestMask.AggregateVal[_i].IntVal == true) \
529 Dest.AggregateVal[_i].IntVal = APInt(1, true); \
591 if(Ty->isVectorTy()) {
609 }
else if (Ty->isFloatTy())
622 if(Ty->isVectorTy()) {
640 }
else if (Ty->isFloatTy())
651 Type *Ty,
const bool val) {
653 if(Ty->isVectorTy()) {
667 Type *Ty =
I.getOperand(0)->getType();
672 switch (
I.getPredicate()) {
674 dbgs() <<
"Don't know how to handle this FCmp predicate!\n-->" <<
I;
702 Type *Ty =
I.getOperand(0)->getType();
708 if (Ty->isVectorTy()) {
713#define INTEGER_VECTOR_OPERATION(OP) \
714 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
715 R.AggregateVal[i].IntVal = \
716 Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
720#define INTEGER_VECTOR_FUNCTION(OP) \
721 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
722 R.AggregateVal[i].IntVal = \
723 Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
727#define FLOAT_VECTOR_FUNCTION(OP, TY) \
728 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
729 R.AggregateVal[i].TY = \
730 Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
734#define FLOAT_VECTOR_OP(OP) { \
735 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
736 FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
738 if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
739 FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
741 dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
742 llvm_unreachable(0); \
747 switch(
I.getOpcode()){
749 dbgs() <<
"Don't know how to handle this binary operator!\n-->" <<
I;
766 case Instruction::FRem:
768 for (
unsigned i = 0; i < R.AggregateVal.size(); ++i)
769 R.AggregateVal[i].FloatVal =
773 for (
unsigned i = 0; i < R.AggregateVal.size(); ++i)
774 R.AggregateVal[i].DoubleVal =
777 dbgs() <<
"Unhandled type for Rem instruction: " << *Ty <<
"\n";
784 switch (
I.getOpcode()) {
786 dbgs() <<
"Don't know how to handle this binary operator!\n-->" <<
I;
789 case Instruction::Add: R.IntVal = Src1.
IntVal + Src2.
IntVal;
break;
790 case Instruction::Sub: R.IntVal = Src1.
IntVal - Src2.
IntVal;
break;
791 case Instruction::Mul: R.IntVal = Src1.
IntVal * Src2.
IntVal;
break;
801 case Instruction::And: R.IntVal = Src1.
IntVal & Src2.
IntVal;
break;
802 case Instruction::Or: R.IntVal = Src1.
IntVal | Src2.
IntVal;
break;
803 case Instruction::Xor: R.IntVal = Src1.
IntVal ^ Src2.
IntVal;
break;
812 if(Ty->isVectorTy()) {
820 Dest = (Src1.
IntVal == 0) ? Src3 : Src2;
827 Type * Ty =
I.getOperand(0)->getType();
856void Interpreter::popStackAndReturnValueToCaller(
Type *RetTy,
861 if (ECStack.empty()) {
863 ExitValue = std::move(Result);
870 ExecutionContext &CallingSF = ECStack.back();
876 SwitchToNewBasicBlock (
II->getNormalDest (), CallingSF);
877 CallingSF.
Caller =
nullptr;
888 if (
I.getNumOperands()) {
889 RetTy =
I.getReturnValue()->getType();
890 Result = getOperandValue(
I.getReturnValue(), SF);
893 popStackAndReturnValueToCaller(RetTy, Result);
902 SwitchToNewBasicBlock(
I.getSuccessor(), SF);
907 bool Cond = getOperandValue(
I.getCondition(), SF).IntVal != 0;
908 SwitchToNewBasicBlock(
I.getSuccessor(
Cond ? 0 : 1), SF);
919 for (
auto Case :
I.cases()) {
920 GenericValue CaseVal = getOperandValue(Case.getCaseValue(), SF);
926 if (!Dest) Dest =
I.getDefaultDest();
927 SwitchToNewBasicBlock(Dest, SF);
932 void *Dest =
GVTOP(getOperandValue(
I.getAddress(), SF));
955 std::vector<GenericValue> ResultValues;
960 assert(i != -1 &&
"PHINode doesn't contain entry for predecessor??");
964 ResultValues.push_back(getOperandValue(IncomingValue, SF));
982 Type *Ty =
I.getAllocatedType();
985 unsigned NumElements =
986 getOperandValue(
I.getOperand(0), SF).IntVal.getZExtValue();
991 unsigned MemToAlloc = std::max(1U, NumElements *
TypeSize);
997 <<
" bytes) x " << NumElements <<
" (Total: " << MemToAlloc
998 <<
") at " << uintptr_t(
Memory) <<
'\n');
1001 assert(Result.PointerVal &&
"Null pointer returned by malloc!");
1004 if (
I.getOpcode() == Instruction::Alloca)
1005 ECStack.back().Allocas.add(
Memory);
1014 "Cannot getElementOffset of a nonpointer type!");
1018 for (;
I != E; ++
I) {
1023 unsigned Index =
unsigned(CPU->getZExtValue());
1036 assert(
BitWidth == 64 &&
"Invalid index type for getelementptr");
1044 Result.PointerVal = ((
char*)getOperandValue(Ptr, SF).PointerVal) +
Total;
1051 SetValue(&
I, executeGEPOperation(
I.getPointerOperand(),
1057 GenericValue SRC = getOperandValue(
I.getPointerOperand(), SF);
1063 dbgs() <<
"Volatile load " <<
I;
1069 GenericValue SRC = getOperandValue(
I.getPointerOperand(), SF);
1071 I.getOperand(0)->getType());
1073 dbgs() <<
"Volatile store: " <<
I;
1094 SetValue(&
I, getOperandValue(*
I.arg_begin(), SF), SF);
1105 bool atBegin(Parent->
begin() == Me);
1108 IL->LowerIntrinsicCall(&
I);
1124 std::vector<GenericValue> ArgVals;
1126 ArgVals.reserve(NumArgs);
1128 ArgVals.push_back(getOperandValue(V, SF));
1140 if (orgShiftAmount < (
uint64_t)valueWidth)
1141 return orgShiftAmount;
1144 return (
NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
1153 Type *Ty =
I.getType();
1155 if (Ty->isVectorTy()) {
1158 for (
unsigned i = 0; i < src1Size; i++) {
1180 Type *Ty =
I.getType();
1182 if (Ty->isVectorTy()) {
1185 for (
unsigned i = 0; i < src1Size; i++) {
1207 Type *Ty =
I.getType();
1209 if (Ty->isVectorTy()) {
1212 for (
unsigned i = 0; i < src1Size; i++) {
1233 if (SrcTy->isVectorTy()) {
1236 unsigned NumElts = Src.AggregateVal.size();
1239 for (
unsigned i = 0; i < NumElts; i++)
1240 Dest.
AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.trunc(DBitWidth);
1252 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1256 unsigned size = Src.AggregateVal.size();
1259 for (
unsigned i = 0; i <
size; i++)
1260 Dest.
AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
1264 Dest.
IntVal = Src.IntVal.sext(DBitWidth);
1272 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1277 unsigned size = Src.AggregateVal.size();
1280 for (
unsigned i = 0; i <
size; i++)
1281 Dest.
AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
1285 Dest.
IntVal = Src.IntVal.zext(DBitWidth);
1292 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1297 "Invalid FPTrunc instruction");
1299 unsigned size = Src.AggregateVal.size();
1302 for (
unsigned i = 0; i <
size; i++)
1303 Dest.
AggregateVal[i].FloatVal = (
float)Src.AggregateVal[i].DoubleVal;
1306 "Invalid FPTrunc instruction");
1307 Dest.
FloatVal = (float)Src.DoubleVal;
1315 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1321 unsigned size = Src.AggregateVal.size();
1324 for (
unsigned i = 0; i <
size; i++)
1325 Dest.
AggregateVal[i].DoubleVal = (
double)Src.AggregateVal[i].FloatVal;
1328 "Invalid FPExt instruction");
1338 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1344 unsigned size = Src.AggregateVal.size();
1350 for (
unsigned i = 0; i <
size; i++)
1352 Src.AggregateVal[i].FloatVal, DBitWidth);
1354 for (
unsigned i = 0; i <
size; i++)
1356 Src.AggregateVal[i].DoubleVal, DBitWidth);
1376 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1382 unsigned size = Src.AggregateVal.size();
1388 for (
unsigned i = 0; i <
size; i++)
1390 Src.AggregateVal[i].FloatVal, DBitWidth);
1392 for (
unsigned i = 0; i <
size; i++)
1394 Src.AggregateVal[i].DoubleVal, DBitWidth);
1412 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1416 unsigned size = Src.AggregateVal.size();
1422 for (
unsigned i = 0; i <
size; i++)
1426 for (
unsigned i = 0; i <
size; i++)
1444 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1448 unsigned size = Src.AggregateVal.size();
1454 for (
unsigned i = 0; i <
size; i++)
1458 for (
unsigned i = 0; i <
size; i++)
1479 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1482 Dest.
IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
1488 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1492 if (PtrSize != Src.IntVal.getBitWidth())
1493 Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
1505 GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1511 GenericValue TempDst, TempSrc, SrcVec;
1514 unsigned SrcBitSize;
1515 unsigned DstBitSize;
1522 SrcNum = Src.AggregateVal.size();
1535 DstNum = (SrcNum * SrcBitSize) / DstBitSize;
1542 if (SrcNum * SrcBitSize != DstNum * DstBitSize)
1548 for (
unsigned i = 0; i < SrcNum; i++)
1553 for (
unsigned i = 0; i < SrcNum; i++)
1557 for (
unsigned i = 0; i < SrcNum; i++)
1565 if (DstNum < SrcNum) {
1567 unsigned Ratio = SrcNum / DstNum;
1568 unsigned SrcElt = 0;
1569 for (
unsigned i = 0; i < DstNum; i++) {
1573 unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
1574 for (
unsigned j = 0;
j < Ratio;
j++) {
1576 Tmp = Tmp.
zext(SrcBitSize);
1578 Tmp = Tmp.
zext(DstBitSize);
1580 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
1587 unsigned Ratio = DstNum / SrcNum;
1588 for (
unsigned i = 0; i < SrcNum; i++) {
1589 unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
1590 for (
unsigned j = 0;
j < Ratio;
j++) {
1596 if (DstBitSize < SrcBitSize)
1598 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
1608 for (
unsigned i = 0; i < DstNum; i++)
1613 for (
unsigned i = 0; i < DstNum; i++)
1640 Dest.
IntVal = Src.IntVal;
1646 Dest.
FloatVal = Src.IntVal.bitsToFloat();
1652 Dest.
DoubleVal = Src.IntVal.bitsToDouble();
1666 SetValue(&
I, executeTruncInst(
I.getOperand(0),
I.getType(), SF), SF);
1671 SetValue(&
I, executeSExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1676 SetValue(&
I, executeZExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1681 SetValue(&
I, executeFPTruncInst(
I.getOperand(0),
I.getType(), SF), SF);
1686 SetValue(&
I, executeFPExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1691 SetValue(&
I, executeUIToFPInst(
I.getOperand(0),
I.getType(), SF), SF);
1696 SetValue(&
I, executeSIToFPInst(
I.getOperand(0),
I.getType(), SF), SF);
1701 SetValue(&
I, executeFPToUIInst(
I.getOperand(0),
I.getType(), SF), SF);
1706 SetValue(&
I, executeFPToSIInst(
I.getOperand(0),
I.getType(), SF), SF);
1711 SetValue(&
I, executePtrToIntInst(
I.getOperand(0),
I.getType(), SF), SF);
1716 SetValue(&
I, executeIntToPtrInst(
I.getOperand(0),
I.getType(), SF), SF);
1721 SetValue(&
I, executeBitCastInst(
I.getOperand(0),
I.getType(), SF), SF);
1724#define IMPLEMENT_VAARG(TY) \
1725 case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
1736 Type *Ty =
I.getType();
1737 switch (Ty->getTypeID()) {
1739 Dest.
IntVal = Src.IntVal;
1745 dbgs() <<
"Unhandled dest type for vaarg instruction: " << *Ty <<
"\n";
1762 Type *Ty =
I.getType();
1766 switch (Ty->getTypeID()) {
1768 dbgs() <<
"Unhandled destination type for extractelement instruction: "
1783 dbgs() <<
"Invalid index in extractelement instruction\n";
1798 Type *TyContained = Ty->getElementType();
1834 Type *TyContained = Ty->getElementType();
1837 unsigned src3Size =
I.getShuffleMask().size();
1846 for(
unsigned i=0; i<src3Size; i++) {
1847 unsigned j = std::max(0,
I.getMaskValue(i));
1850 else if(j < src1Size + src2Size)
1862 for(
unsigned i=0; i<src3Size; i++) {
1863 unsigned j = std::max(0,
I.getMaskValue(i));
1866 else if(j < src1Size + src2Size)
1873 for(
unsigned i=0; i<src3Size; i++) {
1874 unsigned j = std::max(0,
I.getMaskValue(i));
1877 else if(j < src1Size + src2Size)
1890 Value *Agg =
I.getAggregateOperand();
1895 unsigned Num =
I.getNumIndices();
1898 for (
unsigned i = 0 ; i < Num; ++i) {
1934 Value *Agg =
I.getAggregateOperand();
1941 unsigned Num =
I.getNumIndices();
1944 for (
unsigned i = 0 ; i < Num; ++i) {
1981 switch (CE->getOpcode()) {
1982 case Instruction::Trunc:
1983 return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
1984 case Instruction::PtrToInt:
1985 return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
1986 case Instruction::IntToPtr:
1987 return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
1988 case Instruction::BitCast:
1989 return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
1990 case Instruction::GetElementPtr:
1991 return executeGEPOperation(CE->getOperand(0),
gep_type_begin(CE),
1998 GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
1999 GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
2001 switch (CE->getOpcode()) {
2006 case Instruction::Shl:
2010 dbgs() <<
"Unhandled ConstantExpr: " << *CE <<
"\n";
2018 return getConstantExprValue(CE, SF);
2036 assert((ECStack.empty() || !ECStack.back().Caller ||
2037 ECStack.back().Caller->arg_size() == ArgVals.
size()) &&
2038 "Incorrect number of arguments passed into function call!");
2040 ECStack.emplace_back();
2045 if (
F->isDeclaration()) {
2048 popStackAndReturnValueToCaller (
F->getReturnType (), Result);
2053 StackFrame.
CurBB = &
F->front();
2058 (ArgVals.
size() >
F->arg_size() &&
F->getFunctionType()->isVarArg()))&&
2059 "Invalid number of values passed to function invocation!");
2065 SetValue(&*AI, ArgVals[i], StackFrame);
2073 while (!ECStack.empty()) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2, Type *Ty)
static void executeFSubInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2, Type *Ty)
#define FLOAT_VECTOR_OP(OP)
#define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY)
static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2, Type *Ty)
static void executeFDivInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2, Type *Ty)
#define INTEGER_VECTOR_OPERATION(OP)
#define IMPLEMENT_BINARY_OPERATOR(OP, TY)
static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2, Type *Ty)
#define IMPLEMENT_SCALAR_NANS(TY, X, Y)
static void executeFAddInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, GenericValue Src3, Type *Ty)
static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2, Type *Ty)
static void executeFNegInst(GenericValue &Dest, GenericValue Src, Type *Ty)
static cl::opt< bool > PrintVolatile("interpreter-print-volatile", cl::Hidden, cl::desc("make the interpreter print every volatile load and store"))
#define INTEGER_VECTOR_FUNCTION(OP)
#define MASK_VECTOR_NANS(TY, X, Y, FLAG)
#define IMPLEMENT_VECTOR_FCMP(OP)
static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2, Type *Ty)
#define IMPLEMENT_POINTER_ICMP(OP)
static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2, Type *Ty)
#define IMPLEMENT_UNORDERED(TY, X, Y)
static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2, Type *Ty, const bool val)
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF)
#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC)
#define IMPLEMENT_VAARG(TY)
static void executeFRemInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
static unsigned getShiftAmount(uint64_t orgShiftAmount, llvm::APInt valueToShift)
#define IMPLEMENT_INTEGER_ICMP(OP, TY)
#define IMPLEMENT_FCMP(OP, TY)
static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2, Type *Ty)
static void executeFMulInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2, Type *Ty)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt floatToBits(float V)
Converts a float to APInt bits.
LLVM_ABI APInt urem(const APInt &RHS) const
Unsigned remainder operation.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
LLVM_ABI APInt srem(const APInt &RHS) const
Function for signed remainder operation.
static APInt doubleToBits(double V)
Converts a double to APInt bits.
APInt shl(unsigned shiftAmt) const
Left-shift function.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Conditional Branch instruction.
A constant value that is initialized with an expression using other constant values.
This is the shared class of boolean and integer constants.
unsigned getPointerSizeInBits(unsigned AS=0) const
The size in bits of the pointer representation in a given address space.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, Type *Ty)
StoreValueToMemory - Stores the data in Val of type Ty at address Ptr.
GenericValue getConstantValue(const Constant *C)
Converts a Constant* into a GenericValue, including handling of ConstantExpr values.
const DataLayout & getDataLayout() const
void * getPointerToGlobal(const GlobalValue *GV)
getPointerToGlobal - This returns the address of the specified global value.
void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, Type *Ty)
FIXME: document.
This instruction compares its operands according to the predicate given to the constructor.
This class represents an extension of floating point types.
This class represents a cast from floating point to signed integer.
This class represents a cast from floating point to unsigned integer.
This class represents a truncation of floating point types.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
Indirect Branch Instruction.
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
void visit(Iterator Start, Iterator End)
This class represents a cast from an integer to a pointer.
Class to represent integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
void visitSIToFPInst(SIToFPInst &I)
void visitFCmpInst(FCmpInst &I)
void visitPtrToIntInst(PtrToIntInst &I)
void visitShuffleVectorInst(ShuffleVectorInst &I)
void visitCallBase(CallBase &I)
void visitAllocaInst(AllocaInst &I)
void visitSelectInst(SelectInst &I)
void exitCalled(GenericValue GV)
void visitReturnInst(ReturnInst &I)
void visitIntToPtrInst(IntToPtrInst &I)
void visitUncondBrInst(UncondBrInst &I)
void visitUnreachableInst(UnreachableInst &I)
void visitICmpInst(ICmpInst &I)
void visitLShr(BinaryOperator &I)
void visitUIToFPInst(UIToFPInst &I)
void visitIndirectBrInst(IndirectBrInst &I)
void visitInsertValueInst(InsertValueInst &I)
void runAtExitHandlers()
runAtExitHandlers - Run any functions registered by the program's calls to atexit(3),...
void visitVAArgInst(VAArgInst &I)
void visitStoreInst(StoreInst &I)
void visitExtractValueInst(ExtractValueInst &I)
void visitSwitchInst(SwitchInst &I)
void visitExtractElementInst(ExtractElementInst &I)
void visitVACopyInst(VACopyInst &I)
void visitVAEndInst(VAEndInst &I)
void visitTruncInst(TruncInst &I)
void visitFPToUIInst(FPToUIInst &I)
void visitLoadInst(LoadInst &I)
void visitGetElementPtrInst(GetElementPtrInst &I)
void callFunction(Function *F, ArrayRef< GenericValue > ArgVals)
void visitInsertElementInst(InsertElementInst &I)
void visitUnaryOperator(UnaryOperator &I)
void visitFPExtInst(FPExtInst &I)
void visitVAStartInst(VAStartInst &I)
void visitBitCastInst(BitCastInst &I)
void visitCondBrInst(CondBrInst &I)
void visitSExtInst(SExtInst &I)
void visitAShr(BinaryOperator &I)
GenericValue callExternalFunction(Function *F, ArrayRef< GenericValue > ArgVals)
void visitFPTruncInst(FPTruncInst &I)
void visitBinaryOperator(BinaryOperator &I)
void visitShl(BinaryOperator &I)
void visitZExtInst(ZExtInst &I)
void visitFPToSIInst(FPToSIInst &I)
void visitIntrinsicInst(IntrinsicInst &I)
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
This class represents a cast from a pointer to an integer.
Return a value (possibly void), from a function.
This class represents a sign extension of integer types.
This class represents a cast from signed integer to floating point.
This class represents the LLVM 'select' instruction.
This instruction constructs a fixed permutation of two input vectors.
An instruction for storing to memory.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ DoubleTyID
64-bit floating point type
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isVoidTy() const
Return true if this is 'void'.
This class represents a cast unsigned integer to floating point.
Unconditional Branch instruction.
This function has undefined behavior.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
This represents the llvm.va_copy intrinsic.
This represents the llvm.va_end intrinsic.
This represents the llvm.va_start intrinsic.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
Base class of all SIMD vector types.
This class represents zero extension of integer types.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
float RoundAPIntToFloat(const APInt &APIVal)
Converts the given APInt to a float value.
double RoundAPIntToDouble(const APInt &APIVal)
Converts the given APInt to a double value.
APInt RoundFloatToAPInt(float Float, unsigned width)
Converts a float value into a APInt.
LLVM_ABI APInt RoundDoubleToAPInt(double Double, unsigned width)
Converts the given double value into a APInt.
double RoundSignedAPIntToDouble(const APInt &APIVal)
Converts the given APInt to a double value.
float RoundSignedAPIntToFloat(const APInt &APIVal)
Converts the given APInt to a float value.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_end(const User *GEP)
GenericValue PTOGV(void *P)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr unsigned BitWidth
void * GVTOP(const GenericValue &GV)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
BasicBlock::iterator CurInst
std::map< Value *, GenericValue > Values
std::vector< GenericValue > VarArgs
struct IntPair UIntPairVal
std::vector< GenericValue > AggregateVal