xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- Execution.cpp - Implement code to simulate the program ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file contains the actual instruction interpreter.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "Interpreter.h"
140b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
150b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/IntrinsicLowering.h"
170b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
180b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
190b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
200b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
210b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
220b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
240b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric #include <algorithm>
270b57cec5SDimitry Andric #include <cmath>
280b57cec5SDimitry Andric using namespace llvm;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric #define DEBUG_TYPE "interpreter"
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
350b57cec5SDimitry Andric           cl::desc("make the interpreter print every volatile load and store"));
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
380b57cec5SDimitry Andric //                     Various Helper Functions
390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
400b57cec5SDimitry Andric 
SetValue(Value * V,GenericValue Val,ExecutionContext & SF)410b57cec5SDimitry Andric static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
420b57cec5SDimitry Andric   SF.Values[V] = Val;
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
460b57cec5SDimitry Andric //                    Unary Instruction Implementations
470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
480b57cec5SDimitry Andric 
executeFNegInst(GenericValue & Dest,GenericValue Src,Type * Ty)490b57cec5SDimitry Andric static void executeFNegInst(GenericValue &Dest, GenericValue Src, Type *Ty) {
500b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
510b57cec5SDimitry Andric   case Type::FloatTyID:
520b57cec5SDimitry Andric     Dest.FloatVal = -Src.FloatVal;
530b57cec5SDimitry Andric     break;
540b57cec5SDimitry Andric   case Type::DoubleTyID:
550b57cec5SDimitry Andric     Dest.DoubleVal = -Src.DoubleVal;
560b57cec5SDimitry Andric     break;
570b57cec5SDimitry Andric   default:
580b57cec5SDimitry Andric     llvm_unreachable("Unhandled type for FNeg instruction");
590b57cec5SDimitry Andric   }
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric 
visitUnaryOperator(UnaryOperator & I)620b57cec5SDimitry Andric void Interpreter::visitUnaryOperator(UnaryOperator &I) {
630b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
640b57cec5SDimitry Andric   Type *Ty = I.getOperand(0)->getType();
650b57cec5SDimitry Andric   GenericValue Src = getOperandValue(I.getOperand(0), SF);
660b57cec5SDimitry Andric   GenericValue R; // Result
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   // First process vector operation
690b57cec5SDimitry Andric   if (Ty->isVectorTy()) {
700b57cec5SDimitry Andric     R.AggregateVal.resize(Src.AggregateVal.size());
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric     switch(I.getOpcode()) {
730b57cec5SDimitry Andric     default:
740b57cec5SDimitry Andric       llvm_unreachable("Don't know how to handle this unary operator");
750b57cec5SDimitry Andric       break;
760b57cec5SDimitry Andric     case Instruction::FNeg:
770b57cec5SDimitry Andric       if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
780b57cec5SDimitry Andric         for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
790b57cec5SDimitry Andric           R.AggregateVal[i].FloatVal = -Src.AggregateVal[i].FloatVal;
800b57cec5SDimitry Andric       } else if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) {
810b57cec5SDimitry Andric         for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
820b57cec5SDimitry Andric           R.AggregateVal[i].DoubleVal = -Src.AggregateVal[i].DoubleVal;
830b57cec5SDimitry Andric       } else {
840b57cec5SDimitry Andric         llvm_unreachable("Unhandled type for FNeg instruction");
850b57cec5SDimitry Andric       }
860b57cec5SDimitry Andric       break;
870b57cec5SDimitry Andric     }
880b57cec5SDimitry Andric   } else {
890b57cec5SDimitry Andric     switch (I.getOpcode()) {
900b57cec5SDimitry Andric     default:
910b57cec5SDimitry Andric       llvm_unreachable("Don't know how to handle this unary operator");
920b57cec5SDimitry Andric       break;
930b57cec5SDimitry Andric     case Instruction::FNeg: executeFNegInst(R, Src, Ty); break;
940b57cec5SDimitry Andric     }
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric   SetValue(&I, R, SF);
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1000b57cec5SDimitry Andric //                    Binary Instruction Implementations
1010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
1040b57cec5SDimitry Andric    case Type::TY##TyID: \
1050b57cec5SDimitry Andric      Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
1060b57cec5SDimitry Andric      break
1070b57cec5SDimitry Andric 
executeFAddInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1080b57cec5SDimitry Andric static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
1090b57cec5SDimitry Andric                             GenericValue Src2, Type *Ty) {
1100b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1110b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(+, Float);
1120b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(+, Double);
1130b57cec5SDimitry Andric   default:
1140b57cec5SDimitry Andric     dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
1150b57cec5SDimitry Andric     llvm_unreachable(nullptr);
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
executeFSubInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1190b57cec5SDimitry Andric static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
1200b57cec5SDimitry Andric                             GenericValue Src2, Type *Ty) {
1210b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1220b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(-, Float);
1230b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(-, Double);
1240b57cec5SDimitry Andric   default:
1250b57cec5SDimitry Andric     dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
1260b57cec5SDimitry Andric     llvm_unreachable(nullptr);
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
executeFMulInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1300b57cec5SDimitry Andric static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
1310b57cec5SDimitry Andric                             GenericValue Src2, Type *Ty) {
1320b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1330b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(*, Float);
1340b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(*, Double);
1350b57cec5SDimitry Andric   default:
1360b57cec5SDimitry Andric     dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
1370b57cec5SDimitry Andric     llvm_unreachable(nullptr);
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric }
1400b57cec5SDimitry Andric 
executeFDivInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1410b57cec5SDimitry Andric static void executeFDivInst(GenericValue &Dest, GenericValue Src1,
1420b57cec5SDimitry Andric                             GenericValue Src2, Type *Ty) {
1430b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1440b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(/, Float);
1450b57cec5SDimitry Andric     IMPLEMENT_BINARY_OPERATOR(/, Double);
1460b57cec5SDimitry Andric   default:
1470b57cec5SDimitry Andric     dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
1480b57cec5SDimitry Andric     llvm_unreachable(nullptr);
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
executeFRemInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1520b57cec5SDimitry Andric static void executeFRemInst(GenericValue &Dest, GenericValue Src1,
1530b57cec5SDimitry Andric                             GenericValue Src2, Type *Ty) {
1540b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1550b57cec5SDimitry Andric   case Type::FloatTyID:
1560b57cec5SDimitry Andric     Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal);
1570b57cec5SDimitry Andric     break;
1580b57cec5SDimitry Andric   case Type::DoubleTyID:
1590b57cec5SDimitry Andric     Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal);
1600b57cec5SDimitry Andric     break;
1610b57cec5SDimitry Andric   default:
1620b57cec5SDimitry Andric     dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
1630b57cec5SDimitry Andric     llvm_unreachable(nullptr);
1640b57cec5SDimitry Andric   }
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric #define IMPLEMENT_INTEGER_ICMP(OP, TY) \
1680b57cec5SDimitry Andric    case Type::IntegerTyID:  \
1690b57cec5SDimitry Andric       Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \
1700b57cec5SDimitry Andric       break;
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric #define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY)                                  \
1735ffd83dbSDimitry Andric   case Type::FixedVectorTyID:                                                  \
1745ffd83dbSDimitry Andric   case Type::ScalableVectorTyID: {                                             \
1750b57cec5SDimitry Andric     assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());              \
1760b57cec5SDimitry Andric     Dest.AggregateVal.resize(Src1.AggregateVal.size());                        \
1770b57cec5SDimitry Andric     for (uint32_t _i = 0; _i < Src1.AggregateVal.size(); _i++)                 \
1785ffd83dbSDimitry Andric       Dest.AggregateVal[_i].IntVal = APInt(                                    \
1795ffd83dbSDimitry Andric           1, Src1.AggregateVal[_i].IntVal.OP(Src2.AggregateVal[_i].IntVal));   \
1800b57cec5SDimitry Andric   } break;
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric // Handle pointers specially because they must be compared with only as much
1830b57cec5SDimitry Andric // width as the host has.  We _do not_ want to be comparing 64 bit values when
1840b57cec5SDimitry Andric // running on a 32-bit target, otherwise the upper 32 bits might mess up
1850b57cec5SDimitry Andric // comparisons if they contain garbage.
1860b57cec5SDimitry Andric #define IMPLEMENT_POINTER_ICMP(OP) \
1870b57cec5SDimitry Andric    case Type::PointerTyID: \
1880b57cec5SDimitry Andric       Dest.IntVal = APInt(1,(void*)(intptr_t)Src1.PointerVal OP \
1890b57cec5SDimitry Andric                             (void*)(intptr_t)Src2.PointerVal); \
1900b57cec5SDimitry Andric       break;
1910b57cec5SDimitry Andric 
executeICMP_EQ(GenericValue Src1,GenericValue Src2,Type * Ty)1920b57cec5SDimitry Andric static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
1930b57cec5SDimitry Andric                                    Type *Ty) {
1940b57cec5SDimitry Andric   GenericValue Dest;
1950b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
1960b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(eq,Ty);
1970b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(eq,Ty);
1980b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(==);
1990b57cec5SDimitry Andric   default:
2000b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
2010b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2020b57cec5SDimitry Andric   }
2030b57cec5SDimitry Andric   return Dest;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
executeICMP_NE(GenericValue Src1,GenericValue Src2,Type * Ty)2060b57cec5SDimitry Andric static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
2070b57cec5SDimitry Andric                                    Type *Ty) {
2080b57cec5SDimitry Andric   GenericValue Dest;
2090b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2100b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(ne,Ty);
2110b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(ne,Ty);
2120b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(!=);
2130b57cec5SDimitry Andric   default:
2140b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
2150b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2160b57cec5SDimitry Andric   }
2170b57cec5SDimitry Andric   return Dest;
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
executeICMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)2200b57cec5SDimitry Andric static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
2210b57cec5SDimitry Andric                                     Type *Ty) {
2220b57cec5SDimitry Andric   GenericValue Dest;
2230b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2240b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(ult,Ty);
2250b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(ult,Ty);
2260b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(<);
2270b57cec5SDimitry Andric   default:
2280b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
2290b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric   return Dest;
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
executeICMP_SLT(GenericValue Src1,GenericValue Src2,Type * Ty)2340b57cec5SDimitry Andric static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
2350b57cec5SDimitry Andric                                     Type *Ty) {
2360b57cec5SDimitry Andric   GenericValue Dest;
2370b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2380b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(slt,Ty);
2390b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(slt,Ty);
2400b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(<);
2410b57cec5SDimitry Andric   default:
2420b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
2430b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2440b57cec5SDimitry Andric   }
2450b57cec5SDimitry Andric   return Dest;
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
executeICMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)2480b57cec5SDimitry Andric static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
2490b57cec5SDimitry Andric                                     Type *Ty) {
2500b57cec5SDimitry Andric   GenericValue Dest;
2510b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2520b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(ugt,Ty);
2530b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(ugt,Ty);
2540b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(>);
2550b57cec5SDimitry Andric   default:
2560b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
2570b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric   return Dest;
2600b57cec5SDimitry Andric }
2610b57cec5SDimitry Andric 
executeICMP_SGT(GenericValue Src1,GenericValue Src2,Type * Ty)2620b57cec5SDimitry Andric static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
2630b57cec5SDimitry Andric                                     Type *Ty) {
2640b57cec5SDimitry Andric   GenericValue Dest;
2650b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2660b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(sgt,Ty);
2670b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(sgt,Ty);
2680b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(>);
2690b57cec5SDimitry Andric   default:
2700b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
2710b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2720b57cec5SDimitry Andric   }
2730b57cec5SDimitry Andric   return Dest;
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric 
executeICMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)2760b57cec5SDimitry Andric static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
2770b57cec5SDimitry Andric                                     Type *Ty) {
2780b57cec5SDimitry Andric   GenericValue Dest;
2790b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2800b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(ule,Ty);
2810b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(ule,Ty);
2820b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(<=);
2830b57cec5SDimitry Andric   default:
2840b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
2850b57cec5SDimitry Andric     llvm_unreachable(nullptr);
2860b57cec5SDimitry Andric   }
2870b57cec5SDimitry Andric   return Dest;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
executeICMP_SLE(GenericValue Src1,GenericValue Src2,Type * Ty)2900b57cec5SDimitry Andric static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
2910b57cec5SDimitry Andric                                     Type *Ty) {
2920b57cec5SDimitry Andric   GenericValue Dest;
2930b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
2940b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(sle,Ty);
2950b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(sle,Ty);
2960b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(<=);
2970b57cec5SDimitry Andric   default:
2980b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
2990b57cec5SDimitry Andric     llvm_unreachable(nullptr);
3000b57cec5SDimitry Andric   }
3010b57cec5SDimitry Andric   return Dest;
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
executeICMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)3040b57cec5SDimitry Andric static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
3050b57cec5SDimitry Andric                                     Type *Ty) {
3060b57cec5SDimitry Andric   GenericValue Dest;
3070b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
3080b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(uge,Ty);
3090b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(uge,Ty);
3100b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(>=);
3110b57cec5SDimitry Andric   default:
3120b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
3130b57cec5SDimitry Andric     llvm_unreachable(nullptr);
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric   return Dest;
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
executeICMP_SGE(GenericValue Src1,GenericValue Src2,Type * Ty)3180b57cec5SDimitry Andric static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
3190b57cec5SDimitry Andric                                     Type *Ty) {
3200b57cec5SDimitry Andric   GenericValue Dest;
3210b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
3220b57cec5SDimitry Andric     IMPLEMENT_INTEGER_ICMP(sge,Ty);
3230b57cec5SDimitry Andric     IMPLEMENT_VECTOR_INTEGER_ICMP(sge,Ty);
3240b57cec5SDimitry Andric     IMPLEMENT_POINTER_ICMP(>=);
3250b57cec5SDimitry Andric   default:
3260b57cec5SDimitry Andric     dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
3270b57cec5SDimitry Andric     llvm_unreachable(nullptr);
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric   return Dest;
3300b57cec5SDimitry Andric }
3310b57cec5SDimitry Andric 
visitICmpInst(ICmpInst & I)3320b57cec5SDimitry Andric void Interpreter::visitICmpInst(ICmpInst &I) {
3330b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
3340b57cec5SDimitry Andric   Type *Ty    = I.getOperand(0)->getType();
3350b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
3360b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
3370b57cec5SDimitry Andric   GenericValue R;   // Result
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   switch (I.getPredicate()) {
3400b57cec5SDimitry Andric   case ICmpInst::ICMP_EQ:  R = executeICMP_EQ(Src1,  Src2, Ty); break;
3410b57cec5SDimitry Andric   case ICmpInst::ICMP_NE:  R = executeICMP_NE(Src1,  Src2, Ty); break;
3420b57cec5SDimitry Andric   case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
3430b57cec5SDimitry Andric   case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
3440b57cec5SDimitry Andric   case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
3450b57cec5SDimitry Andric   case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
3460b57cec5SDimitry Andric   case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
3470b57cec5SDimitry Andric   case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
3480b57cec5SDimitry Andric   case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
3490b57cec5SDimitry Andric   case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
3500b57cec5SDimitry Andric   default:
3510b57cec5SDimitry Andric     dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
3520b57cec5SDimitry Andric     llvm_unreachable(nullptr);
3530b57cec5SDimitry Andric   }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   SetValue(&I, R, SF);
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric #define IMPLEMENT_FCMP(OP, TY) \
3590b57cec5SDimitry Andric    case Type::TY##TyID: \
3600b57cec5SDimitry Andric      Dest.IntVal = APInt(1,Src1.TY##Val OP Src2.TY##Val); \
3610b57cec5SDimitry Andric      break
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric #define IMPLEMENT_VECTOR_FCMP_T(OP, TY)                             \
3640b57cec5SDimitry Andric   assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());     \
3650b57cec5SDimitry Andric   Dest.AggregateVal.resize( Src1.AggregateVal.size() );             \
3660b57cec5SDimitry Andric   for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++)              \
3670b57cec5SDimitry Andric     Dest.AggregateVal[_i].IntVal = APInt(1,                         \
3680b57cec5SDimitry Andric     Src1.AggregateVal[_i].TY##Val OP Src2.AggregateVal[_i].TY##Val);\
3690b57cec5SDimitry Andric   break;
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric #define IMPLEMENT_VECTOR_FCMP(OP)                                              \
3725ffd83dbSDimitry Andric   case Type::FixedVectorTyID:                                                  \
3735ffd83dbSDimitry Andric   case Type::ScalableVectorTyID:                                               \
3740b57cec5SDimitry Andric     if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {                 \
3750b57cec5SDimitry Andric       IMPLEMENT_VECTOR_FCMP_T(OP, Float);                                      \
3760b57cec5SDimitry Andric     } else {                                                                   \
3770b57cec5SDimitry Andric       IMPLEMENT_VECTOR_FCMP_T(OP, Double);                                     \
3780b57cec5SDimitry Andric     }
3790b57cec5SDimitry Andric 
executeFCMP_OEQ(GenericValue Src1,GenericValue Src2,Type * Ty)3800b57cec5SDimitry Andric static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
3810b57cec5SDimitry Andric                                    Type *Ty) {
3820b57cec5SDimitry Andric   GenericValue Dest;
3830b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
3840b57cec5SDimitry Andric     IMPLEMENT_FCMP(==, Float);
3850b57cec5SDimitry Andric     IMPLEMENT_FCMP(==, Double);
3860b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(==);
3870b57cec5SDimitry Andric   default:
3880b57cec5SDimitry Andric     dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
3890b57cec5SDimitry Andric     llvm_unreachable(nullptr);
3900b57cec5SDimitry Andric   }
3910b57cec5SDimitry Andric   return Dest;
3920b57cec5SDimitry Andric }
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric #define IMPLEMENT_SCALAR_NANS(TY, X,Y)                                      \
3950b57cec5SDimitry Andric   if (TY->isFloatTy()) {                                                    \
3960b57cec5SDimitry Andric     if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) {             \
3970b57cec5SDimitry Andric       Dest.IntVal = APInt(1,false);                                         \
3980b57cec5SDimitry Andric       return Dest;                                                          \
3990b57cec5SDimitry Andric     }                                                                       \
4000b57cec5SDimitry Andric   } else {                                                                  \
4010b57cec5SDimitry Andric     if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) {         \
4020b57cec5SDimitry Andric       Dest.IntVal = APInt(1,false);                                         \
4030b57cec5SDimitry Andric       return Dest;                                                          \
4040b57cec5SDimitry Andric     }                                                                       \
4050b57cec5SDimitry Andric   }
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric #define MASK_VECTOR_NANS_T(X,Y, TZ, FLAG)                                   \
4080b57cec5SDimitry Andric   assert(X.AggregateVal.size() == Y.AggregateVal.size());                   \
4090b57cec5SDimitry Andric   Dest.AggregateVal.resize( X.AggregateVal.size() );                        \
4100b57cec5SDimitry Andric   for( uint32_t _i=0;_i<X.AggregateVal.size();_i++) {                       \
4110b57cec5SDimitry Andric     if (X.AggregateVal[_i].TZ##Val != X.AggregateVal[_i].TZ##Val ||         \
4120b57cec5SDimitry Andric         Y.AggregateVal[_i].TZ##Val != Y.AggregateVal[_i].TZ##Val)           \
4130b57cec5SDimitry Andric       Dest.AggregateVal[_i].IntVal = APInt(1,FLAG);                         \
4140b57cec5SDimitry Andric     else  {                                                                 \
4150b57cec5SDimitry Andric       Dest.AggregateVal[_i].IntVal = APInt(1,!FLAG);                        \
4160b57cec5SDimitry Andric     }                                                                       \
4170b57cec5SDimitry Andric   }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric #define MASK_VECTOR_NANS(TY, X,Y, FLAG)                                     \
4200b57cec5SDimitry Andric   if (TY->isVectorTy()) {                                                   \
4210b57cec5SDimitry Andric     if (cast<VectorType>(TY)->getElementType()->isFloatTy()) {              \
4220b57cec5SDimitry Andric       MASK_VECTOR_NANS_T(X, Y, Float, FLAG)                                 \
4230b57cec5SDimitry Andric     } else {                                                                \
4240b57cec5SDimitry Andric       MASK_VECTOR_NANS_T(X, Y, Double, FLAG)                                \
4250b57cec5SDimitry Andric     }                                                                       \
4260b57cec5SDimitry Andric   }                                                                         \
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric 
executeFCMP_ONE(GenericValue Src1,GenericValue Src2,Type * Ty)4300b57cec5SDimitry Andric static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
4310b57cec5SDimitry Andric                                     Type *Ty)
4320b57cec5SDimitry Andric {
4330b57cec5SDimitry Andric   GenericValue Dest;
4340b57cec5SDimitry Andric   // if input is scalar value and Src1 or Src2 is NaN return false
4350b57cec5SDimitry Andric   IMPLEMENT_SCALAR_NANS(Ty, Src1, Src2)
4360b57cec5SDimitry Andric   // if vector input detect NaNs and fill mask
4370b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, false)
4380b57cec5SDimitry Andric   GenericValue DestMask = Dest;
4390b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
4400b57cec5SDimitry Andric     IMPLEMENT_FCMP(!=, Float);
4410b57cec5SDimitry Andric     IMPLEMENT_FCMP(!=, Double);
4420b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(!=);
4430b57cec5SDimitry Andric     default:
4440b57cec5SDimitry Andric       dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
4450b57cec5SDimitry Andric       llvm_unreachable(nullptr);
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric   // in vector case mask out NaN elements
4480b57cec5SDimitry Andric   if (Ty->isVectorTy())
4490b57cec5SDimitry Andric     for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
4500b57cec5SDimitry Andric       if (DestMask.AggregateVal[_i].IntVal == false)
4510b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1,false);
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   return Dest;
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
executeFCMP_OLE(GenericValue Src1,GenericValue Src2,Type * Ty)4560b57cec5SDimitry Andric static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
4570b57cec5SDimitry Andric                                    Type *Ty) {
4580b57cec5SDimitry Andric   GenericValue Dest;
4590b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
4600b57cec5SDimitry Andric     IMPLEMENT_FCMP(<=, Float);
4610b57cec5SDimitry Andric     IMPLEMENT_FCMP(<=, Double);
4620b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(<=);
4630b57cec5SDimitry Andric   default:
4640b57cec5SDimitry Andric     dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
4650b57cec5SDimitry Andric     llvm_unreachable(nullptr);
4660b57cec5SDimitry Andric   }
4670b57cec5SDimitry Andric   return Dest;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
executeFCMP_OGE(GenericValue Src1,GenericValue Src2,Type * Ty)4700b57cec5SDimitry Andric static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
4710b57cec5SDimitry Andric                                    Type *Ty) {
4720b57cec5SDimitry Andric   GenericValue Dest;
4730b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
4740b57cec5SDimitry Andric     IMPLEMENT_FCMP(>=, Float);
4750b57cec5SDimitry Andric     IMPLEMENT_FCMP(>=, Double);
4760b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(>=);
4770b57cec5SDimitry Andric   default:
4780b57cec5SDimitry Andric     dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
4790b57cec5SDimitry Andric     llvm_unreachable(nullptr);
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric   return Dest;
4820b57cec5SDimitry Andric }
4830b57cec5SDimitry Andric 
executeFCMP_OLT(GenericValue Src1,GenericValue Src2,Type * Ty)4840b57cec5SDimitry Andric static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
4850b57cec5SDimitry Andric                                    Type *Ty) {
4860b57cec5SDimitry Andric   GenericValue Dest;
4870b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
4880b57cec5SDimitry Andric     IMPLEMENT_FCMP(<, Float);
4890b57cec5SDimitry Andric     IMPLEMENT_FCMP(<, Double);
4900b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(<);
4910b57cec5SDimitry Andric   default:
4920b57cec5SDimitry Andric     dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
4930b57cec5SDimitry Andric     llvm_unreachable(nullptr);
4940b57cec5SDimitry Andric   }
4950b57cec5SDimitry Andric   return Dest;
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric 
executeFCMP_OGT(GenericValue Src1,GenericValue Src2,Type * Ty)4980b57cec5SDimitry Andric static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
4990b57cec5SDimitry Andric                                      Type *Ty) {
5000b57cec5SDimitry Andric   GenericValue Dest;
5010b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
5020b57cec5SDimitry Andric     IMPLEMENT_FCMP(>, Float);
5030b57cec5SDimitry Andric     IMPLEMENT_FCMP(>, Double);
5040b57cec5SDimitry Andric     IMPLEMENT_VECTOR_FCMP(>);
5050b57cec5SDimitry Andric   default:
5060b57cec5SDimitry Andric     dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
5070b57cec5SDimitry Andric     llvm_unreachable(nullptr);
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric   return Dest;
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric #define IMPLEMENT_UNORDERED(TY, X,Y)                                     \
5130b57cec5SDimitry Andric   if (TY->isFloatTy()) {                                                 \
5140b57cec5SDimitry Andric     if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) {          \
5150b57cec5SDimitry Andric       Dest.IntVal = APInt(1,true);                                       \
5160b57cec5SDimitry Andric       return Dest;                                                       \
5170b57cec5SDimitry Andric     }                                                                    \
5180b57cec5SDimitry Andric   } else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
5190b57cec5SDimitry Andric     Dest.IntVal = APInt(1,true);                                         \
5200b57cec5SDimitry Andric     return Dest;                                                         \
5210b57cec5SDimitry Andric   }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric #define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC)                             \
5240b57cec5SDimitry Andric   if (TY->isVectorTy()) {                                                      \
5250b57cec5SDimitry Andric     GenericValue DestMask = Dest;                                              \
5260b57cec5SDimitry Andric     Dest = FUNC(Src1, Src2, Ty);                                               \
5270b57cec5SDimitry Andric     for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++)                   \
5280b57cec5SDimitry Andric       if (DestMask.AggregateVal[_i].IntVal == true)                            \
5290b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1, true);                         \
5300b57cec5SDimitry Andric     return Dest;                                                               \
5310b57cec5SDimitry Andric   }
5320b57cec5SDimitry Andric 
executeFCMP_UEQ(GenericValue Src1,GenericValue Src2,Type * Ty)5330b57cec5SDimitry Andric static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
5340b57cec5SDimitry Andric                                    Type *Ty) {
5350b57cec5SDimitry Andric   GenericValue Dest;
5360b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5370b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5380b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OEQ)
5390b57cec5SDimitry Andric   return executeFCMP_OEQ(Src1, Src2, Ty);
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric }
5420b57cec5SDimitry Andric 
executeFCMP_UNE(GenericValue Src1,GenericValue Src2,Type * Ty)5430b57cec5SDimitry Andric static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2,
5440b57cec5SDimitry Andric                                    Type *Ty) {
5450b57cec5SDimitry Andric   GenericValue Dest;
5460b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5470b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5480b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_ONE)
5490b57cec5SDimitry Andric   return executeFCMP_ONE(Src1, Src2, Ty);
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric 
executeFCMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)5520b57cec5SDimitry Andric static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2,
5530b57cec5SDimitry Andric                                    Type *Ty) {
5540b57cec5SDimitry Andric   GenericValue Dest;
5550b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5560b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5570b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLE)
5580b57cec5SDimitry Andric   return executeFCMP_OLE(Src1, Src2, Ty);
5590b57cec5SDimitry Andric }
5600b57cec5SDimitry Andric 
executeFCMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)5610b57cec5SDimitry Andric static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2,
5620b57cec5SDimitry Andric                                    Type *Ty) {
5630b57cec5SDimitry Andric   GenericValue Dest;
5640b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5650b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5660b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGE)
5670b57cec5SDimitry Andric   return executeFCMP_OGE(Src1, Src2, Ty);
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric 
executeFCMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)5700b57cec5SDimitry Andric static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2,
5710b57cec5SDimitry Andric                                    Type *Ty) {
5720b57cec5SDimitry Andric   GenericValue Dest;
5730b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5740b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5750b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLT)
5760b57cec5SDimitry Andric   return executeFCMP_OLT(Src1, Src2, Ty);
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
executeFCMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)5790b57cec5SDimitry Andric static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2,
5800b57cec5SDimitry Andric                                      Type *Ty) {
5810b57cec5SDimitry Andric   GenericValue Dest;
5820b57cec5SDimitry Andric   IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5830b57cec5SDimitry Andric   MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5840b57cec5SDimitry Andric   IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGT)
5850b57cec5SDimitry Andric   return executeFCMP_OGT(Src1, Src2, Ty);
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric 
executeFCMP_ORD(GenericValue Src1,GenericValue Src2,Type * Ty)5880b57cec5SDimitry Andric static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
5890b57cec5SDimitry Andric                                      Type *Ty) {
5900b57cec5SDimitry Andric   GenericValue Dest;
5910b57cec5SDimitry Andric   if(Ty->isVectorTy()) {
5920b57cec5SDimitry Andric     assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
5930b57cec5SDimitry Andric     Dest.AggregateVal.resize( Src1.AggregateVal.size() );
5940b57cec5SDimitry Andric     if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
5950b57cec5SDimitry Andric       for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
5960b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1,
5970b57cec5SDimitry Andric         ( (Src1.AggregateVal[_i].FloatVal ==
5980b57cec5SDimitry Andric         Src1.AggregateVal[_i].FloatVal) &&
5990b57cec5SDimitry Andric         (Src2.AggregateVal[_i].FloatVal ==
6000b57cec5SDimitry Andric         Src2.AggregateVal[_i].FloatVal)));
6010b57cec5SDimitry Andric     } else {
6020b57cec5SDimitry Andric       for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6030b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1,
6040b57cec5SDimitry Andric         ( (Src1.AggregateVal[_i].DoubleVal ==
6050b57cec5SDimitry Andric         Src1.AggregateVal[_i].DoubleVal) &&
6060b57cec5SDimitry Andric         (Src2.AggregateVal[_i].DoubleVal ==
6070b57cec5SDimitry Andric         Src2.AggregateVal[_i].DoubleVal)));
6080b57cec5SDimitry Andric     }
6090b57cec5SDimitry Andric   } else if (Ty->isFloatTy())
6100b57cec5SDimitry Andric     Dest.IntVal = APInt(1,(Src1.FloatVal == Src1.FloatVal &&
6110b57cec5SDimitry Andric                            Src2.FloatVal == Src2.FloatVal));
6120b57cec5SDimitry Andric   else {
6130b57cec5SDimitry Andric     Dest.IntVal = APInt(1,(Src1.DoubleVal == Src1.DoubleVal &&
6140b57cec5SDimitry Andric                            Src2.DoubleVal == Src2.DoubleVal));
6150b57cec5SDimitry Andric   }
6160b57cec5SDimitry Andric   return Dest;
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
executeFCMP_UNO(GenericValue Src1,GenericValue Src2,Type * Ty)6190b57cec5SDimitry Andric static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
6200b57cec5SDimitry Andric                                      Type *Ty) {
6210b57cec5SDimitry Andric   GenericValue Dest;
6220b57cec5SDimitry Andric   if(Ty->isVectorTy()) {
6230b57cec5SDimitry Andric     assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
6240b57cec5SDimitry Andric     Dest.AggregateVal.resize( Src1.AggregateVal.size() );
6250b57cec5SDimitry Andric     if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
6260b57cec5SDimitry Andric       for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6270b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1,
6280b57cec5SDimitry Andric         ( (Src1.AggregateVal[_i].FloatVal !=
6290b57cec5SDimitry Andric            Src1.AggregateVal[_i].FloatVal) ||
6300b57cec5SDimitry Andric           (Src2.AggregateVal[_i].FloatVal !=
6310b57cec5SDimitry Andric            Src2.AggregateVal[_i].FloatVal)));
6320b57cec5SDimitry Andric       } else {
6330b57cec5SDimitry Andric         for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6340b57cec5SDimitry Andric           Dest.AggregateVal[_i].IntVal = APInt(1,
6350b57cec5SDimitry Andric           ( (Src1.AggregateVal[_i].DoubleVal !=
6360b57cec5SDimitry Andric              Src1.AggregateVal[_i].DoubleVal) ||
6370b57cec5SDimitry Andric             (Src2.AggregateVal[_i].DoubleVal !=
6380b57cec5SDimitry Andric              Src2.AggregateVal[_i].DoubleVal)));
6390b57cec5SDimitry Andric       }
6400b57cec5SDimitry Andric   } else if (Ty->isFloatTy())
6410b57cec5SDimitry Andric     Dest.IntVal = APInt(1,(Src1.FloatVal != Src1.FloatVal ||
6420b57cec5SDimitry Andric                            Src2.FloatVal != Src2.FloatVal));
6430b57cec5SDimitry Andric   else {
6440b57cec5SDimitry Andric     Dest.IntVal = APInt(1,(Src1.DoubleVal != Src1.DoubleVal ||
6450b57cec5SDimitry Andric                            Src2.DoubleVal != Src2.DoubleVal));
6460b57cec5SDimitry Andric   }
6470b57cec5SDimitry Andric   return Dest;
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric 
executeFCMP_BOOL(GenericValue Src1,GenericValue Src2,Type * Ty,const bool val)6500b57cec5SDimitry Andric static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2,
6510b57cec5SDimitry Andric                                      Type *Ty, const bool val) {
6520b57cec5SDimitry Andric   GenericValue Dest;
6530b57cec5SDimitry Andric     if(Ty->isVectorTy()) {
6540b57cec5SDimitry Andric       assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
6550b57cec5SDimitry Andric       Dest.AggregateVal.resize( Src1.AggregateVal.size() );
6560b57cec5SDimitry Andric       for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
6570b57cec5SDimitry Andric         Dest.AggregateVal[_i].IntVal = APInt(1,val);
6580b57cec5SDimitry Andric     } else {
6590b57cec5SDimitry Andric       Dest.IntVal = APInt(1, val);
6600b57cec5SDimitry Andric     }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric     return Dest;
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric 
visitFCmpInst(FCmpInst & I)6650b57cec5SDimitry Andric void Interpreter::visitFCmpInst(FCmpInst &I) {
6660b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
6670b57cec5SDimitry Andric   Type *Ty    = I.getOperand(0)->getType();
6680b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
6690b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
6700b57cec5SDimitry Andric   GenericValue R;   // Result
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric   switch (I.getPredicate()) {
6730b57cec5SDimitry Andric   default:
6740b57cec5SDimitry Andric     dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
6750b57cec5SDimitry Andric     llvm_unreachable(nullptr);
6760b57cec5SDimitry Andric   break;
6770b57cec5SDimitry Andric   case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
6780b57cec5SDimitry Andric   break;
6790b57cec5SDimitry Andric   case FCmpInst::FCMP_TRUE:  R = executeFCMP_BOOL(Src1, Src2, Ty, true);
6800b57cec5SDimitry Andric   break;
6810b57cec5SDimitry Andric   case FCmpInst::FCMP_ORD:   R = executeFCMP_ORD(Src1, Src2, Ty); break;
6820b57cec5SDimitry Andric   case FCmpInst::FCMP_UNO:   R = executeFCMP_UNO(Src1, Src2, Ty); break;
6830b57cec5SDimitry Andric   case FCmpInst::FCMP_UEQ:   R = executeFCMP_UEQ(Src1, Src2, Ty); break;
6840b57cec5SDimitry Andric   case FCmpInst::FCMP_OEQ:   R = executeFCMP_OEQ(Src1, Src2, Ty); break;
6850b57cec5SDimitry Andric   case FCmpInst::FCMP_UNE:   R = executeFCMP_UNE(Src1, Src2, Ty); break;
6860b57cec5SDimitry Andric   case FCmpInst::FCMP_ONE:   R = executeFCMP_ONE(Src1, Src2, Ty); break;
6870b57cec5SDimitry Andric   case FCmpInst::FCMP_ULT:   R = executeFCMP_ULT(Src1, Src2, Ty); break;
6880b57cec5SDimitry Andric   case FCmpInst::FCMP_OLT:   R = executeFCMP_OLT(Src1, Src2, Ty); break;
6890b57cec5SDimitry Andric   case FCmpInst::FCMP_UGT:   R = executeFCMP_UGT(Src1, Src2, Ty); break;
6900b57cec5SDimitry Andric   case FCmpInst::FCMP_OGT:   R = executeFCMP_OGT(Src1, Src2, Ty); break;
6910b57cec5SDimitry Andric   case FCmpInst::FCMP_ULE:   R = executeFCMP_ULE(Src1, Src2, Ty); break;
6920b57cec5SDimitry Andric   case FCmpInst::FCMP_OLE:   R = executeFCMP_OLE(Src1, Src2, Ty); break;
6930b57cec5SDimitry Andric   case FCmpInst::FCMP_UGE:   R = executeFCMP_UGE(Src1, Src2, Ty); break;
6940b57cec5SDimitry Andric   case FCmpInst::FCMP_OGE:   R = executeFCMP_OGE(Src1, Src2, Ty); break;
6950b57cec5SDimitry Andric   }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   SetValue(&I, R, SF);
6980b57cec5SDimitry Andric }
6990b57cec5SDimitry Andric 
visitBinaryOperator(BinaryOperator & I)7000b57cec5SDimitry Andric void Interpreter::visitBinaryOperator(BinaryOperator &I) {
7010b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
7020b57cec5SDimitry Andric   Type *Ty    = I.getOperand(0)->getType();
7030b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
7040b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
7050b57cec5SDimitry Andric   GenericValue R;   // Result
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric   // First process vector operation
7080b57cec5SDimitry Andric   if (Ty->isVectorTy()) {
7090b57cec5SDimitry Andric     assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
7100b57cec5SDimitry Andric     R.AggregateVal.resize(Src1.AggregateVal.size());
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric     // Macros to execute binary operation 'OP' over integer vectors
7130b57cec5SDimitry Andric #define INTEGER_VECTOR_OPERATION(OP)                               \
7140b57cec5SDimitry Andric     for (unsigned i = 0; i < R.AggregateVal.size(); ++i)           \
7150b57cec5SDimitry Andric       R.AggregateVal[i].IntVal =                                   \
7160b57cec5SDimitry Andric       Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric     // Additional macros to execute binary operations udiv/sdiv/urem/srem since
7190b57cec5SDimitry Andric     // they have different notation.
7200b57cec5SDimitry Andric #define INTEGER_VECTOR_FUNCTION(OP)                                \
7210b57cec5SDimitry Andric     for (unsigned i = 0; i < R.AggregateVal.size(); ++i)           \
7220b57cec5SDimitry Andric       R.AggregateVal[i].IntVal =                                   \
7230b57cec5SDimitry Andric       Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric     // Macros to execute binary operation 'OP' over floating point type TY
7260b57cec5SDimitry Andric     // (float or double) vectors
7270b57cec5SDimitry Andric #define FLOAT_VECTOR_FUNCTION(OP, TY)                               \
7280b57cec5SDimitry Andric       for (unsigned i = 0; i < R.AggregateVal.size(); ++i)          \
7290b57cec5SDimitry Andric         R.AggregateVal[i].TY =                                      \
7300b57cec5SDimitry Andric         Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric     // Macros to choose appropriate TY: float or double and run operation
7330b57cec5SDimitry Andric     // execution
7340b57cec5SDimitry Andric #define FLOAT_VECTOR_OP(OP) {                                         \
7350b57cec5SDimitry Andric   if (cast<VectorType>(Ty)->getElementType()->isFloatTy())            \
7360b57cec5SDimitry Andric     FLOAT_VECTOR_FUNCTION(OP, FloatVal)                               \
7370b57cec5SDimitry Andric   else {                                                              \
7380b57cec5SDimitry Andric     if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())         \
7390b57cec5SDimitry Andric       FLOAT_VECTOR_FUNCTION(OP, DoubleVal)                            \
7400b57cec5SDimitry Andric     else {                                                            \
7410b57cec5SDimitry Andric       dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
7420b57cec5SDimitry Andric       llvm_unreachable(0);                                            \
7430b57cec5SDimitry Andric     }                                                                 \
7440b57cec5SDimitry Andric   }                                                                   \
7450b57cec5SDimitry Andric }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric     switch(I.getOpcode()){
7480b57cec5SDimitry Andric     default:
7490b57cec5SDimitry Andric       dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
7500b57cec5SDimitry Andric       llvm_unreachable(nullptr);
7510b57cec5SDimitry Andric       break;
7520b57cec5SDimitry Andric     case Instruction::Add:   INTEGER_VECTOR_OPERATION(+) break;
7530b57cec5SDimitry Andric     case Instruction::Sub:   INTEGER_VECTOR_OPERATION(-) break;
7540b57cec5SDimitry Andric     case Instruction::Mul:   INTEGER_VECTOR_OPERATION(*) break;
7550b57cec5SDimitry Andric     case Instruction::UDiv:  INTEGER_VECTOR_FUNCTION(udiv) break;
7560b57cec5SDimitry Andric     case Instruction::SDiv:  INTEGER_VECTOR_FUNCTION(sdiv) break;
7570b57cec5SDimitry Andric     case Instruction::URem:  INTEGER_VECTOR_FUNCTION(urem) break;
7580b57cec5SDimitry Andric     case Instruction::SRem:  INTEGER_VECTOR_FUNCTION(srem) break;
7590b57cec5SDimitry Andric     case Instruction::And:   INTEGER_VECTOR_OPERATION(&) break;
7600b57cec5SDimitry Andric     case Instruction::Or:    INTEGER_VECTOR_OPERATION(|) break;
7610b57cec5SDimitry Andric     case Instruction::Xor:   INTEGER_VECTOR_OPERATION(^) break;
7620b57cec5SDimitry Andric     case Instruction::FAdd:  FLOAT_VECTOR_OP(+) break;
7630b57cec5SDimitry Andric     case Instruction::FSub:  FLOAT_VECTOR_OP(-) break;
7640b57cec5SDimitry Andric     case Instruction::FMul:  FLOAT_VECTOR_OP(*) break;
7650b57cec5SDimitry Andric     case Instruction::FDiv:  FLOAT_VECTOR_OP(/) break;
7660b57cec5SDimitry Andric     case Instruction::FRem:
7670b57cec5SDimitry Andric       if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
7680b57cec5SDimitry Andric         for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
7690b57cec5SDimitry Andric           R.AggregateVal[i].FloatVal =
7700b57cec5SDimitry Andric           fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
7710b57cec5SDimitry Andric       else {
7720b57cec5SDimitry Andric         if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
7730b57cec5SDimitry Andric           for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
7740b57cec5SDimitry Andric             R.AggregateVal[i].DoubleVal =
7750b57cec5SDimitry Andric             fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
7760b57cec5SDimitry Andric         else {
7770b57cec5SDimitry Andric           dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
7780b57cec5SDimitry Andric           llvm_unreachable(nullptr);
7790b57cec5SDimitry Andric         }
7800b57cec5SDimitry Andric       }
7810b57cec5SDimitry Andric       break;
7820b57cec5SDimitry Andric     }
7830b57cec5SDimitry Andric   } else {
7840b57cec5SDimitry Andric     switch (I.getOpcode()) {
7850b57cec5SDimitry Andric     default:
7860b57cec5SDimitry Andric       dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
7870b57cec5SDimitry Andric       llvm_unreachable(nullptr);
7880b57cec5SDimitry Andric       break;
7890b57cec5SDimitry Andric     case Instruction::Add:   R.IntVal = Src1.IntVal + Src2.IntVal; break;
7900b57cec5SDimitry Andric     case Instruction::Sub:   R.IntVal = Src1.IntVal - Src2.IntVal; break;
7910b57cec5SDimitry Andric     case Instruction::Mul:   R.IntVal = Src1.IntVal * Src2.IntVal; break;
7920b57cec5SDimitry Andric     case Instruction::FAdd:  executeFAddInst(R, Src1, Src2, Ty); break;
7930b57cec5SDimitry Andric     case Instruction::FSub:  executeFSubInst(R, Src1, Src2, Ty); break;
7940b57cec5SDimitry Andric     case Instruction::FMul:  executeFMulInst(R, Src1, Src2, Ty); break;
7950b57cec5SDimitry Andric     case Instruction::FDiv:  executeFDivInst(R, Src1, Src2, Ty); break;
7960b57cec5SDimitry Andric     case Instruction::FRem:  executeFRemInst(R, Src1, Src2, Ty); break;
7970b57cec5SDimitry Andric     case Instruction::UDiv:  R.IntVal = Src1.IntVal.udiv(Src2.IntVal); break;
7980b57cec5SDimitry Andric     case Instruction::SDiv:  R.IntVal = Src1.IntVal.sdiv(Src2.IntVal); break;
7990b57cec5SDimitry Andric     case Instruction::URem:  R.IntVal = Src1.IntVal.urem(Src2.IntVal); break;
8000b57cec5SDimitry Andric     case Instruction::SRem:  R.IntVal = Src1.IntVal.srem(Src2.IntVal); break;
8010b57cec5SDimitry Andric     case Instruction::And:   R.IntVal = Src1.IntVal & Src2.IntVal; break;
8020b57cec5SDimitry Andric     case Instruction::Or:    R.IntVal = Src1.IntVal | Src2.IntVal; break;
8030b57cec5SDimitry Andric     case Instruction::Xor:   R.IntVal = Src1.IntVal ^ Src2.IntVal; break;
8040b57cec5SDimitry Andric     }
8050b57cec5SDimitry Andric   }
8060b57cec5SDimitry Andric   SetValue(&I, R, SF);
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric 
executeSelectInst(GenericValue Src1,GenericValue Src2,GenericValue Src3,Type * Ty)8090b57cec5SDimitry Andric static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
8100b57cec5SDimitry Andric                                       GenericValue Src3, Type *Ty) {
8110b57cec5SDimitry Andric     GenericValue Dest;
8120b57cec5SDimitry Andric     if(Ty->isVectorTy()) {
8130b57cec5SDimitry Andric       assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
8140b57cec5SDimitry Andric       assert(Src2.AggregateVal.size() == Src3.AggregateVal.size());
8150b57cec5SDimitry Andric       Dest.AggregateVal.resize( Src1.AggregateVal.size() );
8160b57cec5SDimitry Andric       for (size_t i = 0; i < Src1.AggregateVal.size(); ++i)
8170b57cec5SDimitry Andric         Dest.AggregateVal[i] = (Src1.AggregateVal[i].IntVal == 0) ?
8180b57cec5SDimitry Andric           Src3.AggregateVal[i] : Src2.AggregateVal[i];
8190b57cec5SDimitry Andric     } else {
8200b57cec5SDimitry Andric       Dest = (Src1.IntVal == 0) ? Src3 : Src2;
8210b57cec5SDimitry Andric     }
8220b57cec5SDimitry Andric     return Dest;
8230b57cec5SDimitry Andric }
8240b57cec5SDimitry Andric 
visitSelectInst(SelectInst & I)8250b57cec5SDimitry Andric void Interpreter::visitSelectInst(SelectInst &I) {
8260b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
8270b57cec5SDimitry Andric   Type * Ty = I.getOperand(0)->getType();
8280b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
8290b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
8300b57cec5SDimitry Andric   GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
8310b57cec5SDimitry Andric   GenericValue R = executeSelectInst(Src1, Src2, Src3, Ty);
8320b57cec5SDimitry Andric   SetValue(&I, R, SF);
8330b57cec5SDimitry Andric }
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8360b57cec5SDimitry Andric //                     Terminator Instruction Implementations
8370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8380b57cec5SDimitry Andric 
exitCalled(GenericValue GV)8390b57cec5SDimitry Andric void Interpreter::exitCalled(GenericValue GV) {
8400b57cec5SDimitry Andric   // runAtExitHandlers() assumes there are no stack frames, but
8410b57cec5SDimitry Andric   // if exit() was called, then it had a stack frame. Blow away
8420b57cec5SDimitry Andric   // the stack before interpreting atexit handlers.
8430b57cec5SDimitry Andric   ECStack.clear();
8440b57cec5SDimitry Andric   runAtExitHandlers();
8450b57cec5SDimitry Andric   exit(GV.IntVal.zextOrTrunc(32).getZExtValue());
8460b57cec5SDimitry Andric }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric /// Pop the last stack frame off of ECStack and then copy the result
8490b57cec5SDimitry Andric /// back into the result variable if we are not returning void. The
8500b57cec5SDimitry Andric /// result variable may be the ExitValue, or the Value of the calling
8510b57cec5SDimitry Andric /// CallInst if there was a previous stack frame. This method may
8520b57cec5SDimitry Andric /// invalidate any ECStack iterators you have. This method also takes
8530b57cec5SDimitry Andric /// care of switching to the normal destination BB, if we are returning
8540b57cec5SDimitry Andric /// from an invoke.
8550b57cec5SDimitry Andric ///
popStackAndReturnValueToCaller(Type * RetTy,GenericValue Result)8560b57cec5SDimitry Andric void Interpreter::popStackAndReturnValueToCaller(Type *RetTy,
8570b57cec5SDimitry Andric                                                  GenericValue Result) {
8580b57cec5SDimitry Andric   // Pop the current stack frame.
8590b57cec5SDimitry Andric   ECStack.pop_back();
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric   if (ECStack.empty()) {  // Finished main.  Put result into exit code...
8620b57cec5SDimitry Andric     if (RetTy && !RetTy->isVoidTy()) {          // Nonvoid return type?
8630b57cec5SDimitry Andric       ExitValue = Result;   // Capture the exit value of the program
8640b57cec5SDimitry Andric     } else {
8650b57cec5SDimitry Andric       memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
8660b57cec5SDimitry Andric     }
8670b57cec5SDimitry Andric   } else {
8680b57cec5SDimitry Andric     // If we have a previous stack frame, and we have a previous call,
8690b57cec5SDimitry Andric     // fill in the return value...
8700b57cec5SDimitry Andric     ExecutionContext &CallingSF = ECStack.back();
8715ffd83dbSDimitry Andric     if (CallingSF.Caller) {
8720b57cec5SDimitry Andric       // Save result...
8735ffd83dbSDimitry Andric       if (!CallingSF.Caller->getType()->isVoidTy())
8745ffd83dbSDimitry Andric         SetValue(CallingSF.Caller, Result, CallingSF);
8755ffd83dbSDimitry Andric       if (InvokeInst *II = dyn_cast<InvokeInst>(CallingSF.Caller))
8760b57cec5SDimitry Andric         SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
8775ffd83dbSDimitry Andric       CallingSF.Caller = nullptr;             // We returned from the call...
8780b57cec5SDimitry Andric     }
8790b57cec5SDimitry Andric   }
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
visitReturnInst(ReturnInst & I)8820b57cec5SDimitry Andric void Interpreter::visitReturnInst(ReturnInst &I) {
8830b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
8840b57cec5SDimitry Andric   Type *RetTy = Type::getVoidTy(I.getContext());
8850b57cec5SDimitry Andric   GenericValue Result;
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   // Save away the return value... (if we are not 'ret void')
8880b57cec5SDimitry Andric   if (I.getNumOperands()) {
8890b57cec5SDimitry Andric     RetTy  = I.getReturnValue()->getType();
8900b57cec5SDimitry Andric     Result = getOperandValue(I.getReturnValue(), SF);
8910b57cec5SDimitry Andric   }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   popStackAndReturnValueToCaller(RetTy, Result);
8940b57cec5SDimitry Andric }
8950b57cec5SDimitry Andric 
visitUnreachableInst(UnreachableInst & I)8960b57cec5SDimitry Andric void Interpreter::visitUnreachableInst(UnreachableInst &I) {
8970b57cec5SDimitry Andric   report_fatal_error("Program executed an 'unreachable' instruction!");
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric 
visitBranchInst(BranchInst & I)9000b57cec5SDimitry Andric void Interpreter::visitBranchInst(BranchInst &I) {
9010b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
9020b57cec5SDimitry Andric   BasicBlock *Dest;
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric   Dest = I.getSuccessor(0);          // Uncond branches have a fixed dest...
9050b57cec5SDimitry Andric   if (!I.isUnconditional()) {
9060b57cec5SDimitry Andric     Value *Cond = I.getCondition();
9070b57cec5SDimitry Andric     if (getOperandValue(Cond, SF).IntVal == 0) // If false cond...
9080b57cec5SDimitry Andric       Dest = I.getSuccessor(1);
9090b57cec5SDimitry Andric   }
9100b57cec5SDimitry Andric   SwitchToNewBasicBlock(Dest, SF);
9110b57cec5SDimitry Andric }
9120b57cec5SDimitry Andric 
visitSwitchInst(SwitchInst & I)9130b57cec5SDimitry Andric void Interpreter::visitSwitchInst(SwitchInst &I) {
9140b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
9150b57cec5SDimitry Andric   Value* Cond = I.getCondition();
9160b57cec5SDimitry Andric   Type *ElTy = Cond->getType();
9170b57cec5SDimitry Andric   GenericValue CondVal = getOperandValue(Cond, SF);
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   // Check to see if any of the cases match...
9200b57cec5SDimitry Andric   BasicBlock *Dest = nullptr;
9210b57cec5SDimitry Andric   for (auto Case : I.cases()) {
9220b57cec5SDimitry Andric     GenericValue CaseVal = getOperandValue(Case.getCaseValue(), SF);
9230b57cec5SDimitry Andric     if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
9240b57cec5SDimitry Andric       Dest = cast<BasicBlock>(Case.getCaseSuccessor());
9250b57cec5SDimitry Andric       break;
9260b57cec5SDimitry Andric     }
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric   if (!Dest) Dest = I.getDefaultDest();   // No cases matched: use default
9290b57cec5SDimitry Andric   SwitchToNewBasicBlock(Dest, SF);
9300b57cec5SDimitry Andric }
9310b57cec5SDimitry Andric 
visitIndirectBrInst(IndirectBrInst & I)9320b57cec5SDimitry Andric void Interpreter::visitIndirectBrInst(IndirectBrInst &I) {
9330b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
9340b57cec5SDimitry Andric   void *Dest = GVTOP(getOperandValue(I.getAddress(), SF));
9350b57cec5SDimitry Andric   SwitchToNewBasicBlock((BasicBlock*)Dest, SF);
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric // SwitchToNewBasicBlock - This method is used to jump to a new basic block.
9400b57cec5SDimitry Andric // This function handles the actual updating of block and instruction iterators
9410b57cec5SDimitry Andric // as well as execution of all of the PHI nodes in the destination block.
9420b57cec5SDimitry Andric //
9430b57cec5SDimitry Andric // This method does this because all of the PHI nodes must be executed
9440b57cec5SDimitry Andric // atomically, reading their inputs before any of the results are updated.  Not
9450b57cec5SDimitry Andric // doing this can cause problems if the PHI nodes depend on other PHI nodes for
9460b57cec5SDimitry Andric // their inputs.  If the input PHI node is updated before it is read, incorrect
9470b57cec5SDimitry Andric // results can happen.  Thus we use a two phase approach.
9480b57cec5SDimitry Andric //
SwitchToNewBasicBlock(BasicBlock * Dest,ExecutionContext & SF)9490b57cec5SDimitry Andric void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){
9500b57cec5SDimitry Andric   BasicBlock *PrevBB = SF.CurBB;      // Remember where we came from...
9510b57cec5SDimitry Andric   SF.CurBB   = Dest;                  // Update CurBB to branch destination
9520b57cec5SDimitry Andric   SF.CurInst = SF.CurBB->begin();     // Update new instruction ptr...
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric   if (!isa<PHINode>(SF.CurInst)) return;  // Nothing fancy to do
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric   // Loop over all of the PHI nodes in the current block, reading their inputs.
9570b57cec5SDimitry Andric   std::vector<GenericValue> ResultValues;
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric   for (; PHINode *PN = dyn_cast<PHINode>(SF.CurInst); ++SF.CurInst) {
9600b57cec5SDimitry Andric     // Search for the value corresponding to this previous bb...
9610b57cec5SDimitry Andric     int i = PN->getBasicBlockIndex(PrevBB);
9620b57cec5SDimitry Andric     assert(i != -1 && "PHINode doesn't contain entry for predecessor??");
9630b57cec5SDimitry Andric     Value *IncomingValue = PN->getIncomingValue(i);
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric     // Save the incoming value for this PHI node...
9660b57cec5SDimitry Andric     ResultValues.push_back(getOperandValue(IncomingValue, SF));
9670b57cec5SDimitry Andric   }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   // Now loop over all of the PHI nodes setting their values...
9700b57cec5SDimitry Andric   SF.CurInst = SF.CurBB->begin();
9710b57cec5SDimitry Andric   for (unsigned i = 0; isa<PHINode>(SF.CurInst); ++SF.CurInst, ++i) {
9720b57cec5SDimitry Andric     PHINode *PN = cast<PHINode>(SF.CurInst);
9730b57cec5SDimitry Andric     SetValue(PN, ResultValues[i], SF);
9740b57cec5SDimitry Andric   }
9750b57cec5SDimitry Andric }
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9780b57cec5SDimitry Andric //                     Memory Instruction Implementations
9790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9800b57cec5SDimitry Andric 
visitAllocaInst(AllocaInst & I)9810b57cec5SDimitry Andric void Interpreter::visitAllocaInst(AllocaInst &I) {
9820b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
9830b57cec5SDimitry Andric 
984fe6060f1SDimitry Andric   Type *Ty = I.getAllocatedType(); // Type to be allocated
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   // Get the number of elements being allocated by the array...
9870b57cec5SDimitry Andric   unsigned NumElements =
9880b57cec5SDimitry Andric     getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   unsigned TypeSize = (size_t)getDataLayout().getTypeAllocSize(Ty);
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   // Avoid malloc-ing zero bytes, use max()...
9930b57cec5SDimitry Andric   unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric   // Allocate enough memory to hold the type...
9960b57cec5SDimitry Andric   void *Memory = safe_malloc(MemToAlloc);
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Allocated Type: " << *Ty << " (" << TypeSize
9990b57cec5SDimitry Andric                     << " bytes) x " << NumElements << " (Total: " << MemToAlloc
10000b57cec5SDimitry Andric                     << ") at " << uintptr_t(Memory) << '\n');
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   GenericValue Result = PTOGV(Memory);
10030b57cec5SDimitry Andric   assert(Result.PointerVal && "Null pointer returned by malloc!");
10040b57cec5SDimitry Andric   SetValue(&I, Result, SF);
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric   if (I.getOpcode() == Instruction::Alloca)
10070b57cec5SDimitry Andric     ECStack.back().Allocas.add(Memory);
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric // getElementOffset - The workhorse for getelementptr.
10110b57cec5SDimitry Andric //
executeGEPOperation(Value * Ptr,gep_type_iterator I,gep_type_iterator E,ExecutionContext & SF)10120b57cec5SDimitry Andric GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
10130b57cec5SDimitry Andric                                               gep_type_iterator E,
10140b57cec5SDimitry Andric                                               ExecutionContext &SF) {
10150b57cec5SDimitry Andric   assert(Ptr->getType()->isPointerTy() &&
10160b57cec5SDimitry Andric          "Cannot getElementOffset of a nonpointer type!");
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   uint64_t Total = 0;
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric   for (; I != E; ++I) {
10210b57cec5SDimitry Andric     if (StructType *STy = I.getStructTypeOrNull()) {
10220b57cec5SDimitry Andric       const StructLayout *SLO = getDataLayout().getStructLayout(STy);
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric       const ConstantInt *CPU = cast<ConstantInt>(I.getOperand());
10250b57cec5SDimitry Andric       unsigned Index = unsigned(CPU->getZExtValue());
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric       Total += SLO->getElementOffset(Index);
10280b57cec5SDimitry Andric     } else {
10290b57cec5SDimitry Andric       // Get the index number for the array... which must be long type...
10300b57cec5SDimitry Andric       GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric       int64_t Idx;
10330b57cec5SDimitry Andric       unsigned BitWidth =
10340b57cec5SDimitry Andric         cast<IntegerType>(I.getOperand()->getType())->getBitWidth();
10350b57cec5SDimitry Andric       if (BitWidth == 32)
10360b57cec5SDimitry Andric         Idx = (int64_t)(int32_t)IdxGV.IntVal.getZExtValue();
10370b57cec5SDimitry Andric       else {
10380b57cec5SDimitry Andric         assert(BitWidth == 64 && "Invalid index type for getelementptr");
10390b57cec5SDimitry Andric         Idx = (int64_t)IdxGV.IntVal.getZExtValue();
10400b57cec5SDimitry Andric       }
1041*1db9f3b2SDimitry Andric       Total += I.getSequentialElementStride(getDataLayout()) * Idx;
10420b57cec5SDimitry Andric     }
10430b57cec5SDimitry Andric   }
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric   GenericValue Result;
10460b57cec5SDimitry Andric   Result.PointerVal = ((char*)getOperandValue(Ptr, SF).PointerVal) + Total;
10470b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "GEP Index " << Total << " bytes.\n");
10480b57cec5SDimitry Andric   return Result;
10490b57cec5SDimitry Andric }
10500b57cec5SDimitry Andric 
visitGetElementPtrInst(GetElementPtrInst & I)10510b57cec5SDimitry Andric void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
10520b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
10530b57cec5SDimitry Andric   SetValue(&I, executeGEPOperation(I.getPointerOperand(),
10540b57cec5SDimitry Andric                                    gep_type_begin(I), gep_type_end(I), SF), SF);
10550b57cec5SDimitry Andric }
10560b57cec5SDimitry Andric 
visitLoadInst(LoadInst & I)10570b57cec5SDimitry Andric void Interpreter::visitLoadInst(LoadInst &I) {
10580b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
10590b57cec5SDimitry Andric   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
10600b57cec5SDimitry Andric   GenericValue *Ptr = (GenericValue*)GVTOP(SRC);
10610b57cec5SDimitry Andric   GenericValue Result;
10620b57cec5SDimitry Andric   LoadValueFromMemory(Result, Ptr, I.getType());
10630b57cec5SDimitry Andric   SetValue(&I, Result, SF);
10640b57cec5SDimitry Andric   if (I.isVolatile() && PrintVolatile)
10650b57cec5SDimitry Andric     dbgs() << "Volatile load " << I;
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric 
visitStoreInst(StoreInst & I)10680b57cec5SDimitry Andric void Interpreter::visitStoreInst(StoreInst &I) {
10690b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
10700b57cec5SDimitry Andric   GenericValue Val = getOperandValue(I.getOperand(0), SF);
10710b57cec5SDimitry Andric   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
10720b57cec5SDimitry Andric   StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC),
10730b57cec5SDimitry Andric                      I.getOperand(0)->getType());
10740b57cec5SDimitry Andric   if (I.isVolatile() && PrintVolatile)
10750b57cec5SDimitry Andric     dbgs() << "Volatile store: " << I;
10760b57cec5SDimitry Andric }
10770b57cec5SDimitry Andric 
10780b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10790b57cec5SDimitry Andric //                 Miscellaneous Instruction Implementations
10800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10810b57cec5SDimitry Andric 
visitVAStartInst(VAStartInst & I)10825ffd83dbSDimitry Andric void Interpreter::visitVAStartInst(VAStartInst &I) {
10830b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
10840b57cec5SDimitry Andric   GenericValue ArgIndex;
10850b57cec5SDimitry Andric   ArgIndex.UIntPairVal.first = ECStack.size() - 1;
10860b57cec5SDimitry Andric   ArgIndex.UIntPairVal.second = 0;
10875ffd83dbSDimitry Andric   SetValue(&I, ArgIndex, SF);
10880b57cec5SDimitry Andric }
10895ffd83dbSDimitry Andric 
visitVAEndInst(VAEndInst & I)10905ffd83dbSDimitry Andric void Interpreter::visitVAEndInst(VAEndInst &I) {
10915ffd83dbSDimitry Andric   // va_end is a noop for the interpreter
10925ffd83dbSDimitry Andric }
10935ffd83dbSDimitry Andric 
visitVACopyInst(VACopyInst & I)10945ffd83dbSDimitry Andric void Interpreter::visitVACopyInst(VACopyInst &I) {
10955ffd83dbSDimitry Andric   ExecutionContext &SF = ECStack.back();
10965ffd83dbSDimitry Andric   SetValue(&I, getOperandValue(*I.arg_begin(), SF), SF);
10975ffd83dbSDimitry Andric }
10985ffd83dbSDimitry Andric 
visitIntrinsicInst(IntrinsicInst & I)10995ffd83dbSDimitry Andric void Interpreter::visitIntrinsicInst(IntrinsicInst &I) {
11005ffd83dbSDimitry Andric   ExecutionContext &SF = ECStack.back();
11015ffd83dbSDimitry Andric 
11020b57cec5SDimitry Andric   // If it is an unknown intrinsic function, use the intrinsic lowering
11030b57cec5SDimitry Andric   // class to transform it into hopefully tasty LLVM code.
11040b57cec5SDimitry Andric   //
11055ffd83dbSDimitry Andric   BasicBlock::iterator Me(&I);
11065ffd83dbSDimitry Andric   BasicBlock *Parent = I.getParent();
11075ffd83dbSDimitry Andric   bool atBegin(Parent->begin() == Me);
11080b57cec5SDimitry Andric   if (!atBegin)
11095ffd83dbSDimitry Andric     --Me;
11105ffd83dbSDimitry Andric   IL->LowerIntrinsicCall(&I);
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric   // Restore the CurInst pointer to the first instruction newly inserted, if
11130b57cec5SDimitry Andric   // any.
11140b57cec5SDimitry Andric   if (atBegin) {
11150b57cec5SDimitry Andric     SF.CurInst = Parent->begin();
11160b57cec5SDimitry Andric   } else {
11175ffd83dbSDimitry Andric     SF.CurInst = Me;
11180b57cec5SDimitry Andric     ++SF.CurInst;
11190b57cec5SDimitry Andric   }
11200b57cec5SDimitry Andric }
11210b57cec5SDimitry Andric 
visitCallBase(CallBase & I)11225ffd83dbSDimitry Andric void Interpreter::visitCallBase(CallBase &I) {
11235ffd83dbSDimitry Andric   ExecutionContext &SF = ECStack.back();
11240b57cec5SDimitry Andric 
11255ffd83dbSDimitry Andric   SF.Caller = &I;
11260b57cec5SDimitry Andric   std::vector<GenericValue> ArgVals;
11275ffd83dbSDimitry Andric   const unsigned NumArgs = SF.Caller->arg_size();
11280b57cec5SDimitry Andric   ArgVals.reserve(NumArgs);
11295ffd83dbSDimitry Andric   for (Value *V : SF.Caller->args())
11300b57cec5SDimitry Andric     ArgVals.push_back(getOperandValue(V, SF));
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric   // To handle indirect calls, we must get the pointer value from the argument
11330b57cec5SDimitry Andric   // and treat it as a function pointer.
11345ffd83dbSDimitry Andric   GenericValue SRC = getOperandValue(SF.Caller->getCalledOperand(), SF);
11350b57cec5SDimitry Andric   callFunction((Function*)GVTOP(SRC), ArgVals);
11360b57cec5SDimitry Andric }
11370b57cec5SDimitry Andric 
11380b57cec5SDimitry Andric // auxiliary function for shift operations
getShiftAmount(uint64_t orgShiftAmount,llvm::APInt valueToShift)11390b57cec5SDimitry Andric static unsigned getShiftAmount(uint64_t orgShiftAmount,
11400b57cec5SDimitry Andric                                llvm::APInt valueToShift) {
11410b57cec5SDimitry Andric   unsigned valueWidth = valueToShift.getBitWidth();
11420b57cec5SDimitry Andric   if (orgShiftAmount < (uint64_t)valueWidth)
11430b57cec5SDimitry Andric     return orgShiftAmount;
11440b57cec5SDimitry Andric   // according to the llvm documentation, if orgShiftAmount > valueWidth,
11450b57cec5SDimitry Andric   // the result is undfeined. but we do shift by this rule:
11460b57cec5SDimitry Andric   return (NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
11470b57cec5SDimitry Andric }
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric 
visitShl(BinaryOperator & I)11500b57cec5SDimitry Andric void Interpreter::visitShl(BinaryOperator &I) {
11510b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
11520b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
11530b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
11540b57cec5SDimitry Andric   GenericValue Dest;
11550b57cec5SDimitry Andric   Type *Ty = I.getType();
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric   if (Ty->isVectorTy()) {
11580b57cec5SDimitry Andric     uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
11590b57cec5SDimitry Andric     assert(src1Size == Src2.AggregateVal.size());
11600b57cec5SDimitry Andric     for (unsigned i = 0; i < src1Size; i++) {
11610b57cec5SDimitry Andric       GenericValue Result;
11620b57cec5SDimitry Andric       uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
11630b57cec5SDimitry Andric       llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
11640b57cec5SDimitry Andric       Result.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
11650b57cec5SDimitry Andric       Dest.AggregateVal.push_back(Result);
11660b57cec5SDimitry Andric     }
11670b57cec5SDimitry Andric   } else {
11680b57cec5SDimitry Andric     // scalar
11690b57cec5SDimitry Andric     uint64_t shiftAmount = Src2.IntVal.getZExtValue();
11700b57cec5SDimitry Andric     llvm::APInt valueToShift = Src1.IntVal;
11710b57cec5SDimitry Andric     Dest.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
11720b57cec5SDimitry Andric   }
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
11750b57cec5SDimitry Andric }
11760b57cec5SDimitry Andric 
visitLShr(BinaryOperator & I)11770b57cec5SDimitry Andric void Interpreter::visitLShr(BinaryOperator &I) {
11780b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
11790b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
11800b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
11810b57cec5SDimitry Andric   GenericValue Dest;
11820b57cec5SDimitry Andric   Type *Ty = I.getType();
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric   if (Ty->isVectorTy()) {
11850b57cec5SDimitry Andric     uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
11860b57cec5SDimitry Andric     assert(src1Size == Src2.AggregateVal.size());
11870b57cec5SDimitry Andric     for (unsigned i = 0; i < src1Size; i++) {
11880b57cec5SDimitry Andric       GenericValue Result;
11890b57cec5SDimitry Andric       uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
11900b57cec5SDimitry Andric       llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
11910b57cec5SDimitry Andric       Result.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
11920b57cec5SDimitry Andric       Dest.AggregateVal.push_back(Result);
11930b57cec5SDimitry Andric     }
11940b57cec5SDimitry Andric   } else {
11950b57cec5SDimitry Andric     // scalar
11960b57cec5SDimitry Andric     uint64_t shiftAmount = Src2.IntVal.getZExtValue();
11970b57cec5SDimitry Andric     llvm::APInt valueToShift = Src1.IntVal;
11980b57cec5SDimitry Andric     Dest.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
11990b57cec5SDimitry Andric   }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
visitAShr(BinaryOperator & I)12040b57cec5SDimitry Andric void Interpreter::visitAShr(BinaryOperator &I) {
12050b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
12060b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
12070b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
12080b57cec5SDimitry Andric   GenericValue Dest;
12090b57cec5SDimitry Andric   Type *Ty = I.getType();
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   if (Ty->isVectorTy()) {
12120b57cec5SDimitry Andric     size_t src1Size = Src1.AggregateVal.size();
12130b57cec5SDimitry Andric     assert(src1Size == Src2.AggregateVal.size());
12140b57cec5SDimitry Andric     for (unsigned i = 0; i < src1Size; i++) {
12150b57cec5SDimitry Andric       GenericValue Result;
12160b57cec5SDimitry Andric       uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
12170b57cec5SDimitry Andric       llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
12180b57cec5SDimitry Andric       Result.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
12190b57cec5SDimitry Andric       Dest.AggregateVal.push_back(Result);
12200b57cec5SDimitry Andric     }
12210b57cec5SDimitry Andric   } else {
12220b57cec5SDimitry Andric     // scalar
12230b57cec5SDimitry Andric     uint64_t shiftAmount = Src2.IntVal.getZExtValue();
12240b57cec5SDimitry Andric     llvm::APInt valueToShift = Src1.IntVal;
12250b57cec5SDimitry Andric     Dest.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
12260b57cec5SDimitry Andric   }
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
12290b57cec5SDimitry Andric }
12300b57cec5SDimitry Andric 
executeTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12310b57cec5SDimitry Andric GenericValue Interpreter::executeTruncInst(Value *SrcVal, Type *DstTy,
12320b57cec5SDimitry Andric                                            ExecutionContext &SF) {
12330b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12340b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
12350b57cec5SDimitry Andric   if (SrcTy->isVectorTy()) {
12360b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
12370b57cec5SDimitry Andric     unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
12380b57cec5SDimitry Andric     unsigned NumElts = Src.AggregateVal.size();
12390b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal
12400b57cec5SDimitry Andric     Dest.AggregateVal.resize(NumElts);
12410b57cec5SDimitry Andric     for (unsigned i = 0; i < NumElts; i++)
12420b57cec5SDimitry Andric       Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.trunc(DBitWidth);
12430b57cec5SDimitry Andric   } else {
12440b57cec5SDimitry Andric     IntegerType *DITy = cast<IntegerType>(DstTy);
12450b57cec5SDimitry Andric     unsigned DBitWidth = DITy->getBitWidth();
12460b57cec5SDimitry Andric     Dest.IntVal = Src.IntVal.trunc(DBitWidth);
12470b57cec5SDimitry Andric   }
12480b57cec5SDimitry Andric   return Dest;
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric 
executeSExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12510b57cec5SDimitry Andric GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy,
12520b57cec5SDimitry Andric                                           ExecutionContext &SF) {
12530b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
12540b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12550b57cec5SDimitry Andric   if (SrcTy->isVectorTy()) {
12560b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
12570b57cec5SDimitry Andric     unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
12580b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
12590b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal.
12600b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
12610b57cec5SDimitry Andric     for (unsigned i = 0; i < size; i++)
12620b57cec5SDimitry Andric       Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
12630b57cec5SDimitry Andric   } else {
12640b57cec5SDimitry Andric     auto *DITy = cast<IntegerType>(DstTy);
12650b57cec5SDimitry Andric     unsigned DBitWidth = DITy->getBitWidth();
12660b57cec5SDimitry Andric     Dest.IntVal = Src.IntVal.sext(DBitWidth);
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric   return Dest;
12690b57cec5SDimitry Andric }
12700b57cec5SDimitry Andric 
executeZExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12710b57cec5SDimitry Andric GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy,
12720b57cec5SDimitry Andric                                           ExecutionContext &SF) {
12730b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
12740b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12750b57cec5SDimitry Andric   if (SrcTy->isVectorTy()) {
12760b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
12770b57cec5SDimitry Andric     unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
12780b57cec5SDimitry Andric 
12790b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
12800b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal.
12810b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
12820b57cec5SDimitry Andric     for (unsigned i = 0; i < size; i++)
12830b57cec5SDimitry Andric       Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
12840b57cec5SDimitry Andric   } else {
12850b57cec5SDimitry Andric     auto *DITy = cast<IntegerType>(DstTy);
12860b57cec5SDimitry Andric     unsigned DBitWidth = DITy->getBitWidth();
12870b57cec5SDimitry Andric     Dest.IntVal = Src.IntVal.zext(DBitWidth);
12880b57cec5SDimitry Andric   }
12890b57cec5SDimitry Andric   return Dest;
12900b57cec5SDimitry Andric }
12910b57cec5SDimitry Andric 
executeFPTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12920b57cec5SDimitry Andric GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, Type *DstTy,
12930b57cec5SDimitry Andric                                              ExecutionContext &SF) {
12940b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12950b57cec5SDimitry Andric 
12965ffd83dbSDimitry Andric   if (isa<VectorType>(SrcVal->getType())) {
12970b57cec5SDimitry Andric     assert(SrcVal->getType()->getScalarType()->isDoubleTy() &&
12980b57cec5SDimitry Andric            DstTy->getScalarType()->isFloatTy() &&
12990b57cec5SDimitry Andric            "Invalid FPTrunc instruction");
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
13020b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal.
13030b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
13040b57cec5SDimitry Andric     for (unsigned i = 0; i < size; i++)
13050b57cec5SDimitry Andric       Dest.AggregateVal[i].FloatVal = (float)Src.AggregateVal[i].DoubleVal;
13060b57cec5SDimitry Andric   } else {
13070b57cec5SDimitry Andric     assert(SrcVal->getType()->isDoubleTy() && DstTy->isFloatTy() &&
13080b57cec5SDimitry Andric            "Invalid FPTrunc instruction");
13090b57cec5SDimitry Andric     Dest.FloatVal = (float)Src.DoubleVal;
13100b57cec5SDimitry Andric   }
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric   return Dest;
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
executeFPExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13150b57cec5SDimitry Andric GenericValue Interpreter::executeFPExtInst(Value *SrcVal, Type *DstTy,
13160b57cec5SDimitry Andric                                            ExecutionContext &SF) {
13170b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13180b57cec5SDimitry Andric 
13195ffd83dbSDimitry Andric   if (isa<VectorType>(SrcVal->getType())) {
13200b57cec5SDimitry Andric     assert(SrcVal->getType()->getScalarType()->isFloatTy() &&
13210b57cec5SDimitry Andric            DstTy->getScalarType()->isDoubleTy() && "Invalid FPExt instruction");
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
13240b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal.
13250b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
13260b57cec5SDimitry Andric     for (unsigned i = 0; i < size; i++)
13270b57cec5SDimitry Andric       Dest.AggregateVal[i].DoubleVal = (double)Src.AggregateVal[i].FloatVal;
13280b57cec5SDimitry Andric   } else {
13290b57cec5SDimitry Andric     assert(SrcVal->getType()->isFloatTy() && DstTy->isDoubleTy() &&
13300b57cec5SDimitry Andric            "Invalid FPExt instruction");
13310b57cec5SDimitry Andric     Dest.DoubleVal = (double)Src.FloatVal;
13320b57cec5SDimitry Andric   }
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric   return Dest;
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
executeFPToUIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13370b57cec5SDimitry Andric GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, Type *DstTy,
13380b57cec5SDimitry Andric                                             ExecutionContext &SF) {
13390b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
13400b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13410b57cec5SDimitry Andric 
13425ffd83dbSDimitry Andric   if (isa<VectorType>(SrcTy)) {
13430b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
13440b57cec5SDimitry Andric     Type *SrcVecTy = SrcTy->getScalarType();
13450b57cec5SDimitry Andric     uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
13460b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
13470b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal.
13480b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric     if (SrcVecTy->getTypeID() == Type::FloatTyID) {
13510b57cec5SDimitry Andric       assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToUI instruction");
13520b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
13530b57cec5SDimitry Andric         Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
13540b57cec5SDimitry Andric             Src.AggregateVal[i].FloatVal, DBitWidth);
13550b57cec5SDimitry Andric     } else {
13560b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
13570b57cec5SDimitry Andric         Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
13580b57cec5SDimitry Andric             Src.AggregateVal[i].DoubleVal, DBitWidth);
13590b57cec5SDimitry Andric     }
13600b57cec5SDimitry Andric   } else {
13610b57cec5SDimitry Andric     // scalar
13620b57cec5SDimitry Andric     uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
13630b57cec5SDimitry Andric     assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric     if (SrcTy->getTypeID() == Type::FloatTyID)
13660b57cec5SDimitry Andric       Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
13670b57cec5SDimitry Andric     else {
13680b57cec5SDimitry Andric       Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
13690b57cec5SDimitry Andric     }
13700b57cec5SDimitry Andric   }
13710b57cec5SDimitry Andric 
13720b57cec5SDimitry Andric   return Dest;
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric 
executeFPToSIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13750b57cec5SDimitry Andric GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, Type *DstTy,
13760b57cec5SDimitry Andric                                             ExecutionContext &SF) {
13770b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
13780b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13790b57cec5SDimitry Andric 
13805ffd83dbSDimitry Andric   if (isa<VectorType>(SrcTy)) {
13810b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
13820b57cec5SDimitry Andric     Type *SrcVecTy = SrcTy->getScalarType();
13830b57cec5SDimitry Andric     uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
13840b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
13850b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal
13860b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric     if (SrcVecTy->getTypeID() == Type::FloatTyID) {
13890b57cec5SDimitry Andric       assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToSI instruction");
13900b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
13910b57cec5SDimitry Andric         Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
13920b57cec5SDimitry Andric             Src.AggregateVal[i].FloatVal, DBitWidth);
13930b57cec5SDimitry Andric     } else {
13940b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
13950b57cec5SDimitry Andric         Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
13960b57cec5SDimitry Andric             Src.AggregateVal[i].DoubleVal, DBitWidth);
13970b57cec5SDimitry Andric     }
13980b57cec5SDimitry Andric   } else {
13990b57cec5SDimitry Andric     // scalar
14000b57cec5SDimitry Andric     unsigned DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
14010b57cec5SDimitry Andric     assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric     if (SrcTy->getTypeID() == Type::FloatTyID)
14040b57cec5SDimitry Andric       Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
14050b57cec5SDimitry Andric     else {
14060b57cec5SDimitry Andric       Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
14070b57cec5SDimitry Andric     }
14080b57cec5SDimitry Andric   }
14090b57cec5SDimitry Andric   return Dest;
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric 
executeUIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14120b57cec5SDimitry Andric GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, Type *DstTy,
14130b57cec5SDimitry Andric                                             ExecutionContext &SF) {
14140b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14150b57cec5SDimitry Andric 
14165ffd83dbSDimitry Andric   if (isa<VectorType>(SrcVal->getType())) {
14170b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
14180b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
14190b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal
14200b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric     if (DstVecTy->getTypeID() == Type::FloatTyID) {
14230b57cec5SDimitry Andric       assert(DstVecTy->isFloatingPointTy() && "Invalid UIToFP instruction");
14240b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
14250b57cec5SDimitry Andric         Dest.AggregateVal[i].FloatVal =
14260b57cec5SDimitry Andric             APIntOps::RoundAPIntToFloat(Src.AggregateVal[i].IntVal);
14270b57cec5SDimitry Andric     } else {
14280b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
14290b57cec5SDimitry Andric         Dest.AggregateVal[i].DoubleVal =
14300b57cec5SDimitry Andric             APIntOps::RoundAPIntToDouble(Src.AggregateVal[i].IntVal);
14310b57cec5SDimitry Andric     }
14320b57cec5SDimitry Andric   } else {
14330b57cec5SDimitry Andric     // scalar
14340b57cec5SDimitry Andric     assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
14350b57cec5SDimitry Andric     if (DstTy->getTypeID() == Type::FloatTyID)
14360b57cec5SDimitry Andric       Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
14370b57cec5SDimitry Andric     else {
14380b57cec5SDimitry Andric       Dest.DoubleVal = APIntOps::RoundAPIntToDouble(Src.IntVal);
14390b57cec5SDimitry Andric     }
14400b57cec5SDimitry Andric   }
14410b57cec5SDimitry Andric   return Dest;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
executeSIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14440b57cec5SDimitry Andric GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, Type *DstTy,
14450b57cec5SDimitry Andric                                             ExecutionContext &SF) {
14460b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14470b57cec5SDimitry Andric 
14485ffd83dbSDimitry Andric   if (isa<VectorType>(SrcVal->getType())) {
14490b57cec5SDimitry Andric     Type *DstVecTy = DstTy->getScalarType();
14500b57cec5SDimitry Andric     unsigned size = Src.AggregateVal.size();
14510b57cec5SDimitry Andric     // the sizes of src and dst vectors must be equal
14520b57cec5SDimitry Andric     Dest.AggregateVal.resize(size);
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric     if (DstVecTy->getTypeID() == Type::FloatTyID) {
14550b57cec5SDimitry Andric       assert(DstVecTy->isFloatingPointTy() && "Invalid SIToFP instruction");
14560b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
14570b57cec5SDimitry Andric         Dest.AggregateVal[i].FloatVal =
14580b57cec5SDimitry Andric             APIntOps::RoundSignedAPIntToFloat(Src.AggregateVal[i].IntVal);
14590b57cec5SDimitry Andric     } else {
14600b57cec5SDimitry Andric       for (unsigned i = 0; i < size; i++)
14610b57cec5SDimitry Andric         Dest.AggregateVal[i].DoubleVal =
14620b57cec5SDimitry Andric             APIntOps::RoundSignedAPIntToDouble(Src.AggregateVal[i].IntVal);
14630b57cec5SDimitry Andric     }
14640b57cec5SDimitry Andric   } else {
14650b57cec5SDimitry Andric     // scalar
14660b57cec5SDimitry Andric     assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric     if (DstTy->getTypeID() == Type::FloatTyID)
14690b57cec5SDimitry Andric       Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
14700b57cec5SDimitry Andric     else {
14710b57cec5SDimitry Andric       Dest.DoubleVal = APIntOps::RoundSignedAPIntToDouble(Src.IntVal);
14720b57cec5SDimitry Andric     }
14730b57cec5SDimitry Andric   }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric   return Dest;
14760b57cec5SDimitry Andric }
14770b57cec5SDimitry Andric 
executePtrToIntInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14780b57cec5SDimitry Andric GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, Type *DstTy,
14790b57cec5SDimitry Andric                                               ExecutionContext &SF) {
14800b57cec5SDimitry Andric   uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
14810b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14820b57cec5SDimitry Andric   assert(SrcVal->getType()->isPointerTy() && "Invalid PtrToInt instruction");
14830b57cec5SDimitry Andric 
14840b57cec5SDimitry Andric   Dest.IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
14850b57cec5SDimitry Andric   return Dest;
14860b57cec5SDimitry Andric }
14870b57cec5SDimitry Andric 
executeIntToPtrInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14880b57cec5SDimitry Andric GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, Type *DstTy,
14890b57cec5SDimitry Andric                                               ExecutionContext &SF) {
14900b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14910b57cec5SDimitry Andric   assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
14920b57cec5SDimitry Andric 
14930b57cec5SDimitry Andric   uint32_t PtrSize = getDataLayout().getPointerSizeInBits();
14940b57cec5SDimitry Andric   if (PtrSize != Src.IntVal.getBitWidth())
14950b57cec5SDimitry Andric     Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric   Dest.PointerVal = PointerTy(intptr_t(Src.IntVal.getZExtValue()));
14980b57cec5SDimitry Andric   return Dest;
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric 
executeBitCastInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)15010b57cec5SDimitry Andric GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy,
15020b57cec5SDimitry Andric                                              ExecutionContext &SF) {
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric   // This instruction supports bitwise conversion of vectors to integers and
15050b57cec5SDimitry Andric   // to vectors of other types (as long as they have the same size)
15060b57cec5SDimitry Andric   Type *SrcTy = SrcVal->getType();
15070b57cec5SDimitry Andric   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
15080b57cec5SDimitry Andric 
15095ffd83dbSDimitry Andric   if (isa<VectorType>(SrcTy) || isa<VectorType>(DstTy)) {
15100b57cec5SDimitry Andric     // vector src bitcast to vector dst or vector src bitcast to scalar dst or
15110b57cec5SDimitry Andric     // scalar src bitcast to vector dst
15120b57cec5SDimitry Andric     bool isLittleEndian = getDataLayout().isLittleEndian();
15130b57cec5SDimitry Andric     GenericValue TempDst, TempSrc, SrcVec;
15140b57cec5SDimitry Andric     Type *SrcElemTy;
15150b57cec5SDimitry Andric     Type *DstElemTy;
15160b57cec5SDimitry Andric     unsigned SrcBitSize;
15170b57cec5SDimitry Andric     unsigned DstBitSize;
15180b57cec5SDimitry Andric     unsigned SrcNum;
15190b57cec5SDimitry Andric     unsigned DstNum;
15200b57cec5SDimitry Andric 
15215ffd83dbSDimitry Andric     if (isa<VectorType>(SrcTy)) {
15220b57cec5SDimitry Andric       SrcElemTy = SrcTy->getScalarType();
15230b57cec5SDimitry Andric       SrcBitSize = SrcTy->getScalarSizeInBits();
15240b57cec5SDimitry Andric       SrcNum = Src.AggregateVal.size();
15250b57cec5SDimitry Andric       SrcVec = Src;
15260b57cec5SDimitry Andric     } else {
15270b57cec5SDimitry Andric       // if src is scalar value, make it vector <1 x type>
15280b57cec5SDimitry Andric       SrcElemTy = SrcTy;
15290b57cec5SDimitry Andric       SrcBitSize = SrcTy->getPrimitiveSizeInBits();
15300b57cec5SDimitry Andric       SrcNum = 1;
15310b57cec5SDimitry Andric       SrcVec.AggregateVal.push_back(Src);
15320b57cec5SDimitry Andric     }
15330b57cec5SDimitry Andric 
15345ffd83dbSDimitry Andric     if (isa<VectorType>(DstTy)) {
15350b57cec5SDimitry Andric       DstElemTy = DstTy->getScalarType();
15360b57cec5SDimitry Andric       DstBitSize = DstTy->getScalarSizeInBits();
15370b57cec5SDimitry Andric       DstNum = (SrcNum * SrcBitSize) / DstBitSize;
15380b57cec5SDimitry Andric     } else {
15390b57cec5SDimitry Andric       DstElemTy = DstTy;
15400b57cec5SDimitry Andric       DstBitSize = DstTy->getPrimitiveSizeInBits();
15410b57cec5SDimitry Andric       DstNum = 1;
15420b57cec5SDimitry Andric     }
15430b57cec5SDimitry Andric 
15440b57cec5SDimitry Andric     if (SrcNum * SrcBitSize != DstNum * DstBitSize)
15450b57cec5SDimitry Andric       llvm_unreachable("Invalid BitCast");
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric     // If src is floating point, cast to integer first.
15480b57cec5SDimitry Andric     TempSrc.AggregateVal.resize(SrcNum);
15490b57cec5SDimitry Andric     if (SrcElemTy->isFloatTy()) {
15500b57cec5SDimitry Andric       for (unsigned i = 0; i < SrcNum; i++)
15510b57cec5SDimitry Andric         TempSrc.AggregateVal[i].IntVal =
15520b57cec5SDimitry Andric             APInt::floatToBits(SrcVec.AggregateVal[i].FloatVal);
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric     } else if (SrcElemTy->isDoubleTy()) {
15550b57cec5SDimitry Andric       for (unsigned i = 0; i < SrcNum; i++)
15560b57cec5SDimitry Andric         TempSrc.AggregateVal[i].IntVal =
15570b57cec5SDimitry Andric             APInt::doubleToBits(SrcVec.AggregateVal[i].DoubleVal);
15580b57cec5SDimitry Andric     } else if (SrcElemTy->isIntegerTy()) {
15590b57cec5SDimitry Andric       for (unsigned i = 0; i < SrcNum; i++)
15600b57cec5SDimitry Andric         TempSrc.AggregateVal[i].IntVal = SrcVec.AggregateVal[i].IntVal;
15610b57cec5SDimitry Andric     } else {
15620b57cec5SDimitry Andric       // Pointers are not allowed as the element type of vector.
15630b57cec5SDimitry Andric       llvm_unreachable("Invalid Bitcast");
15640b57cec5SDimitry Andric     }
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric     // now TempSrc is integer type vector
15670b57cec5SDimitry Andric     if (DstNum < SrcNum) {
15680b57cec5SDimitry Andric       // Example: bitcast <4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>
15690b57cec5SDimitry Andric       unsigned Ratio = SrcNum / DstNum;
15700b57cec5SDimitry Andric       unsigned SrcElt = 0;
15710b57cec5SDimitry Andric       for (unsigned i = 0; i < DstNum; i++) {
15720b57cec5SDimitry Andric         GenericValue Elt;
15730b57cec5SDimitry Andric         Elt.IntVal = 0;
15740b57cec5SDimitry Andric         Elt.IntVal = Elt.IntVal.zext(DstBitSize);
15750b57cec5SDimitry Andric         unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
15760b57cec5SDimitry Andric         for (unsigned j = 0; j < Ratio; j++) {
15770b57cec5SDimitry Andric           APInt Tmp;
15780b57cec5SDimitry Andric           Tmp = Tmp.zext(SrcBitSize);
15790b57cec5SDimitry Andric           Tmp = TempSrc.AggregateVal[SrcElt++].IntVal;
15800b57cec5SDimitry Andric           Tmp = Tmp.zext(DstBitSize);
15810b57cec5SDimitry Andric           Tmp <<= ShiftAmt;
15820b57cec5SDimitry Andric           ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
15830b57cec5SDimitry Andric           Elt.IntVal |= Tmp;
15840b57cec5SDimitry Andric         }
15850b57cec5SDimitry Andric         TempDst.AggregateVal.push_back(Elt);
15860b57cec5SDimitry Andric       }
15870b57cec5SDimitry Andric     } else {
15880b57cec5SDimitry Andric       // Example: bitcast <2 x i64> <i64 0, i64 1> to <4 x i32>
15890b57cec5SDimitry Andric       unsigned Ratio = DstNum / SrcNum;
15900b57cec5SDimitry Andric       for (unsigned i = 0; i < SrcNum; i++) {
15910b57cec5SDimitry Andric         unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
15920b57cec5SDimitry Andric         for (unsigned j = 0; j < Ratio; j++) {
15930b57cec5SDimitry Andric           GenericValue Elt;
15940b57cec5SDimitry Andric           Elt.IntVal = Elt.IntVal.zext(SrcBitSize);
15950b57cec5SDimitry Andric           Elt.IntVal = TempSrc.AggregateVal[i].IntVal;
15960b57cec5SDimitry Andric           Elt.IntVal.lshrInPlace(ShiftAmt);
15970b57cec5SDimitry Andric           // it could be DstBitSize == SrcBitSize, so check it
15980b57cec5SDimitry Andric           if (DstBitSize < SrcBitSize)
15990b57cec5SDimitry Andric             Elt.IntVal = Elt.IntVal.trunc(DstBitSize);
16000b57cec5SDimitry Andric           ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
16010b57cec5SDimitry Andric           TempDst.AggregateVal.push_back(Elt);
16020b57cec5SDimitry Andric         }
16030b57cec5SDimitry Andric       }
16040b57cec5SDimitry Andric     }
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric     // convert result from integer to specified type
16075ffd83dbSDimitry Andric     if (isa<VectorType>(DstTy)) {
16080b57cec5SDimitry Andric       if (DstElemTy->isDoubleTy()) {
16090b57cec5SDimitry Andric         Dest.AggregateVal.resize(DstNum);
16100b57cec5SDimitry Andric         for (unsigned i = 0; i < DstNum; i++)
16110b57cec5SDimitry Andric           Dest.AggregateVal[i].DoubleVal =
16120b57cec5SDimitry Andric               TempDst.AggregateVal[i].IntVal.bitsToDouble();
16130b57cec5SDimitry Andric       } else if (DstElemTy->isFloatTy()) {
16140b57cec5SDimitry Andric         Dest.AggregateVal.resize(DstNum);
16150b57cec5SDimitry Andric         for (unsigned i = 0; i < DstNum; i++)
16160b57cec5SDimitry Andric           Dest.AggregateVal[i].FloatVal =
16170b57cec5SDimitry Andric               TempDst.AggregateVal[i].IntVal.bitsToFloat();
16180b57cec5SDimitry Andric       } else {
16190b57cec5SDimitry Andric         Dest = TempDst;
16200b57cec5SDimitry Andric       }
16210b57cec5SDimitry Andric     } else {
16220b57cec5SDimitry Andric       if (DstElemTy->isDoubleTy())
16230b57cec5SDimitry Andric         Dest.DoubleVal = TempDst.AggregateVal[0].IntVal.bitsToDouble();
16240b57cec5SDimitry Andric       else if (DstElemTy->isFloatTy()) {
16250b57cec5SDimitry Andric         Dest.FloatVal = TempDst.AggregateVal[0].IntVal.bitsToFloat();
16260b57cec5SDimitry Andric       } else {
16270b57cec5SDimitry Andric         Dest.IntVal = TempDst.AggregateVal[0].IntVal;
16280b57cec5SDimitry Andric       }
16290b57cec5SDimitry Andric     }
16305ffd83dbSDimitry Andric   } else { //  if (isa<VectorType>(SrcTy)) || isa<VectorType>(DstTy))
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric     // scalar src bitcast to scalar dst
16330b57cec5SDimitry Andric     if (DstTy->isPointerTy()) {
16340b57cec5SDimitry Andric       assert(SrcTy->isPointerTy() && "Invalid BitCast");
16350b57cec5SDimitry Andric       Dest.PointerVal = Src.PointerVal;
16360b57cec5SDimitry Andric     } else if (DstTy->isIntegerTy()) {
16370b57cec5SDimitry Andric       if (SrcTy->isFloatTy())
16380b57cec5SDimitry Andric         Dest.IntVal = APInt::floatToBits(Src.FloatVal);
16390b57cec5SDimitry Andric       else if (SrcTy->isDoubleTy()) {
16400b57cec5SDimitry Andric         Dest.IntVal = APInt::doubleToBits(Src.DoubleVal);
16410b57cec5SDimitry Andric       } else if (SrcTy->isIntegerTy()) {
16420b57cec5SDimitry Andric         Dest.IntVal = Src.IntVal;
16430b57cec5SDimitry Andric       } else {
16440b57cec5SDimitry Andric         llvm_unreachable("Invalid BitCast");
16450b57cec5SDimitry Andric       }
16460b57cec5SDimitry Andric     } else if (DstTy->isFloatTy()) {
16470b57cec5SDimitry Andric       if (SrcTy->isIntegerTy())
16480b57cec5SDimitry Andric         Dest.FloatVal = Src.IntVal.bitsToFloat();
16490b57cec5SDimitry Andric       else {
16500b57cec5SDimitry Andric         Dest.FloatVal = Src.FloatVal;
16510b57cec5SDimitry Andric       }
16520b57cec5SDimitry Andric     } else if (DstTy->isDoubleTy()) {
16530b57cec5SDimitry Andric       if (SrcTy->isIntegerTy())
16540b57cec5SDimitry Andric         Dest.DoubleVal = Src.IntVal.bitsToDouble();
16550b57cec5SDimitry Andric       else {
16560b57cec5SDimitry Andric         Dest.DoubleVal = Src.DoubleVal;
16570b57cec5SDimitry Andric       }
16580b57cec5SDimitry Andric     } else {
16590b57cec5SDimitry Andric       llvm_unreachable("Invalid Bitcast");
16600b57cec5SDimitry Andric     }
16610b57cec5SDimitry Andric   }
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric   return Dest;
16640b57cec5SDimitry Andric }
16650b57cec5SDimitry Andric 
visitTruncInst(TruncInst & I)16660b57cec5SDimitry Andric void Interpreter::visitTruncInst(TruncInst &I) {
16670b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16680b57cec5SDimitry Andric   SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
16690b57cec5SDimitry Andric }
16700b57cec5SDimitry Andric 
visitSExtInst(SExtInst & I)16710b57cec5SDimitry Andric void Interpreter::visitSExtInst(SExtInst &I) {
16720b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16730b57cec5SDimitry Andric   SetValue(&I, executeSExtInst(I.getOperand(0), I.getType(), SF), SF);
16740b57cec5SDimitry Andric }
16750b57cec5SDimitry Andric 
visitZExtInst(ZExtInst & I)16760b57cec5SDimitry Andric void Interpreter::visitZExtInst(ZExtInst &I) {
16770b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16780b57cec5SDimitry Andric   SetValue(&I, executeZExtInst(I.getOperand(0), I.getType(), SF), SF);
16790b57cec5SDimitry Andric }
16800b57cec5SDimitry Andric 
visitFPTruncInst(FPTruncInst & I)16810b57cec5SDimitry Andric void Interpreter::visitFPTruncInst(FPTruncInst &I) {
16820b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16830b57cec5SDimitry Andric   SetValue(&I, executeFPTruncInst(I.getOperand(0), I.getType(), SF), SF);
16840b57cec5SDimitry Andric }
16850b57cec5SDimitry Andric 
visitFPExtInst(FPExtInst & I)16860b57cec5SDimitry Andric void Interpreter::visitFPExtInst(FPExtInst &I) {
16870b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16880b57cec5SDimitry Andric   SetValue(&I, executeFPExtInst(I.getOperand(0), I.getType(), SF), SF);
16890b57cec5SDimitry Andric }
16900b57cec5SDimitry Andric 
visitUIToFPInst(UIToFPInst & I)16910b57cec5SDimitry Andric void Interpreter::visitUIToFPInst(UIToFPInst &I) {
16920b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16930b57cec5SDimitry Andric   SetValue(&I, executeUIToFPInst(I.getOperand(0), I.getType(), SF), SF);
16940b57cec5SDimitry Andric }
16950b57cec5SDimitry Andric 
visitSIToFPInst(SIToFPInst & I)16960b57cec5SDimitry Andric void Interpreter::visitSIToFPInst(SIToFPInst &I) {
16970b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
16980b57cec5SDimitry Andric   SetValue(&I, executeSIToFPInst(I.getOperand(0), I.getType(), SF), SF);
16990b57cec5SDimitry Andric }
17000b57cec5SDimitry Andric 
visitFPToUIInst(FPToUIInst & I)17010b57cec5SDimitry Andric void Interpreter::visitFPToUIInst(FPToUIInst &I) {
17020b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17030b57cec5SDimitry Andric   SetValue(&I, executeFPToUIInst(I.getOperand(0), I.getType(), SF), SF);
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric 
visitFPToSIInst(FPToSIInst & I)17060b57cec5SDimitry Andric void Interpreter::visitFPToSIInst(FPToSIInst &I) {
17070b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17080b57cec5SDimitry Andric   SetValue(&I, executeFPToSIInst(I.getOperand(0), I.getType(), SF), SF);
17090b57cec5SDimitry Andric }
17100b57cec5SDimitry Andric 
visitPtrToIntInst(PtrToIntInst & I)17110b57cec5SDimitry Andric void Interpreter::visitPtrToIntInst(PtrToIntInst &I) {
17120b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17130b57cec5SDimitry Andric   SetValue(&I, executePtrToIntInst(I.getOperand(0), I.getType(), SF), SF);
17140b57cec5SDimitry Andric }
17150b57cec5SDimitry Andric 
visitIntToPtrInst(IntToPtrInst & I)17160b57cec5SDimitry Andric void Interpreter::visitIntToPtrInst(IntToPtrInst &I) {
17170b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17180b57cec5SDimitry Andric   SetValue(&I, executeIntToPtrInst(I.getOperand(0), I.getType(), SF), SF);
17190b57cec5SDimitry Andric }
17200b57cec5SDimitry Andric 
visitBitCastInst(BitCastInst & I)17210b57cec5SDimitry Andric void Interpreter::visitBitCastInst(BitCastInst &I) {
17220b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17230b57cec5SDimitry Andric   SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
17240b57cec5SDimitry Andric }
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric #define IMPLEMENT_VAARG(TY) \
17270b57cec5SDimitry Andric    case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
17280b57cec5SDimitry Andric 
visitVAArgInst(VAArgInst & I)17290b57cec5SDimitry Andric void Interpreter::visitVAArgInst(VAArgInst &I) {
17300b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   // Get the incoming valist parameter.  LLI treats the valist as a
17330b57cec5SDimitry Andric   // (ec-stack-depth var-arg-index) pair.
17340b57cec5SDimitry Andric   GenericValue VAList = getOperandValue(I.getOperand(0), SF);
17350b57cec5SDimitry Andric   GenericValue Dest;
17360b57cec5SDimitry Andric   GenericValue Src = ECStack[VAList.UIntPairVal.first]
17370b57cec5SDimitry Andric                       .VarArgs[VAList.UIntPairVal.second];
17380b57cec5SDimitry Andric   Type *Ty = I.getType();
17390b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
17400b57cec5SDimitry Andric   case Type::IntegerTyID:
17410b57cec5SDimitry Andric     Dest.IntVal = Src.IntVal;
17420b57cec5SDimitry Andric     break;
17430b57cec5SDimitry Andric   IMPLEMENT_VAARG(Pointer);
17440b57cec5SDimitry Andric   IMPLEMENT_VAARG(Float);
17450b57cec5SDimitry Andric   IMPLEMENT_VAARG(Double);
17460b57cec5SDimitry Andric   default:
17470b57cec5SDimitry Andric     dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
17480b57cec5SDimitry Andric     llvm_unreachable(nullptr);
17490b57cec5SDimitry Andric   }
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric   // Set the Value of this Instruction.
17520b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric   // Move the pointer to the next vararg.
17550b57cec5SDimitry Andric   ++VAList.UIntPairVal.second;
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric 
visitExtractElementInst(ExtractElementInst & I)17580b57cec5SDimitry Andric void Interpreter::visitExtractElementInst(ExtractElementInst &I) {
17590b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17600b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
17610b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
17620b57cec5SDimitry Andric   GenericValue Dest;
17630b57cec5SDimitry Andric 
17640b57cec5SDimitry Andric   Type *Ty = I.getType();
17650b57cec5SDimitry Andric   const unsigned indx = unsigned(Src2.IntVal.getZExtValue());
17660b57cec5SDimitry Andric 
17670b57cec5SDimitry Andric   if(Src1.AggregateVal.size() > indx) {
17680b57cec5SDimitry Andric     switch (Ty->getTypeID()) {
17690b57cec5SDimitry Andric     default:
17700b57cec5SDimitry Andric       dbgs() << "Unhandled destination type for extractelement instruction: "
17710b57cec5SDimitry Andric       << *Ty << "\n";
17720b57cec5SDimitry Andric       llvm_unreachable(nullptr);
17730b57cec5SDimitry Andric       break;
17740b57cec5SDimitry Andric     case Type::IntegerTyID:
17750b57cec5SDimitry Andric       Dest.IntVal = Src1.AggregateVal[indx].IntVal;
17760b57cec5SDimitry Andric       break;
17770b57cec5SDimitry Andric     case Type::FloatTyID:
17780b57cec5SDimitry Andric       Dest.FloatVal = Src1.AggregateVal[indx].FloatVal;
17790b57cec5SDimitry Andric       break;
17800b57cec5SDimitry Andric     case Type::DoubleTyID:
17810b57cec5SDimitry Andric       Dest.DoubleVal = Src1.AggregateVal[indx].DoubleVal;
17820b57cec5SDimitry Andric       break;
17830b57cec5SDimitry Andric     }
17840b57cec5SDimitry Andric   } else {
17850b57cec5SDimitry Andric     dbgs() << "Invalid index in extractelement instruction\n";
17860b57cec5SDimitry Andric   }
17870b57cec5SDimitry Andric 
17880b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric 
visitInsertElementInst(InsertElementInst & I)17910b57cec5SDimitry Andric void Interpreter::visitInsertElementInst(InsertElementInst &I) {
17920b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
17930b57cec5SDimitry Andric   VectorType *Ty = cast<VectorType>(I.getType());
17940b57cec5SDimitry Andric 
17950b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
17960b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
17970b57cec5SDimitry Andric   GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
17980b57cec5SDimitry Andric   GenericValue Dest;
17990b57cec5SDimitry Andric 
18000b57cec5SDimitry Andric   Type *TyContained = Ty->getElementType();
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric   const unsigned indx = unsigned(Src3.IntVal.getZExtValue());
18030b57cec5SDimitry Andric   Dest.AggregateVal = Src1.AggregateVal;
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   if(Src1.AggregateVal.size() <= indx)
18060b57cec5SDimitry Andric       llvm_unreachable("Invalid index in insertelement instruction");
18070b57cec5SDimitry Andric   switch (TyContained->getTypeID()) {
18080b57cec5SDimitry Andric     default:
18090b57cec5SDimitry Andric       llvm_unreachable("Unhandled dest type for insertelement instruction");
18100b57cec5SDimitry Andric     case Type::IntegerTyID:
18110b57cec5SDimitry Andric       Dest.AggregateVal[indx].IntVal = Src2.IntVal;
18120b57cec5SDimitry Andric       break;
18130b57cec5SDimitry Andric     case Type::FloatTyID:
18140b57cec5SDimitry Andric       Dest.AggregateVal[indx].FloatVal = Src2.FloatVal;
18150b57cec5SDimitry Andric       break;
18160b57cec5SDimitry Andric     case Type::DoubleTyID:
18170b57cec5SDimitry Andric       Dest.AggregateVal[indx].DoubleVal = Src2.DoubleVal;
18180b57cec5SDimitry Andric       break;
18190b57cec5SDimitry Andric   }
18200b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
18210b57cec5SDimitry Andric }
18220b57cec5SDimitry Andric 
visitShuffleVectorInst(ShuffleVectorInst & I)18230b57cec5SDimitry Andric void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){
18240b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric   VectorType *Ty = cast<VectorType>(I.getType());
18270b57cec5SDimitry Andric 
18280b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
18290b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
18300b57cec5SDimitry Andric   GenericValue Dest;
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric   // There is no need to check types of src1 and src2, because the compiled
18330b57cec5SDimitry Andric   // bytecode can't contain different types for src1 and src2 for a
18340b57cec5SDimitry Andric   // shufflevector instruction.
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   Type *TyContained = Ty->getElementType();
18370b57cec5SDimitry Andric   unsigned src1Size = (unsigned)Src1.AggregateVal.size();
18380b57cec5SDimitry Andric   unsigned src2Size = (unsigned)Src2.AggregateVal.size();
18395ffd83dbSDimitry Andric   unsigned src3Size = I.getShuffleMask().size();
18400b57cec5SDimitry Andric 
18410b57cec5SDimitry Andric   Dest.AggregateVal.resize(src3Size);
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric   switch (TyContained->getTypeID()) {
18440b57cec5SDimitry Andric     default:
18450b57cec5SDimitry Andric       llvm_unreachable("Unhandled dest type for insertelement instruction");
18460b57cec5SDimitry Andric       break;
18470b57cec5SDimitry Andric     case Type::IntegerTyID:
18480b57cec5SDimitry Andric       for( unsigned i=0; i<src3Size; i++) {
18495ffd83dbSDimitry Andric         unsigned j = std::max(0, I.getMaskValue(i));
18500b57cec5SDimitry Andric         if(j < src1Size)
18510b57cec5SDimitry Andric           Dest.AggregateVal[i].IntVal = Src1.AggregateVal[j].IntVal;
18520b57cec5SDimitry Andric         else if(j < src1Size + src2Size)
18530b57cec5SDimitry Andric           Dest.AggregateVal[i].IntVal = Src2.AggregateVal[j-src1Size].IntVal;
18540b57cec5SDimitry Andric         else
18550b57cec5SDimitry Andric           // The selector may not be greater than sum of lengths of first and
18560b57cec5SDimitry Andric           // second operands and llasm should not allow situation like
18570b57cec5SDimitry Andric           // %tmp = shufflevector <2 x i32> <i32 3, i32 4>, <2 x i32> undef,
18580b57cec5SDimitry Andric           //                      <2 x i32> < i32 0, i32 5 >,
18590b57cec5SDimitry Andric           // where i32 5 is invalid, but let it be additional check here:
18600b57cec5SDimitry Andric           llvm_unreachable("Invalid mask in shufflevector instruction");
18610b57cec5SDimitry Andric       }
18620b57cec5SDimitry Andric       break;
18630b57cec5SDimitry Andric     case Type::FloatTyID:
18640b57cec5SDimitry Andric       for( unsigned i=0; i<src3Size; i++) {
18655ffd83dbSDimitry Andric         unsigned j = std::max(0, I.getMaskValue(i));
18660b57cec5SDimitry Andric         if(j < src1Size)
18670b57cec5SDimitry Andric           Dest.AggregateVal[i].FloatVal = Src1.AggregateVal[j].FloatVal;
18680b57cec5SDimitry Andric         else if(j < src1Size + src2Size)
18690b57cec5SDimitry Andric           Dest.AggregateVal[i].FloatVal = Src2.AggregateVal[j-src1Size].FloatVal;
18700b57cec5SDimitry Andric         else
18710b57cec5SDimitry Andric           llvm_unreachable("Invalid mask in shufflevector instruction");
18720b57cec5SDimitry Andric         }
18730b57cec5SDimitry Andric       break;
18740b57cec5SDimitry Andric     case Type::DoubleTyID:
18750b57cec5SDimitry Andric       for( unsigned i=0; i<src3Size; i++) {
18765ffd83dbSDimitry Andric         unsigned j = std::max(0, I.getMaskValue(i));
18770b57cec5SDimitry Andric         if(j < src1Size)
18780b57cec5SDimitry Andric           Dest.AggregateVal[i].DoubleVal = Src1.AggregateVal[j].DoubleVal;
18790b57cec5SDimitry Andric         else if(j < src1Size + src2Size)
18800b57cec5SDimitry Andric           Dest.AggregateVal[i].DoubleVal =
18810b57cec5SDimitry Andric             Src2.AggregateVal[j-src1Size].DoubleVal;
18820b57cec5SDimitry Andric         else
18830b57cec5SDimitry Andric           llvm_unreachable("Invalid mask in shufflevector instruction");
18840b57cec5SDimitry Andric       }
18850b57cec5SDimitry Andric       break;
18860b57cec5SDimitry Andric   }
18870b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
visitExtractValueInst(ExtractValueInst & I)18900b57cec5SDimitry Andric void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
18910b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
18920b57cec5SDimitry Andric   Value *Agg = I.getAggregateOperand();
18930b57cec5SDimitry Andric   GenericValue Dest;
18940b57cec5SDimitry Andric   GenericValue Src = getOperandValue(Agg, SF);
18950b57cec5SDimitry Andric 
18960b57cec5SDimitry Andric   ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
18970b57cec5SDimitry Andric   unsigned Num = I.getNumIndices();
18980b57cec5SDimitry Andric   GenericValue *pSrc = &Src;
18990b57cec5SDimitry Andric 
19000b57cec5SDimitry Andric   for (unsigned i = 0 ; i < Num; ++i) {
19010b57cec5SDimitry Andric     pSrc = &pSrc->AggregateVal[*IdxBegin];
19020b57cec5SDimitry Andric     ++IdxBegin;
19030b57cec5SDimitry Andric   }
19040b57cec5SDimitry Andric 
19050b57cec5SDimitry Andric   Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
19060b57cec5SDimitry Andric   switch (IndexedType->getTypeID()) {
19070b57cec5SDimitry Andric     default:
19080b57cec5SDimitry Andric       llvm_unreachable("Unhandled dest type for extractelement instruction");
19090b57cec5SDimitry Andric     break;
19100b57cec5SDimitry Andric     case Type::IntegerTyID:
19110b57cec5SDimitry Andric       Dest.IntVal = pSrc->IntVal;
19120b57cec5SDimitry Andric     break;
19130b57cec5SDimitry Andric     case Type::FloatTyID:
19140b57cec5SDimitry Andric       Dest.FloatVal = pSrc->FloatVal;
19150b57cec5SDimitry Andric     break;
19160b57cec5SDimitry Andric     case Type::DoubleTyID:
19170b57cec5SDimitry Andric       Dest.DoubleVal = pSrc->DoubleVal;
19180b57cec5SDimitry Andric     break;
19190b57cec5SDimitry Andric     case Type::ArrayTyID:
19200b57cec5SDimitry Andric     case Type::StructTyID:
19215ffd83dbSDimitry Andric     case Type::FixedVectorTyID:
19225ffd83dbSDimitry Andric     case Type::ScalableVectorTyID:
19230b57cec5SDimitry Andric       Dest.AggregateVal = pSrc->AggregateVal;
19240b57cec5SDimitry Andric     break;
19250b57cec5SDimitry Andric     case Type::PointerTyID:
19260b57cec5SDimitry Andric       Dest.PointerVal = pSrc->PointerVal;
19270b57cec5SDimitry Andric     break;
19280b57cec5SDimitry Andric   }
19290b57cec5SDimitry Andric 
19300b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
19310b57cec5SDimitry Andric }
19320b57cec5SDimitry Andric 
visitInsertValueInst(InsertValueInst & I)19330b57cec5SDimitry Andric void Interpreter::visitInsertValueInst(InsertValueInst &I) {
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric   ExecutionContext &SF = ECStack.back();
19360b57cec5SDimitry Andric   Value *Agg = I.getAggregateOperand();
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric   GenericValue Src1 = getOperandValue(Agg, SF);
19390b57cec5SDimitry Andric   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
19400b57cec5SDimitry Andric   GenericValue Dest = Src1; // Dest is a slightly changed Src1
19410b57cec5SDimitry Andric 
19420b57cec5SDimitry Andric   ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
19430b57cec5SDimitry Andric   unsigned Num = I.getNumIndices();
19440b57cec5SDimitry Andric 
19450b57cec5SDimitry Andric   GenericValue *pDest = &Dest;
19460b57cec5SDimitry Andric   for (unsigned i = 0 ; i < Num; ++i) {
19470b57cec5SDimitry Andric     pDest = &pDest->AggregateVal[*IdxBegin];
19480b57cec5SDimitry Andric     ++IdxBegin;
19490b57cec5SDimitry Andric   }
19500b57cec5SDimitry Andric   // pDest points to the target value in the Dest now
19510b57cec5SDimitry Andric 
19520b57cec5SDimitry Andric   Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric   switch (IndexedType->getTypeID()) {
19550b57cec5SDimitry Andric     default:
19560b57cec5SDimitry Andric       llvm_unreachable("Unhandled dest type for insertelement instruction");
19570b57cec5SDimitry Andric     break;
19580b57cec5SDimitry Andric     case Type::IntegerTyID:
19590b57cec5SDimitry Andric       pDest->IntVal = Src2.IntVal;
19600b57cec5SDimitry Andric     break;
19610b57cec5SDimitry Andric     case Type::FloatTyID:
19620b57cec5SDimitry Andric       pDest->FloatVal = Src2.FloatVal;
19630b57cec5SDimitry Andric     break;
19640b57cec5SDimitry Andric     case Type::DoubleTyID:
19650b57cec5SDimitry Andric       pDest->DoubleVal = Src2.DoubleVal;
19660b57cec5SDimitry Andric     break;
19670b57cec5SDimitry Andric     case Type::ArrayTyID:
19680b57cec5SDimitry Andric     case Type::StructTyID:
19695ffd83dbSDimitry Andric     case Type::FixedVectorTyID:
19705ffd83dbSDimitry Andric     case Type::ScalableVectorTyID:
19710b57cec5SDimitry Andric       pDest->AggregateVal = Src2.AggregateVal;
19720b57cec5SDimitry Andric     break;
19730b57cec5SDimitry Andric     case Type::PointerTyID:
19740b57cec5SDimitry Andric       pDest->PointerVal = Src2.PointerVal;
19750b57cec5SDimitry Andric     break;
19760b57cec5SDimitry Andric   }
19770b57cec5SDimitry Andric 
19780b57cec5SDimitry Andric   SetValue(&I, Dest, SF);
19790b57cec5SDimitry Andric }
19800b57cec5SDimitry Andric 
getConstantExprValue(ConstantExpr * CE,ExecutionContext & SF)19810b57cec5SDimitry Andric GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
19820b57cec5SDimitry Andric                                                 ExecutionContext &SF) {
19830b57cec5SDimitry Andric   switch (CE->getOpcode()) {
19840b57cec5SDimitry Andric   case Instruction::Trunc:
19850b57cec5SDimitry Andric       return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
19860b57cec5SDimitry Andric   case Instruction::PtrToInt:
19870b57cec5SDimitry Andric       return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
19880b57cec5SDimitry Andric   case Instruction::IntToPtr:
19890b57cec5SDimitry Andric       return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
19900b57cec5SDimitry Andric   case Instruction::BitCast:
19910b57cec5SDimitry Andric       return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
19920b57cec5SDimitry Andric   case Instruction::GetElementPtr:
19930b57cec5SDimitry Andric     return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
19940b57cec5SDimitry Andric                                gep_type_end(CE), SF);
19950b57cec5SDimitry Andric     break;
19960b57cec5SDimitry Andric   }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric   // The cases below here require a GenericValue parameter for the result
19990b57cec5SDimitry Andric   // so we initialize one, compute it and then return it.
20000b57cec5SDimitry Andric   GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
20010b57cec5SDimitry Andric   GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
20020b57cec5SDimitry Andric   GenericValue Dest;
20030b57cec5SDimitry Andric   switch (CE->getOpcode()) {
20040b57cec5SDimitry Andric   case Instruction::Add:  Dest.IntVal = Op0.IntVal + Op1.IntVal; break;
20050b57cec5SDimitry Andric   case Instruction::Sub:  Dest.IntVal = Op0.IntVal - Op1.IntVal; break;
20060b57cec5SDimitry Andric   case Instruction::Mul:  Dest.IntVal = Op0.IntVal * Op1.IntVal; break;
20070b57cec5SDimitry Andric   case Instruction::Xor:  Dest.IntVal = Op0.IntVal ^ Op1.IntVal; break;
20080b57cec5SDimitry Andric   case Instruction::Shl:
20090b57cec5SDimitry Andric     Dest.IntVal = Op0.IntVal.shl(Op1.IntVal.getZExtValue());
20100b57cec5SDimitry Andric     break;
20110b57cec5SDimitry Andric   default:
20120b57cec5SDimitry Andric     dbgs() << "Unhandled ConstantExpr: " << *CE << "\n";
20130b57cec5SDimitry Andric     llvm_unreachable("Unhandled ConstantExpr");
20140b57cec5SDimitry Andric   }
20150b57cec5SDimitry Andric   return Dest;
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric 
getOperandValue(Value * V,ExecutionContext & SF)20180b57cec5SDimitry Andric GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
20190b57cec5SDimitry Andric   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
20200b57cec5SDimitry Andric     return getConstantExprValue(CE, SF);
20210b57cec5SDimitry Andric   } else if (Constant *CPV = dyn_cast<Constant>(V)) {
20220b57cec5SDimitry Andric     return getConstantValue(CPV);
20230b57cec5SDimitry Andric   } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
20240b57cec5SDimitry Andric     return PTOGV(getPointerToGlobal(GV));
20250b57cec5SDimitry Andric   } else {
20260b57cec5SDimitry Andric     return SF.Values[V];
20270b57cec5SDimitry Andric   }
20280b57cec5SDimitry Andric }
20290b57cec5SDimitry Andric 
20300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
20310b57cec5SDimitry Andric //                        Dispatch and Execution Code
20320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
20350b57cec5SDimitry Andric // callFunction - Execute the specified function...
20360b57cec5SDimitry Andric //
callFunction(Function * F,ArrayRef<GenericValue> ArgVals)20370b57cec5SDimitry Andric void Interpreter::callFunction(Function *F, ArrayRef<GenericValue> ArgVals) {
20385ffd83dbSDimitry Andric   assert((ECStack.empty() || !ECStack.back().Caller ||
20395ffd83dbSDimitry Andric           ECStack.back().Caller->arg_size() == ArgVals.size()) &&
20400b57cec5SDimitry Andric          "Incorrect number of arguments passed into function call!");
20410b57cec5SDimitry Andric   // Make a new stack frame... and fill it in.
20420b57cec5SDimitry Andric   ECStack.emplace_back();
20430b57cec5SDimitry Andric   ExecutionContext &StackFrame = ECStack.back();
20440b57cec5SDimitry Andric   StackFrame.CurFunction = F;
20450b57cec5SDimitry Andric 
20460b57cec5SDimitry Andric   // Special handling for external functions.
20470b57cec5SDimitry Andric   if (F->isDeclaration()) {
20480b57cec5SDimitry Andric     GenericValue Result = callExternalFunction (F, ArgVals);
20490b57cec5SDimitry Andric     // Simulate a 'ret' instruction of the appropriate type.
20500b57cec5SDimitry Andric     popStackAndReturnValueToCaller (F->getReturnType (), Result);
20510b57cec5SDimitry Andric     return;
20520b57cec5SDimitry Andric   }
20530b57cec5SDimitry Andric 
20540b57cec5SDimitry Andric   // Get pointers to first LLVM BB & Instruction in function.
20550b57cec5SDimitry Andric   StackFrame.CurBB     = &F->front();
20560b57cec5SDimitry Andric   StackFrame.CurInst   = StackFrame.CurBB->begin();
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric   // Run through the function arguments and initialize their values...
20590b57cec5SDimitry Andric   assert((ArgVals.size() == F->arg_size() ||
20600b57cec5SDimitry Andric          (ArgVals.size() > F->arg_size() && F->getFunctionType()->isVarArg()))&&
20610b57cec5SDimitry Andric          "Invalid number of values passed to function invocation!");
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric   // Handle non-varargs arguments...
20640b57cec5SDimitry Andric   unsigned i = 0;
20650b57cec5SDimitry Andric   for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
20660b57cec5SDimitry Andric        AI != E; ++AI, ++i)
20670b57cec5SDimitry Andric     SetValue(&*AI, ArgVals[i], StackFrame);
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric   // Handle varargs arguments...
20700b57cec5SDimitry Andric   StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end());
20710b57cec5SDimitry Andric }
20720b57cec5SDimitry Andric 
20730b57cec5SDimitry Andric 
run()20740b57cec5SDimitry Andric void Interpreter::run() {
20750b57cec5SDimitry Andric   while (!ECStack.empty()) {
20760b57cec5SDimitry Andric     // Interpret a single instruction & increment the "PC".
20770b57cec5SDimitry Andric     ExecutionContext &SF = ECStack.back();  // Current stack frame
20780b57cec5SDimitry Andric     Instruction &I = *SF.CurInst++;         // Increment before execute
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric     // Track the number of dynamic instructions executed.
20810b57cec5SDimitry Andric     ++NumDynamicInsts;
20820b57cec5SDimitry Andric 
20830b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "About to interpret: " << I << "\n");
20840b57cec5SDimitry Andric     visit(I);   // Dispatch to one of the visit* methods...
20850b57cec5SDimitry Andric   }
20860b57cec5SDimitry Andric }
2087