Go to the documentation of this file.
30 #define DEBUG_TYPE "interpreter"
32 STATISTIC(NumDynamicInsts,
"Number of dynamic instructions executed");
35 cl::desc(
"make the interpreter print every volatile load and store"));
64 Type *Ty =
I.getOperand(0)->getType();
70 R.AggregateVal.resize(Src.AggregateVal.size());
72 switch(
I.getOpcode()) {
76 case Instruction::FNeg:
77 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
78 for (
unsigned i = 0;
i < R.AggregateVal.size(); ++
i)
79 R.AggregateVal[
i].FloatVal = -Src.AggregateVal[
i].FloatVal;
80 }
else if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) {
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; \
114 dbgs() <<
"Unhandled type for FAdd instruction: " << *Ty <<
"\n";
125 dbgs() <<
"Unhandled type for FSub instruction: " << *Ty <<
"\n";
136 dbgs() <<
"Unhandled type for FMul instruction: " << *Ty <<
"\n";
147 dbgs() <<
"Unhandled type for FDiv instruction: " << *Ty <<
"\n";
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); \
200 dbgs() <<
"Unhandled type for ICMP_EQ predicate: " << *Ty <<
"\n";
214 dbgs() <<
"Unhandled type for ICMP_NE predicate: " << *Ty <<
"\n";
228 dbgs() <<
"Unhandled type for ICMP_ULT predicate: " << *Ty <<
"\n";
242 dbgs() <<
"Unhandled type for ICMP_SLT predicate: " << *Ty <<
"\n";
256 dbgs() <<
"Unhandled type for ICMP_UGT predicate: " << *Ty <<
"\n";
270 dbgs() <<
"Unhandled type for ICMP_SGT predicate: " << *Ty <<
"\n";
284 dbgs() <<
"Unhandled type for ICMP_ULE predicate: " << *Ty <<
"\n";
298 dbgs() <<
"Unhandled type for ICMP_SLE predicate: " << *Ty <<
"\n";
312 dbgs() <<
"Unhandled type for ICMP_UGE predicate: " << *Ty <<
"\n";
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); \
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) \
444 dbgs() <<
"Unhandled type for FCmp NE instruction: " << *Ty <<
"\n";
464 dbgs() <<
"Unhandled type for FCmp LE instruction: " << *Ty <<
"\n";
478 dbgs() <<
"Unhandled type for FCmp GE instruction: " << *Ty <<
"\n";
492 dbgs() <<
"Unhandled type for FCmp LT instruction: " << *Ty <<
"\n";
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); \
594 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
625 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
667 Type *Ty =
I.getOperand(0)->getType();
672 switch (
I.getPredicate()) {
674 dbgs() <<
"Don't know how to handle this FCmp predicate!\n-->" <<
I;
731 dbgs() <<
"Unhandled Cmp predicate\n";
738 Type *Ty =
I.getOperand(0)->getType();
749 #define INTEGER_VECTOR_OPERATION(OP) \
750 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
751 R.AggregateVal[i].IntVal = \
752 Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
756 #define INTEGER_VECTOR_FUNCTION(OP) \
757 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
758 R.AggregateVal[i].IntVal = \
759 Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
763 #define FLOAT_VECTOR_FUNCTION(OP, TY) \
764 for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
765 R.AggregateVal[i].TY = \
766 Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
770 #define FLOAT_VECTOR_OP(OP) { \
771 if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
772 FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
774 if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
775 FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
777 dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
778 llvm_unreachable(0); \
783 switch(
I.getOpcode()){
785 dbgs() <<
"Don't know how to handle this binary operator!\n-->" <<
I;
802 case Instruction::FRem:
803 if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
804 for (
unsigned i = 0;
i < R.AggregateVal.size(); ++
i)
805 R.AggregateVal[
i].FloatVal =
808 if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
809 for (
unsigned i = 0;
i < R.AggregateVal.size(); ++
i)
810 R.AggregateVal[
i].DoubleVal =
813 dbgs() <<
"Unhandled type for Rem instruction: " << *Ty <<
"\n";
820 switch (
I.getOpcode()) {
822 dbgs() <<
"Don't know how to handle this binary operator!\n-->" <<
I;
826 case Instruction::Sub: R.IntVal = Src1.
IntVal - Src2.
IntVal;
break;
837 case Instruction::And: R.IntVal = Src1.
IntVal & Src2.
IntVal;
break;
838 case Instruction::Or: R.IntVal = Src1.
IntVal | Src2.
IntVal;
break;
839 case Instruction::Xor: R.IntVal = Src1.
IntVal ^ Src2.
IntVal;
break;
856 Dest = (Src1.
IntVal == 0) ? Src3 : Src2;
863 Type * Ty =
I.getOperand(0)->getType();
892 void Interpreter::popStackAndReturnValueToCaller(
Type *RetTy,
897 if (ECStack.empty()) {
912 SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
913 CallingSF.
Caller =
nullptr;
924 if (
I.getNumOperands()) {
925 RetTy =
I.getReturnValue()->getType();
926 Result = getOperandValue(
I.getReturnValue(), SF);
929 popStackAndReturnValueToCaller(RetTy, Result);
940 Dest =
I.getSuccessor(0);
941 if (!
I.isUnconditional()) {
944 Dest =
I.getSuccessor(1);
946 SwitchToNewBasicBlock(Dest, SF);
957 for (
auto Case :
I.cases()) {
958 GenericValue CaseVal = getOperandValue(Case.getCaseValue(), SF);
960 Dest = cast<BasicBlock>(Case.getCaseSuccessor());
964 if (!Dest) Dest =
I.getDefaultDest();
965 SwitchToNewBasicBlock(Dest, SF);
970 void *Dest =
GVTOP(getOperandValue(
I.getAddress(), SF));
990 if (!isa<PHINode>(SF.
CurInst))
return;
993 std::vector<GenericValue> ResultValues;
998 assert(
i != -1 &&
"PHINode doesn't contain entry for predecessor??");
1002 ResultValues.push_back(getOperandValue(IncomingValue, SF));
1020 Type *Ty =
I.getAllocatedType();
1023 unsigned NumElements =
1035 <<
" bytes) x " << NumElements <<
" (Total: " << MemToAlloc
1036 <<
") at " << uintptr_t(
Memory) <<
'\n');
1039 assert(Result.PointerVal &&
"Null pointer returned by malloc!");
1042 if (
I.getOpcode() == Instruction::Alloca)
1043 ECStack.back().Allocas.add(
Memory);
1052 "Cannot getElementOffset of a nonpointer type!");
1056 for (;
I !=
E; ++
I) {
1060 const ConstantInt *CPU = cast<ConstantInt>(
I.getOperand());
1070 cast<IntegerType>(
I.getOperand()->getType())->getBitWidth();
1074 assert(
BitWidth == 64 &&
"Invalid index type for getelementptr");
1089 SetValue(&
I, executeGEPOperation(
I.getPointerOperand(),
1095 GenericValue SRC = getOperandValue(
I.getPointerOperand(), SF);
1101 dbgs() <<
"Volatile load " <<
I;
1107 GenericValue SRC = getOperandValue(
I.getPointerOperand(), SF);
1109 I.getOperand(0)->getType());
1111 dbgs() <<
"Volatile store: " <<
I;
1132 SetValue(&
I, getOperandValue(*
I.arg_begin(), SF), SF);
1143 bool atBegin(Parent->
begin() == Me);
1162 std::vector<GenericValue> ArgVals;
1164 ArgVals.reserve(NumArgs);
1166 ArgVals.push_back(getOperandValue(V, SF));
1178 if (orgShiftAmount < (
uint64_t)valueWidth)
1179 return orgShiftAmount;
1182 return (
NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
1191 Type *Ty =
I.getType();
1196 for (
unsigned i = 0;
i < src1Size;
i++) {
1218 Type *Ty =
I.getType();
1223 for (
unsigned i = 0;
i < src1Size;
i++) {
1245 Type *Ty =
I.getType();
1250 for (
unsigned i = 0;
i < src1Size;
i++) {
1273 unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1274 unsigned NumElts = Src.AggregateVal.size();
1277 for (
unsigned i = 0;
i < NumElts;
i++)
1278 Dest.
AggregateVal[
i].IntVal = Src.AggregateVal[
i].IntVal.trunc(DBitWidth);
1282 Dest.
IntVal = Src.IntVal.trunc(DBitWidth);
1293 unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1294 unsigned size = Src.AggregateVal.size();
1297 for (
unsigned i = 0;
i <
size;
i++)
1298 Dest.
AggregateVal[
i].IntVal = Src.AggregateVal[
i].IntVal.sext(DBitWidth);
1300 auto *DITy = cast<IntegerType>(DstTy);
1302 Dest.
IntVal = Src.IntVal.sext(DBitWidth);
1313 unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1315 unsigned size = Src.AggregateVal.size();
1318 for (
unsigned i = 0;
i <
size;
i++)
1319 Dest.
AggregateVal[
i].IntVal = Src.AggregateVal[
i].IntVal.zext(DBitWidth);
1321 auto *DITy = cast<IntegerType>(DstTy);
1323 Dest.
IntVal = Src.IntVal.zext(DBitWidth);
1332 if (isa<VectorType>(SrcVal->
getType())) {
1335 "Invalid FPTrunc instruction");
1337 unsigned size = Src.AggregateVal.size();
1340 for (
unsigned i = 0;
i <
size;
i++)
1341 Dest.
AggregateVal[
i].FloatVal = (
float)Src.AggregateVal[
i].DoubleVal;
1344 "Invalid FPTrunc instruction");
1345 Dest.
FloatVal = (float)Src.DoubleVal;
1355 if (isa<VectorType>(SrcVal->
getType())) {
1359 unsigned size = Src.AggregateVal.size();
1362 for (
unsigned i = 0;
i <
size;
i++)
1363 Dest.
AggregateVal[
i].DoubleVal = (
double)Src.AggregateVal[
i].FloatVal;
1366 "Invalid FPExt instruction");
1378 if (isa<VectorType>(SrcTy)) {
1381 uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
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);
1398 uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1416 if (isa<VectorType>(SrcTy)) {
1419 uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1420 unsigned size = Src.AggregateVal.size();
1426 for (
unsigned i = 0;
i <
size;
i++)
1428 Src.AggregateVal[
i].FloatVal, DBitWidth);
1430 for (
unsigned i = 0;
i <
size;
i++)
1432 Src.AggregateVal[
i].DoubleVal, DBitWidth);
1436 unsigned DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1452 if (isa<VectorType>(SrcVal->
getType())) {
1454 unsigned size = Src.AggregateVal.size();
1460 for (
unsigned i = 0;
i <
size;
i++)
1464 for (
unsigned i = 0;
i <
size;
i++)
1484 if (isa<VectorType>(SrcVal->
getType())) {
1486 unsigned size = Src.AggregateVal.size();
1492 for (
unsigned i = 0;
i <
size;
i++)
1496 for (
unsigned i = 0;
i <
size;
i++)
1516 uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1530 if (PtrSize != Src.IntVal.getBitWidth())
1531 Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
1545 if (isa<VectorType>(SrcTy) || isa<VectorType>(DstTy)) {
1552 unsigned SrcBitSize;
1553 unsigned DstBitSize;
1557 if (isa<VectorType>(SrcTy)) {
1560 SrcNum = Src.AggregateVal.size();
1570 if (isa<VectorType>(DstTy)) {
1573 DstNum = (SrcNum * SrcBitSize) / DstBitSize;
1580 if (SrcNum * SrcBitSize != DstNum * DstBitSize)
1586 for (
unsigned i = 0;
i < SrcNum;
i++)
1591 for (
unsigned i = 0;
i < SrcNum;
i++)
1595 for (
unsigned i = 0;
i < SrcNum;
i++)
1603 if (DstNum < SrcNum) {
1605 unsigned Ratio = SrcNum / DstNum;
1606 unsigned SrcElt = 0;
1607 for (
unsigned i = 0;
i < DstNum;
i++) {
1611 unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
1612 for (
unsigned j = 0;
j < Ratio;
j++) {
1614 Tmp = Tmp.
zext(SrcBitSize);
1616 Tmp = Tmp.
zext(DstBitSize);
1618 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
1625 unsigned Ratio = DstNum / SrcNum;
1626 for (
unsigned i = 0;
i < SrcNum;
i++) {
1627 unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
1628 for (
unsigned j = 0;
j < Ratio;
j++) {
1634 if (DstBitSize < SrcBitSize)
1636 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
1643 if (isa<VectorType>(DstTy)) {
1646 for (
unsigned i = 0;
i < DstNum;
i++)
1651 for (
unsigned i = 0;
i < DstNum;
i++)
1678 Dest.
IntVal = Src.IntVal;
1684 Dest.
FloatVal = Src.IntVal.bitsToFloat();
1690 Dest.
DoubleVal = Src.IntVal.bitsToDouble();
1704 SetValue(&
I, executeTruncInst(
I.getOperand(0),
I.getType(), SF), SF);
1709 SetValue(&
I, executeSExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1714 SetValue(&
I, executeZExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1719 SetValue(&
I, executeFPTruncInst(
I.getOperand(0),
I.getType(), SF), SF);
1724 SetValue(&
I, executeFPExtInst(
I.getOperand(0),
I.getType(), SF), SF);
1729 SetValue(&
I, executeUIToFPInst(
I.getOperand(0),
I.getType(), SF), SF);
1734 SetValue(&
I, executeSIToFPInst(
I.getOperand(0),
I.getType(), SF), SF);
1739 SetValue(&
I, executeFPToUIInst(
I.getOperand(0),
I.getType(), SF), SF);
1744 SetValue(&
I, executeFPToSIInst(
I.getOperand(0),
I.getType(), SF), SF);
1749 SetValue(&
I, executePtrToIntInst(
I.getOperand(0),
I.getType(), SF), SF);
1754 SetValue(&
I, executeIntToPtrInst(
I.getOperand(0),
I.getType(), SF), SF);
1759 SetValue(&
I, executeBitCastInst(
I.getOperand(0),
I.getType(), SF), SF);
1762 #define IMPLEMENT_VAARG(TY) \
1763 case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
1774 Type *Ty =
I.getType();
1777 Dest.
IntVal = Src.IntVal;
1783 dbgs() <<
"Unhandled dest type for vaarg instruction: " << *Ty <<
"\n";
1800 Type *Ty =
I.getType();
1806 dbgs() <<
"Unhandled destination type for extractelement instruction: "
1821 dbgs() <<
"Invalid index in extractelement instruction\n";
1873 unsigned src1Size = (unsigned)Src1.
AggregateVal.size();
1874 unsigned src2Size = (unsigned)Src2.
AggregateVal.size();
1875 unsigned src3Size =
I.getShuffleMask().size();
1884 for(
unsigned i=0;
i<src3Size;
i++) {
1888 else if(
j < src1Size + src2Size)
1900 for(
unsigned i=0;
i<src3Size;
i++) {
1904 else if(
j < src1Size + src2Size)
1911 for(
unsigned i=0;
i<src3Size;
i++) {
1915 else if(
j < src1Size + src2Size)
1928 Value *Agg =
I.getAggregateOperand();
1933 unsigned Num =
I.getNumIndices();
1936 for (
unsigned i = 0 ;
i < Num; ++
i) {
1972 Value *Agg =
I.getAggregateOperand();
1979 unsigned Num =
I.getNumIndices();
1982 for (
unsigned i = 0 ;
i < Num; ++
i) {
2019 switch (CE->getOpcode()) {
2020 case Instruction::Trunc:
2021 return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
2022 case Instruction::ZExt:
2023 return executeZExtInst(CE->getOperand(0), CE->getType(), SF);
2024 case Instruction::SExt:
2025 return executeSExtInst(CE->getOperand(0), CE->getType(), SF);
2026 case Instruction::FPTrunc:
2027 return executeFPTruncInst(CE->getOperand(0), CE->getType(), SF);
2028 case Instruction::FPExt:
2029 return executeFPExtInst(CE->getOperand(0), CE->getType(), SF);
2030 case Instruction::UIToFP:
2031 return executeUIToFPInst(CE->getOperand(0), CE->getType(), SF);
2032 case Instruction::SIToFP:
2033 return executeSIToFPInst(CE->getOperand(0), CE->getType(), SF);
2034 case Instruction::FPToUI:
2035 return executeFPToUIInst(CE->getOperand(0), CE->getType(), SF);
2036 case Instruction::FPToSI:
2037 return executeFPToSIInst(CE->getOperand(0), CE->getType(), SF);
2038 case Instruction::PtrToInt:
2039 return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
2040 case Instruction::IntToPtr:
2041 return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
2042 case Instruction::BitCast:
2043 return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
2044 case Instruction::GetElementPtr:
2045 return executeGEPOperation(CE->getOperand(0),
gep_type_begin(CE),
2047 case Instruction::FCmp:
2048 case Instruction::ICmp:
2050 getOperandValue(CE->getOperand(0), SF),
2051 getOperandValue(CE->getOperand(1), SF),
2052 CE->getOperand(0)->getType());
2055 getOperandValue(CE->getOperand(1), SF),
2056 getOperandValue(CE->getOperand(2), SF),
2057 CE->getOperand(0)->getType());
2064 GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
2065 GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
2067 Type * Ty = CE->getOperand(0)->getType();
2068 switch (CE->getOpcode()) {
2084 case Instruction::Shl:
2087 case Instruction::LShr:
2090 case Instruction::AShr:
2094 dbgs() <<
"Unhandled ConstantExpr: " << *CE <<
"\n";
2102 return getConstantExprValue(CE, SF);
2103 }
else if (
Constant *CPV = dyn_cast<Constant>(V)) {
2105 }
else if (
GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
2120 assert((ECStack.empty() || !ECStack.back().Caller ||
2121 ECStack.back().Caller->arg_size() == ArgVals.
size()) &&
2122 "Incorrect number of arguments passed into function call!");
2124 ECStack.emplace_back();
2129 if (
F->isDeclaration()) {
2132 popStackAndReturnValueToCaller (
F->getReturnType (), Result);
2137 StackFrame.
CurBB = &
F->front();
2142 (ArgVals.
size() >
F->arg_size() &&
F->getFunctionType()->isVarArg()))&&
2143 "Invalid number of values passed to function invocation!");
2157 while (!ECStack.empty()) {
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
This class represents an incoming formal argument to a Function.
void visitUnreachableInst(UnreachableInst &I)
@ FloatTyID
32-bit floating point type
void visitCallBase(CallBase &I)
#define IMPLEMENT_INTEGER_ICMP(OP, TY)
@ DoubleTyID
64-bit floating point type
This is an optimization pass for GlobalISel generic memory operations.
std::vector< GenericValue > AggregateVal
Return a value (possibly void), from a function.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
void visitFPExtInst(FPExtInst &I)
InstListType::iterator iterator
Instruction iterators...
bool isPointerTy() const
True if this is an instance of PointerType.
static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2, Type *Ty)
void visitVAEndInst(VAEndInst &I)
float RoundSignedAPIntToFloat(const APInt &APIVal)
Converts the given APInt to a float value.
struct IntPair UIntPairVal
void visitLoadInst(LoadInst &I)
#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC)
void visitShl(BinaryOperator &I)
This class represents a no-op cast from one type to another.
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
void visitInsertElementInst(InsertElementInst &I)
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
void visitReturnInst(ReturnInst &I)
static cl::opt< bool > PrintVolatile("interpreter-print-volatile", cl::Hidden, cl::desc("make the interpreter print every volatile load and store"))
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
TypeID getTypeID() const
Return the type id for the type.
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
void runAtExitHandlers()
runAtExitHandlers - Run any functions registered by the program's calls to atexit(3),...
static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2, Type *Ty)
@ ICMP_SGT
signed greater than
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getBitWidth() const
Return the number of bits in the APInt.
void visitBranchInst(BranchInst &I)
void visitUnaryOperator(UnaryOperator &I)
void callFunction(Function *F, ArrayRef< GenericValue > ArgVals)
static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2, Type *Ty, const bool val)
void visitFPTruncInst(FPTruncInst &I)
Type * getElementType() const
@ ICMP_SLE
signed less or equal
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
void visitICmpInst(ICmpInst &I)
gep_type_iterator gep_type_begin(const User *GEP)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
#define INTEGER_VECTOR_FUNCTION(OP)
void visitVAArgInst(VAArgInst &I)
void visitStoreInst(StoreInst &I)
static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, GenericValue Src3, Type *Ty)
LLVM Basic Block Representation.
gep_type_iterator gep_type_end(const User *GEP)
This represents the llvm.va_start intrinsic.
@ FCMP_ULT
1 1 0 0 True if unordered or less than
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, Type *Ty)
StoreValueToMemory - Stores the data in Val of type Ty at address Ptr.
void visitSIToFPInst(SIToFPInst &I)
static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2, Type *Ty)
std::map< Value *, GenericValue > Values
void exitCalled(GenericValue GV)
void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, Type *Ty)
FIXME: document.
void visitZExtInst(ZExtInst &I)
This is the shared class of boolean and integer constants.
void visitIntrinsicInst(IntrinsicInst &I)
static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2, Type *Ty)
void visitIndirectBrInst(IndirectBrInst &I)
static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2, Type *Ty)
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2, Type *Ty)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
#define IMPLEMENT_VECTOR_FCMP(OP)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
@ ICMP_ULE
unsigned less or equal
void visitAllocaInst(AllocaInst &I)
static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2, Type *Ty)
iterator begin()
Instruction iterator methods.
This instruction compares its operands according to the predicate given to the constructor.
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
#define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY)
#define IMPLEMENT_BINARY_OPERATOR(OP, TY)
bool isVectorTy() const
True if this is an instance of VectorType.
This instruction inserts a single (scalar) element into a VectorType value.
void * GVTOP(const GenericValue &GV)
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2, Type *Ty)
Class to represent integer types.
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static void executeFRemInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2, Type *Ty)
static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2, Type *Ty)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
uint64_t getZExtValue() const
Get zero extended value.
STATISTIC(NumFunctions, "Total number of functions")
void visitTruncInst(TruncInst &I)
GenericValue getConstantValue(const Constant *C)
Converts a Constant* into a GenericValue, including handling of ConstantExpr values.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
void visitBitCastInst(BitCastInst &I)
static void executeFDivInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
#define FLOAT_VECTOR_OP(OP)
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
const DataLayout & getDataLayout() const
bool isIntegerTy() const
True if this is an instance of IntegerType.
Base class of all SIMD vector types.
static void executeFSubInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 the input will be treated as an leaving the upper bits uninitialised For i64 store i32 val
static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2, Type *Ty)
#define IMPLEMENT_UNORDERED(TY, X, Y)
An instruction for storing to memory.
static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2, Type *Ty)
This is an important base class in LLVM.
This instruction compares its operands according to the predicate given to the constructor.
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
void visitVAStartInst(VAStartInst &I)
This class represents a cast from floating point to signed integer.
static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, Type *Ty)
This class represents a truncation of integer types.
static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2, Type *Ty)
bool isLittleEndian() const
Layout endianness...
#define MASK_VECTOR_NANS(TY, X, Y, FLAG)
APInt RoundFloatToAPInt(float Float, unsigned width)
Converts a float value into a APInt.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
float RoundAPIntToFloat(const APInt &APIVal)
Converts the given APInt to a float value.
void visit(Iterator Start, Iterator End)
void visitVACopyInst(VACopyInst &I)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void visitInsertValueInst(InsertValueInst &I)
void visitExtractElementInst(ExtractElementInst &I)
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2, Type *Ty)
This class represents the LLVM 'select' instruction.
bool isVoidTy() const
Return true if this is 'void'.
This class represents a cast from floating point to unsigned integer.
void visitPtrToIntInst(PtrToIntInst &I)
#define IMPLEMENT_SCALAR_NANS(TY, X, Y)
void visitFCmpInst(FCmpInst &I)
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
This class represents zero extension of integer types.
Class for arbitrary precision integers.
double RoundSignedAPIntToDouble(const APInt &APIVal)
Converts the given APInt to a double value.
void visitFPToUIInst(FPToUIInst &I)
@ ICMP_SLT
signed less than
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.
void * getPointerToGlobal(const GlobalValue *GV)
getPointerToGlobal - This returns the address of the specified global value.
static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2, Type *Ty)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This represents the llvm.va_end intrinsic.
BasicBlock::iterator CurInst
This class provides various memory handling functions that manipulate MemoryBlock instances.
Class to represent struct types.
SmallVector< MachineOperand, 4 > Cond
static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2, Type *Ty)
@ ICMP_ULT
unsigned less than
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
std::vector< GenericValue > VarArgs
static void executeFAddInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
void visitLShr(BinaryOperator &I)
void visitSExtInst(SExtInst &I)
This class represents a cast from a pointer to an integer.
void visitSwitchInst(SwitchInst &I)
This class represents an extension of floating point types.
static APInt doubleToBits(double V)
Converts a double to APInt bits.
#define IMPLEMENT_VAARG(TY)
This class represents a sign extension of integer types.
double RoundAPIntToDouble(const APInt &APIVal)
Converts the given APInt to a double value.
An instruction for reading from memory.
static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2, Type *Ty)
APInt udiv(const APInt &RHS) const
Unsigned division operation.
void visitUIToFPInst(UIToFPInst &I)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
APInt zext(unsigned width) const
Zero extend to a new width.
@ IntegerTyID
Arbitrary bit width integers.
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
A constant value that is initialized with an expression using other constant values.
static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2, Type *Ty)
APInt trunc(unsigned width) const
Truncate to new width.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
uint64_t getElementOffset(unsigned Idx) const
This represents the llvm.va_copy intrinsic.
@ FixedVectorTyID
Fixed width SIMD vector type.
unsigned arg_size() const
#define INTEGER_VECTOR_OPERATION(OP)
constexpr unsigned BitWidth
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static void executeFMulInst(GenericValue &Dest, GenericValue Src1, GenericValue Src2, Type *Ty)
#define IMPLEMENT_POINTER_ICMP(OP)
void visitBinaryOperator(BinaryOperator &I)
static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2, Type *Ty)
This class represents a cast unsigned integer to floating point.
static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2, Type *Ty)
@ ICMP_SGE
signed greater or equal
APInt RoundDoubleToAPInt(double Double, unsigned width)
Converts the given double value into a APInt.
Value * getCalledOperand() const
void visitFPToSIInst(FPToSIInst &I)
This class represents a cast from an integer to a pointer.
Indirect Branch Instruction.
A wrapper class for inspecting calls to intrinsic functions.
void visitShuffleVectorInst(ShuffleVectorInst &I)
void visitAShr(BinaryOperator &I)
static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2, Type *Ty)
static Type * getVoidTy(LLVMContext &C)
void visitSelectInst(SelectInst &I)
This instruction constructs a fixed permutation of two input vectors.
GenericValue PTOGV(void *P)
static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1, GenericValue Src2, Type *Ty)
This class represents a cast from signed integer to floating point.
declare void exit(i32) noreturn nounwind This compiles into
@ ICMP_UGT
unsigned greater than
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
This class represents a truncation of floating point types.
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF)
size_t size() const
size - Get the array size.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
GenericValue callExternalFunction(Function *F, ArrayRef< GenericValue > ArgVals)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
@ ScalableVectorTyID
Scalable SIMD vector type.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
This function has undefined behavior.
void visitGetElementPtrInst(GetElementPtrInst &I)
static void executeFNegInst(GenericValue &Dest, GenericValue Src, Type *Ty)
an instruction to allocate memory on the stack
APInt shl(unsigned shiftAmt) const
Left-shift function.
#define IMPLEMENT_FCMP(OP, TY)
Conditional or Unconditional Branch instruction.
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
void visitIntToPtrInst(IntToPtrInst &I)
This instruction inserts a struct field of array element value into an aggregate value.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
void visitExtractValueInst(ExtractValueInst &I)
LLVM Value Representation.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2, Type *Ty)
static APInt floatToBits(float V)
Converts a float to APInt bits.
static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2, Type *Ty)
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
static unsigned getShiftAmount(uint64_t orgShiftAmount, llvm::APInt valueToShift)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...