17330f729Sjoerg //===-- Execution.cpp - Implement code to simulate the program ------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file contains the actual instruction interpreter.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "Interpreter.h"
147330f729Sjoerg #include "llvm/ADT/APInt.h"
157330f729Sjoerg #include "llvm/ADT/Statistic.h"
167330f729Sjoerg #include "llvm/CodeGen/IntrinsicLowering.h"
177330f729Sjoerg #include "llvm/IR/Constants.h"
187330f729Sjoerg #include "llvm/IR/DerivedTypes.h"
197330f729Sjoerg #include "llvm/IR/GetElementPtrTypeIterator.h"
207330f729Sjoerg #include "llvm/IR/Instructions.h"
217330f729Sjoerg #include "llvm/Support/CommandLine.h"
227330f729Sjoerg #include "llvm/Support/Debug.h"
237330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
247330f729Sjoerg #include "llvm/Support/MathExtras.h"
257330f729Sjoerg #include "llvm/Support/raw_ostream.h"
267330f729Sjoerg #include <algorithm>
277330f729Sjoerg #include <cmath>
287330f729Sjoerg using namespace llvm;
297330f729Sjoerg
307330f729Sjoerg #define DEBUG_TYPE "interpreter"
317330f729Sjoerg
327330f729Sjoerg STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
337330f729Sjoerg
347330f729Sjoerg static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
357330f729Sjoerg cl::desc("make the interpreter print every volatile load and store"));
367330f729Sjoerg
377330f729Sjoerg //===----------------------------------------------------------------------===//
387330f729Sjoerg // Various Helper Functions
397330f729Sjoerg //===----------------------------------------------------------------------===//
407330f729Sjoerg
SetValue(Value * V,GenericValue Val,ExecutionContext & SF)417330f729Sjoerg static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
427330f729Sjoerg SF.Values[V] = Val;
437330f729Sjoerg }
447330f729Sjoerg
457330f729Sjoerg //===----------------------------------------------------------------------===//
467330f729Sjoerg // Unary Instruction Implementations
477330f729Sjoerg //===----------------------------------------------------------------------===//
487330f729Sjoerg
executeFNegInst(GenericValue & Dest,GenericValue Src,Type * Ty)497330f729Sjoerg static void executeFNegInst(GenericValue &Dest, GenericValue Src, Type *Ty) {
507330f729Sjoerg switch (Ty->getTypeID()) {
517330f729Sjoerg case Type::FloatTyID:
527330f729Sjoerg Dest.FloatVal = -Src.FloatVal;
537330f729Sjoerg break;
547330f729Sjoerg case Type::DoubleTyID:
557330f729Sjoerg Dest.DoubleVal = -Src.DoubleVal;
567330f729Sjoerg break;
577330f729Sjoerg default:
587330f729Sjoerg llvm_unreachable("Unhandled type for FNeg instruction");
597330f729Sjoerg }
607330f729Sjoerg }
617330f729Sjoerg
visitUnaryOperator(UnaryOperator & I)627330f729Sjoerg void Interpreter::visitUnaryOperator(UnaryOperator &I) {
637330f729Sjoerg ExecutionContext &SF = ECStack.back();
647330f729Sjoerg Type *Ty = I.getOperand(0)->getType();
657330f729Sjoerg GenericValue Src = getOperandValue(I.getOperand(0), SF);
667330f729Sjoerg GenericValue R; // Result
677330f729Sjoerg
687330f729Sjoerg // First process vector operation
697330f729Sjoerg if (Ty->isVectorTy()) {
707330f729Sjoerg R.AggregateVal.resize(Src.AggregateVal.size());
717330f729Sjoerg
727330f729Sjoerg switch(I.getOpcode()) {
737330f729Sjoerg default:
747330f729Sjoerg llvm_unreachable("Don't know how to handle this unary operator");
757330f729Sjoerg break;
767330f729Sjoerg case Instruction::FNeg:
777330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
787330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
797330f729Sjoerg R.AggregateVal[i].FloatVal = -Src.AggregateVal[i].FloatVal;
807330f729Sjoerg } else if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) {
817330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
827330f729Sjoerg R.AggregateVal[i].DoubleVal = -Src.AggregateVal[i].DoubleVal;
837330f729Sjoerg } else {
847330f729Sjoerg llvm_unreachable("Unhandled type for FNeg instruction");
857330f729Sjoerg }
867330f729Sjoerg break;
877330f729Sjoerg }
887330f729Sjoerg } else {
897330f729Sjoerg switch (I.getOpcode()) {
907330f729Sjoerg default:
917330f729Sjoerg llvm_unreachable("Don't know how to handle this unary operator");
927330f729Sjoerg break;
937330f729Sjoerg case Instruction::FNeg: executeFNegInst(R, Src, Ty); break;
947330f729Sjoerg }
957330f729Sjoerg }
967330f729Sjoerg SetValue(&I, R, SF);
977330f729Sjoerg }
987330f729Sjoerg
997330f729Sjoerg //===----------------------------------------------------------------------===//
1007330f729Sjoerg // Binary Instruction Implementations
1017330f729Sjoerg //===----------------------------------------------------------------------===//
1027330f729Sjoerg
1037330f729Sjoerg #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
1047330f729Sjoerg case Type::TY##TyID: \
1057330f729Sjoerg Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
1067330f729Sjoerg break
1077330f729Sjoerg
executeFAddInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1087330f729Sjoerg static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
1097330f729Sjoerg GenericValue Src2, Type *Ty) {
1107330f729Sjoerg switch (Ty->getTypeID()) {
1117330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(+, Float);
1127330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(+, Double);
1137330f729Sjoerg default:
1147330f729Sjoerg dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
1157330f729Sjoerg llvm_unreachable(nullptr);
1167330f729Sjoerg }
1177330f729Sjoerg }
1187330f729Sjoerg
executeFSubInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1197330f729Sjoerg static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
1207330f729Sjoerg GenericValue Src2, Type *Ty) {
1217330f729Sjoerg switch (Ty->getTypeID()) {
1227330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(-, Float);
1237330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(-, Double);
1247330f729Sjoerg default:
1257330f729Sjoerg dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
1267330f729Sjoerg llvm_unreachable(nullptr);
1277330f729Sjoerg }
1287330f729Sjoerg }
1297330f729Sjoerg
executeFMulInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1307330f729Sjoerg static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
1317330f729Sjoerg GenericValue Src2, Type *Ty) {
1327330f729Sjoerg switch (Ty->getTypeID()) {
1337330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(*, Float);
1347330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(*, Double);
1357330f729Sjoerg default:
1367330f729Sjoerg dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
1377330f729Sjoerg llvm_unreachable(nullptr);
1387330f729Sjoerg }
1397330f729Sjoerg }
1407330f729Sjoerg
executeFDivInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1417330f729Sjoerg static void executeFDivInst(GenericValue &Dest, GenericValue Src1,
1427330f729Sjoerg GenericValue Src2, Type *Ty) {
1437330f729Sjoerg switch (Ty->getTypeID()) {
1447330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(/, Float);
1457330f729Sjoerg IMPLEMENT_BINARY_OPERATOR(/, Double);
1467330f729Sjoerg default:
1477330f729Sjoerg dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
1487330f729Sjoerg llvm_unreachable(nullptr);
1497330f729Sjoerg }
1507330f729Sjoerg }
1517330f729Sjoerg
executeFRemInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)1527330f729Sjoerg static void executeFRemInst(GenericValue &Dest, GenericValue Src1,
1537330f729Sjoerg GenericValue Src2, Type *Ty) {
1547330f729Sjoerg switch (Ty->getTypeID()) {
1557330f729Sjoerg case Type::FloatTyID:
1567330f729Sjoerg Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal);
1577330f729Sjoerg break;
1587330f729Sjoerg case Type::DoubleTyID:
1597330f729Sjoerg Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal);
1607330f729Sjoerg break;
1617330f729Sjoerg default:
1627330f729Sjoerg dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
1637330f729Sjoerg llvm_unreachable(nullptr);
1647330f729Sjoerg }
1657330f729Sjoerg }
1667330f729Sjoerg
1677330f729Sjoerg #define IMPLEMENT_INTEGER_ICMP(OP, TY) \
1687330f729Sjoerg case Type::IntegerTyID: \
1697330f729Sjoerg Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \
1707330f729Sjoerg break;
1717330f729Sjoerg
1727330f729Sjoerg #define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY) \
173*82d56013Sjoerg case Type::FixedVectorTyID: \
174*82d56013Sjoerg case Type::ScalableVectorTyID: { \
1757330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
1767330f729Sjoerg Dest.AggregateVal.resize(Src1.AggregateVal.size()); \
1777330f729Sjoerg for (uint32_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
178*82d56013Sjoerg Dest.AggregateVal[_i].IntVal = APInt( \
179*82d56013Sjoerg 1, Src1.AggregateVal[_i].IntVal.OP(Src2.AggregateVal[_i].IntVal)); \
1807330f729Sjoerg } break;
1817330f729Sjoerg
1827330f729Sjoerg // Handle pointers specially because they must be compared with only as much
1837330f729Sjoerg // width as the host has. We _do not_ want to be comparing 64 bit values when
1847330f729Sjoerg // running on a 32-bit target, otherwise the upper 32 bits might mess up
1857330f729Sjoerg // comparisons if they contain garbage.
1867330f729Sjoerg #define IMPLEMENT_POINTER_ICMP(OP) \
1877330f729Sjoerg case Type::PointerTyID: \
1887330f729Sjoerg Dest.IntVal = APInt(1,(void*)(intptr_t)Src1.PointerVal OP \
1897330f729Sjoerg (void*)(intptr_t)Src2.PointerVal); \
1907330f729Sjoerg break;
1917330f729Sjoerg
executeICMP_EQ(GenericValue Src1,GenericValue Src2,Type * Ty)1927330f729Sjoerg static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
1937330f729Sjoerg Type *Ty) {
1947330f729Sjoerg GenericValue Dest;
1957330f729Sjoerg switch (Ty->getTypeID()) {
1967330f729Sjoerg IMPLEMENT_INTEGER_ICMP(eq,Ty);
1977330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(eq,Ty);
1987330f729Sjoerg IMPLEMENT_POINTER_ICMP(==);
1997330f729Sjoerg default:
2007330f729Sjoerg dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
2017330f729Sjoerg llvm_unreachable(nullptr);
2027330f729Sjoerg }
2037330f729Sjoerg return Dest;
2047330f729Sjoerg }
2057330f729Sjoerg
executeICMP_NE(GenericValue Src1,GenericValue Src2,Type * Ty)2067330f729Sjoerg static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
2077330f729Sjoerg Type *Ty) {
2087330f729Sjoerg GenericValue Dest;
2097330f729Sjoerg switch (Ty->getTypeID()) {
2107330f729Sjoerg IMPLEMENT_INTEGER_ICMP(ne,Ty);
2117330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(ne,Ty);
2127330f729Sjoerg IMPLEMENT_POINTER_ICMP(!=);
2137330f729Sjoerg default:
2147330f729Sjoerg dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
2157330f729Sjoerg llvm_unreachable(nullptr);
2167330f729Sjoerg }
2177330f729Sjoerg return Dest;
2187330f729Sjoerg }
2197330f729Sjoerg
executeICMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)2207330f729Sjoerg static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
2217330f729Sjoerg Type *Ty) {
2227330f729Sjoerg GenericValue Dest;
2237330f729Sjoerg switch (Ty->getTypeID()) {
2247330f729Sjoerg IMPLEMENT_INTEGER_ICMP(ult,Ty);
2257330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(ult,Ty);
2267330f729Sjoerg IMPLEMENT_POINTER_ICMP(<);
2277330f729Sjoerg default:
2287330f729Sjoerg dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
2297330f729Sjoerg llvm_unreachable(nullptr);
2307330f729Sjoerg }
2317330f729Sjoerg return Dest;
2327330f729Sjoerg }
2337330f729Sjoerg
executeICMP_SLT(GenericValue Src1,GenericValue Src2,Type * Ty)2347330f729Sjoerg static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
2357330f729Sjoerg Type *Ty) {
2367330f729Sjoerg GenericValue Dest;
2377330f729Sjoerg switch (Ty->getTypeID()) {
2387330f729Sjoerg IMPLEMENT_INTEGER_ICMP(slt,Ty);
2397330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(slt,Ty);
2407330f729Sjoerg IMPLEMENT_POINTER_ICMP(<);
2417330f729Sjoerg default:
2427330f729Sjoerg dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
2437330f729Sjoerg llvm_unreachable(nullptr);
2447330f729Sjoerg }
2457330f729Sjoerg return Dest;
2467330f729Sjoerg }
2477330f729Sjoerg
executeICMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)2487330f729Sjoerg static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
2497330f729Sjoerg Type *Ty) {
2507330f729Sjoerg GenericValue Dest;
2517330f729Sjoerg switch (Ty->getTypeID()) {
2527330f729Sjoerg IMPLEMENT_INTEGER_ICMP(ugt,Ty);
2537330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(ugt,Ty);
2547330f729Sjoerg IMPLEMENT_POINTER_ICMP(>);
2557330f729Sjoerg default:
2567330f729Sjoerg dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
2577330f729Sjoerg llvm_unreachable(nullptr);
2587330f729Sjoerg }
2597330f729Sjoerg return Dest;
2607330f729Sjoerg }
2617330f729Sjoerg
executeICMP_SGT(GenericValue Src1,GenericValue Src2,Type * Ty)2627330f729Sjoerg static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
2637330f729Sjoerg Type *Ty) {
2647330f729Sjoerg GenericValue Dest;
2657330f729Sjoerg switch (Ty->getTypeID()) {
2667330f729Sjoerg IMPLEMENT_INTEGER_ICMP(sgt,Ty);
2677330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(sgt,Ty);
2687330f729Sjoerg IMPLEMENT_POINTER_ICMP(>);
2697330f729Sjoerg default:
2707330f729Sjoerg dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
2717330f729Sjoerg llvm_unreachable(nullptr);
2727330f729Sjoerg }
2737330f729Sjoerg return Dest;
2747330f729Sjoerg }
2757330f729Sjoerg
executeICMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)2767330f729Sjoerg static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
2777330f729Sjoerg Type *Ty) {
2787330f729Sjoerg GenericValue Dest;
2797330f729Sjoerg switch (Ty->getTypeID()) {
2807330f729Sjoerg IMPLEMENT_INTEGER_ICMP(ule,Ty);
2817330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(ule,Ty);
2827330f729Sjoerg IMPLEMENT_POINTER_ICMP(<=);
2837330f729Sjoerg default:
2847330f729Sjoerg dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
2857330f729Sjoerg llvm_unreachable(nullptr);
2867330f729Sjoerg }
2877330f729Sjoerg return Dest;
2887330f729Sjoerg }
2897330f729Sjoerg
executeICMP_SLE(GenericValue Src1,GenericValue Src2,Type * Ty)2907330f729Sjoerg static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
2917330f729Sjoerg Type *Ty) {
2927330f729Sjoerg GenericValue Dest;
2937330f729Sjoerg switch (Ty->getTypeID()) {
2947330f729Sjoerg IMPLEMENT_INTEGER_ICMP(sle,Ty);
2957330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(sle,Ty);
2967330f729Sjoerg IMPLEMENT_POINTER_ICMP(<=);
2977330f729Sjoerg default:
2987330f729Sjoerg dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
2997330f729Sjoerg llvm_unreachable(nullptr);
3007330f729Sjoerg }
3017330f729Sjoerg return Dest;
3027330f729Sjoerg }
3037330f729Sjoerg
executeICMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)3047330f729Sjoerg static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
3057330f729Sjoerg Type *Ty) {
3067330f729Sjoerg GenericValue Dest;
3077330f729Sjoerg switch (Ty->getTypeID()) {
3087330f729Sjoerg IMPLEMENT_INTEGER_ICMP(uge,Ty);
3097330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(uge,Ty);
3107330f729Sjoerg IMPLEMENT_POINTER_ICMP(>=);
3117330f729Sjoerg default:
3127330f729Sjoerg dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
3137330f729Sjoerg llvm_unreachable(nullptr);
3147330f729Sjoerg }
3157330f729Sjoerg return Dest;
3167330f729Sjoerg }
3177330f729Sjoerg
executeICMP_SGE(GenericValue Src1,GenericValue Src2,Type * Ty)3187330f729Sjoerg static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
3197330f729Sjoerg Type *Ty) {
3207330f729Sjoerg GenericValue Dest;
3217330f729Sjoerg switch (Ty->getTypeID()) {
3227330f729Sjoerg IMPLEMENT_INTEGER_ICMP(sge,Ty);
3237330f729Sjoerg IMPLEMENT_VECTOR_INTEGER_ICMP(sge,Ty);
3247330f729Sjoerg IMPLEMENT_POINTER_ICMP(>=);
3257330f729Sjoerg default:
3267330f729Sjoerg dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
3277330f729Sjoerg llvm_unreachable(nullptr);
3287330f729Sjoerg }
3297330f729Sjoerg return Dest;
3307330f729Sjoerg }
3317330f729Sjoerg
visitICmpInst(ICmpInst & I)3327330f729Sjoerg void Interpreter::visitICmpInst(ICmpInst &I) {
3337330f729Sjoerg ExecutionContext &SF = ECStack.back();
3347330f729Sjoerg Type *Ty = I.getOperand(0)->getType();
3357330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
3367330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
3377330f729Sjoerg GenericValue R; // Result
3387330f729Sjoerg
3397330f729Sjoerg switch (I.getPredicate()) {
3407330f729Sjoerg case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
3417330f729Sjoerg case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
3427330f729Sjoerg case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
3437330f729Sjoerg case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
3447330f729Sjoerg case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
3457330f729Sjoerg case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
3467330f729Sjoerg case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
3477330f729Sjoerg case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
3487330f729Sjoerg case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
3497330f729Sjoerg case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
3507330f729Sjoerg default:
3517330f729Sjoerg dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
3527330f729Sjoerg llvm_unreachable(nullptr);
3537330f729Sjoerg }
3547330f729Sjoerg
3557330f729Sjoerg SetValue(&I, R, SF);
3567330f729Sjoerg }
3577330f729Sjoerg
3587330f729Sjoerg #define IMPLEMENT_FCMP(OP, TY) \
3597330f729Sjoerg case Type::TY##TyID: \
3607330f729Sjoerg Dest.IntVal = APInt(1,Src1.TY##Val OP Src2.TY##Val); \
3617330f729Sjoerg break
3627330f729Sjoerg
3637330f729Sjoerg #define IMPLEMENT_VECTOR_FCMP_T(OP, TY) \
3647330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
3657330f729Sjoerg Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
3667330f729Sjoerg for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
3677330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1, \
3687330f729Sjoerg Src1.AggregateVal[_i].TY##Val OP Src2.AggregateVal[_i].TY##Val);\
3697330f729Sjoerg break;
3707330f729Sjoerg
3717330f729Sjoerg #define IMPLEMENT_VECTOR_FCMP(OP) \
372*82d56013Sjoerg case Type::FixedVectorTyID: \
373*82d56013Sjoerg case Type::ScalableVectorTyID: \
3747330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
3757330f729Sjoerg IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
3767330f729Sjoerg } else { \
3777330f729Sjoerg IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
3787330f729Sjoerg }
3797330f729Sjoerg
executeFCMP_OEQ(GenericValue Src1,GenericValue Src2,Type * Ty)3807330f729Sjoerg static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
3817330f729Sjoerg Type *Ty) {
3827330f729Sjoerg GenericValue Dest;
3837330f729Sjoerg switch (Ty->getTypeID()) {
3847330f729Sjoerg IMPLEMENT_FCMP(==, Float);
3857330f729Sjoerg IMPLEMENT_FCMP(==, Double);
3867330f729Sjoerg IMPLEMENT_VECTOR_FCMP(==);
3877330f729Sjoerg default:
3887330f729Sjoerg dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
3897330f729Sjoerg llvm_unreachable(nullptr);
3907330f729Sjoerg }
3917330f729Sjoerg return Dest;
3927330f729Sjoerg }
3937330f729Sjoerg
3947330f729Sjoerg #define IMPLEMENT_SCALAR_NANS(TY, X,Y) \
3957330f729Sjoerg if (TY->isFloatTy()) { \
3967330f729Sjoerg if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
3977330f729Sjoerg Dest.IntVal = APInt(1,false); \
3987330f729Sjoerg return Dest; \
3997330f729Sjoerg } \
4007330f729Sjoerg } else { \
4017330f729Sjoerg if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
4027330f729Sjoerg Dest.IntVal = APInt(1,false); \
4037330f729Sjoerg return Dest; \
4047330f729Sjoerg } \
4057330f729Sjoerg }
4067330f729Sjoerg
4077330f729Sjoerg #define MASK_VECTOR_NANS_T(X,Y, TZ, FLAG) \
4087330f729Sjoerg assert(X.AggregateVal.size() == Y.AggregateVal.size()); \
4097330f729Sjoerg Dest.AggregateVal.resize( X.AggregateVal.size() ); \
4107330f729Sjoerg for( uint32_t _i=0;_i<X.AggregateVal.size();_i++) { \
4117330f729Sjoerg if (X.AggregateVal[_i].TZ##Val != X.AggregateVal[_i].TZ##Val || \
4127330f729Sjoerg Y.AggregateVal[_i].TZ##Val != Y.AggregateVal[_i].TZ##Val) \
4137330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,FLAG); \
4147330f729Sjoerg else { \
4157330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,!FLAG); \
4167330f729Sjoerg } \
4177330f729Sjoerg }
4187330f729Sjoerg
4197330f729Sjoerg #define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
4207330f729Sjoerg if (TY->isVectorTy()) { \
4217330f729Sjoerg if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
4227330f729Sjoerg MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
4237330f729Sjoerg } else { \
4247330f729Sjoerg MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
4257330f729Sjoerg } \
4267330f729Sjoerg } \
4277330f729Sjoerg
4287330f729Sjoerg
4297330f729Sjoerg
executeFCMP_ONE(GenericValue Src1,GenericValue Src2,Type * Ty)4307330f729Sjoerg static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
4317330f729Sjoerg Type *Ty)
4327330f729Sjoerg {
4337330f729Sjoerg GenericValue Dest;
4347330f729Sjoerg // if input is scalar value and Src1 or Src2 is NaN return false
4357330f729Sjoerg IMPLEMENT_SCALAR_NANS(Ty, Src1, Src2)
4367330f729Sjoerg // if vector input detect NaNs and fill mask
4377330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, false)
4387330f729Sjoerg GenericValue DestMask = Dest;
4397330f729Sjoerg switch (Ty->getTypeID()) {
4407330f729Sjoerg IMPLEMENT_FCMP(!=, Float);
4417330f729Sjoerg IMPLEMENT_FCMP(!=, Double);
4427330f729Sjoerg IMPLEMENT_VECTOR_FCMP(!=);
4437330f729Sjoerg default:
4447330f729Sjoerg dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
4457330f729Sjoerg llvm_unreachable(nullptr);
4467330f729Sjoerg }
4477330f729Sjoerg // in vector case mask out NaN elements
4487330f729Sjoerg if (Ty->isVectorTy())
4497330f729Sjoerg for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
4507330f729Sjoerg if (DestMask.AggregateVal[_i].IntVal == false)
4517330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,false);
4527330f729Sjoerg
4537330f729Sjoerg return Dest;
4547330f729Sjoerg }
4557330f729Sjoerg
executeFCMP_OLE(GenericValue Src1,GenericValue Src2,Type * Ty)4567330f729Sjoerg static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
4577330f729Sjoerg Type *Ty) {
4587330f729Sjoerg GenericValue Dest;
4597330f729Sjoerg switch (Ty->getTypeID()) {
4607330f729Sjoerg IMPLEMENT_FCMP(<=, Float);
4617330f729Sjoerg IMPLEMENT_FCMP(<=, Double);
4627330f729Sjoerg IMPLEMENT_VECTOR_FCMP(<=);
4637330f729Sjoerg default:
4647330f729Sjoerg dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
4657330f729Sjoerg llvm_unreachable(nullptr);
4667330f729Sjoerg }
4677330f729Sjoerg return Dest;
4687330f729Sjoerg }
4697330f729Sjoerg
executeFCMP_OGE(GenericValue Src1,GenericValue Src2,Type * Ty)4707330f729Sjoerg static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
4717330f729Sjoerg Type *Ty) {
4727330f729Sjoerg GenericValue Dest;
4737330f729Sjoerg switch (Ty->getTypeID()) {
4747330f729Sjoerg IMPLEMENT_FCMP(>=, Float);
4757330f729Sjoerg IMPLEMENT_FCMP(>=, Double);
4767330f729Sjoerg IMPLEMENT_VECTOR_FCMP(>=);
4777330f729Sjoerg default:
4787330f729Sjoerg dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
4797330f729Sjoerg llvm_unreachable(nullptr);
4807330f729Sjoerg }
4817330f729Sjoerg return Dest;
4827330f729Sjoerg }
4837330f729Sjoerg
executeFCMP_OLT(GenericValue Src1,GenericValue Src2,Type * Ty)4847330f729Sjoerg static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
4857330f729Sjoerg Type *Ty) {
4867330f729Sjoerg GenericValue Dest;
4877330f729Sjoerg switch (Ty->getTypeID()) {
4887330f729Sjoerg IMPLEMENT_FCMP(<, Float);
4897330f729Sjoerg IMPLEMENT_FCMP(<, Double);
4907330f729Sjoerg IMPLEMENT_VECTOR_FCMP(<);
4917330f729Sjoerg default:
4927330f729Sjoerg dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
4937330f729Sjoerg llvm_unreachable(nullptr);
4947330f729Sjoerg }
4957330f729Sjoerg return Dest;
4967330f729Sjoerg }
4977330f729Sjoerg
executeFCMP_OGT(GenericValue Src1,GenericValue Src2,Type * Ty)4987330f729Sjoerg static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
4997330f729Sjoerg Type *Ty) {
5007330f729Sjoerg GenericValue Dest;
5017330f729Sjoerg switch (Ty->getTypeID()) {
5027330f729Sjoerg IMPLEMENT_FCMP(>, Float);
5037330f729Sjoerg IMPLEMENT_FCMP(>, Double);
5047330f729Sjoerg IMPLEMENT_VECTOR_FCMP(>);
5057330f729Sjoerg default:
5067330f729Sjoerg dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
5077330f729Sjoerg llvm_unreachable(nullptr);
5087330f729Sjoerg }
5097330f729Sjoerg return Dest;
5107330f729Sjoerg }
5117330f729Sjoerg
5127330f729Sjoerg #define IMPLEMENT_UNORDERED(TY, X,Y) \
5137330f729Sjoerg if (TY->isFloatTy()) { \
5147330f729Sjoerg if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
5157330f729Sjoerg Dest.IntVal = APInt(1,true); \
5167330f729Sjoerg return Dest; \
5177330f729Sjoerg } \
5187330f729Sjoerg } else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
5197330f729Sjoerg Dest.IntVal = APInt(1,true); \
5207330f729Sjoerg return Dest; \
5217330f729Sjoerg }
5227330f729Sjoerg
5237330f729Sjoerg #define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
5247330f729Sjoerg if (TY->isVectorTy()) { \
5257330f729Sjoerg GenericValue DestMask = Dest; \
5267330f729Sjoerg Dest = FUNC(Src1, Src2, Ty); \
5277330f729Sjoerg for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
5287330f729Sjoerg if (DestMask.AggregateVal[_i].IntVal == true) \
5297330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1, true); \
5307330f729Sjoerg return Dest; \
5317330f729Sjoerg }
5327330f729Sjoerg
executeFCMP_UEQ(GenericValue Src1,GenericValue Src2,Type * Ty)5337330f729Sjoerg static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
5347330f729Sjoerg Type *Ty) {
5357330f729Sjoerg GenericValue Dest;
5367330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5377330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5387330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OEQ)
5397330f729Sjoerg return executeFCMP_OEQ(Src1, Src2, Ty);
5407330f729Sjoerg
5417330f729Sjoerg }
5427330f729Sjoerg
executeFCMP_UNE(GenericValue Src1,GenericValue Src2,Type * Ty)5437330f729Sjoerg static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2,
5447330f729Sjoerg Type *Ty) {
5457330f729Sjoerg GenericValue Dest;
5467330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5477330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5487330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_ONE)
5497330f729Sjoerg return executeFCMP_ONE(Src1, Src2, Ty);
5507330f729Sjoerg }
5517330f729Sjoerg
executeFCMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)5527330f729Sjoerg static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2,
5537330f729Sjoerg Type *Ty) {
5547330f729Sjoerg GenericValue Dest;
5557330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5567330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5577330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLE)
5587330f729Sjoerg return executeFCMP_OLE(Src1, Src2, Ty);
5597330f729Sjoerg }
5607330f729Sjoerg
executeFCMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)5617330f729Sjoerg static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2,
5627330f729Sjoerg Type *Ty) {
5637330f729Sjoerg GenericValue Dest;
5647330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5657330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5667330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGE)
5677330f729Sjoerg return executeFCMP_OGE(Src1, Src2, Ty);
5687330f729Sjoerg }
5697330f729Sjoerg
executeFCMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)5707330f729Sjoerg static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2,
5717330f729Sjoerg Type *Ty) {
5727330f729Sjoerg GenericValue Dest;
5737330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5747330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5757330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLT)
5767330f729Sjoerg return executeFCMP_OLT(Src1, Src2, Ty);
5777330f729Sjoerg }
5787330f729Sjoerg
executeFCMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)5797330f729Sjoerg static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2,
5807330f729Sjoerg Type *Ty) {
5817330f729Sjoerg GenericValue Dest;
5827330f729Sjoerg IMPLEMENT_UNORDERED(Ty, Src1, Src2)
5837330f729Sjoerg MASK_VECTOR_NANS(Ty, Src1, Src2, true)
5847330f729Sjoerg IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGT)
5857330f729Sjoerg return executeFCMP_OGT(Src1, Src2, Ty);
5867330f729Sjoerg }
5877330f729Sjoerg
executeFCMP_ORD(GenericValue Src1,GenericValue Src2,Type * Ty)5887330f729Sjoerg static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
5897330f729Sjoerg Type *Ty) {
5907330f729Sjoerg GenericValue Dest;
5917330f729Sjoerg if(Ty->isVectorTy()) {
5927330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
5937330f729Sjoerg Dest.AggregateVal.resize( Src1.AggregateVal.size() );
5947330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
5957330f729Sjoerg for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
5967330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,
5977330f729Sjoerg ( (Src1.AggregateVal[_i].FloatVal ==
5987330f729Sjoerg Src1.AggregateVal[_i].FloatVal) &&
5997330f729Sjoerg (Src2.AggregateVal[_i].FloatVal ==
6007330f729Sjoerg Src2.AggregateVal[_i].FloatVal)));
6017330f729Sjoerg } else {
6027330f729Sjoerg for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6037330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,
6047330f729Sjoerg ( (Src1.AggregateVal[_i].DoubleVal ==
6057330f729Sjoerg Src1.AggregateVal[_i].DoubleVal) &&
6067330f729Sjoerg (Src2.AggregateVal[_i].DoubleVal ==
6077330f729Sjoerg Src2.AggregateVal[_i].DoubleVal)));
6087330f729Sjoerg }
6097330f729Sjoerg } else if (Ty->isFloatTy())
6107330f729Sjoerg Dest.IntVal = APInt(1,(Src1.FloatVal == Src1.FloatVal &&
6117330f729Sjoerg Src2.FloatVal == Src2.FloatVal));
6127330f729Sjoerg else {
6137330f729Sjoerg Dest.IntVal = APInt(1,(Src1.DoubleVal == Src1.DoubleVal &&
6147330f729Sjoerg Src2.DoubleVal == Src2.DoubleVal));
6157330f729Sjoerg }
6167330f729Sjoerg return Dest;
6177330f729Sjoerg }
6187330f729Sjoerg
executeFCMP_UNO(GenericValue Src1,GenericValue Src2,Type * Ty)6197330f729Sjoerg static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
6207330f729Sjoerg Type *Ty) {
6217330f729Sjoerg GenericValue Dest;
6227330f729Sjoerg if(Ty->isVectorTy()) {
6237330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
6247330f729Sjoerg Dest.AggregateVal.resize( Src1.AggregateVal.size() );
6257330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
6267330f729Sjoerg for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6277330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,
6287330f729Sjoerg ( (Src1.AggregateVal[_i].FloatVal !=
6297330f729Sjoerg Src1.AggregateVal[_i].FloatVal) ||
6307330f729Sjoerg (Src2.AggregateVal[_i].FloatVal !=
6317330f729Sjoerg Src2.AggregateVal[_i].FloatVal)));
6327330f729Sjoerg } else {
6337330f729Sjoerg for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
6347330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,
6357330f729Sjoerg ( (Src1.AggregateVal[_i].DoubleVal !=
6367330f729Sjoerg Src1.AggregateVal[_i].DoubleVal) ||
6377330f729Sjoerg (Src2.AggregateVal[_i].DoubleVal !=
6387330f729Sjoerg Src2.AggregateVal[_i].DoubleVal)));
6397330f729Sjoerg }
6407330f729Sjoerg } else if (Ty->isFloatTy())
6417330f729Sjoerg Dest.IntVal = APInt(1,(Src1.FloatVal != Src1.FloatVal ||
6427330f729Sjoerg Src2.FloatVal != Src2.FloatVal));
6437330f729Sjoerg else {
6447330f729Sjoerg Dest.IntVal = APInt(1,(Src1.DoubleVal != Src1.DoubleVal ||
6457330f729Sjoerg Src2.DoubleVal != Src2.DoubleVal));
6467330f729Sjoerg }
6477330f729Sjoerg return Dest;
6487330f729Sjoerg }
6497330f729Sjoerg
executeFCMP_BOOL(GenericValue Src1,GenericValue Src2,Type * Ty,const bool val)6507330f729Sjoerg static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2,
6517330f729Sjoerg Type *Ty, const bool val) {
6527330f729Sjoerg GenericValue Dest;
6537330f729Sjoerg if(Ty->isVectorTy()) {
6547330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
6557330f729Sjoerg Dest.AggregateVal.resize( Src1.AggregateVal.size() );
6567330f729Sjoerg for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
6577330f729Sjoerg Dest.AggregateVal[_i].IntVal = APInt(1,val);
6587330f729Sjoerg } else {
6597330f729Sjoerg Dest.IntVal = APInt(1, val);
6607330f729Sjoerg }
6617330f729Sjoerg
6627330f729Sjoerg return Dest;
6637330f729Sjoerg }
6647330f729Sjoerg
visitFCmpInst(FCmpInst & I)6657330f729Sjoerg void Interpreter::visitFCmpInst(FCmpInst &I) {
6667330f729Sjoerg ExecutionContext &SF = ECStack.back();
6677330f729Sjoerg Type *Ty = I.getOperand(0)->getType();
6687330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
6697330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
6707330f729Sjoerg GenericValue R; // Result
6717330f729Sjoerg
6727330f729Sjoerg switch (I.getPredicate()) {
6737330f729Sjoerg default:
6747330f729Sjoerg dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
6757330f729Sjoerg llvm_unreachable(nullptr);
6767330f729Sjoerg break;
6777330f729Sjoerg case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
6787330f729Sjoerg break;
6797330f729Sjoerg case FCmpInst::FCMP_TRUE: R = executeFCMP_BOOL(Src1, Src2, Ty, true);
6807330f729Sjoerg break;
6817330f729Sjoerg case FCmpInst::FCMP_ORD: R = executeFCMP_ORD(Src1, Src2, Ty); break;
6827330f729Sjoerg case FCmpInst::FCMP_UNO: R = executeFCMP_UNO(Src1, Src2, Ty); break;
6837330f729Sjoerg case FCmpInst::FCMP_UEQ: R = executeFCMP_UEQ(Src1, Src2, Ty); break;
6847330f729Sjoerg case FCmpInst::FCMP_OEQ: R = executeFCMP_OEQ(Src1, Src2, Ty); break;
6857330f729Sjoerg case FCmpInst::FCMP_UNE: R = executeFCMP_UNE(Src1, Src2, Ty); break;
6867330f729Sjoerg case FCmpInst::FCMP_ONE: R = executeFCMP_ONE(Src1, Src2, Ty); break;
6877330f729Sjoerg case FCmpInst::FCMP_ULT: R = executeFCMP_ULT(Src1, Src2, Ty); break;
6887330f729Sjoerg case FCmpInst::FCMP_OLT: R = executeFCMP_OLT(Src1, Src2, Ty); break;
6897330f729Sjoerg case FCmpInst::FCMP_UGT: R = executeFCMP_UGT(Src1, Src2, Ty); break;
6907330f729Sjoerg case FCmpInst::FCMP_OGT: R = executeFCMP_OGT(Src1, Src2, Ty); break;
6917330f729Sjoerg case FCmpInst::FCMP_ULE: R = executeFCMP_ULE(Src1, Src2, Ty); break;
6927330f729Sjoerg case FCmpInst::FCMP_OLE: R = executeFCMP_OLE(Src1, Src2, Ty); break;
6937330f729Sjoerg case FCmpInst::FCMP_UGE: R = executeFCMP_UGE(Src1, Src2, Ty); break;
6947330f729Sjoerg case FCmpInst::FCMP_OGE: R = executeFCMP_OGE(Src1, Src2, Ty); break;
6957330f729Sjoerg }
6967330f729Sjoerg
6977330f729Sjoerg SetValue(&I, R, SF);
6987330f729Sjoerg }
6997330f729Sjoerg
executeCmpInst(unsigned predicate,GenericValue Src1,GenericValue Src2,Type * Ty)7007330f729Sjoerg static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
7017330f729Sjoerg GenericValue Src2, Type *Ty) {
7027330f729Sjoerg GenericValue Result;
7037330f729Sjoerg switch (predicate) {
7047330f729Sjoerg case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty);
7057330f729Sjoerg case ICmpInst::ICMP_NE: return executeICMP_NE(Src1, Src2, Ty);
7067330f729Sjoerg case ICmpInst::ICMP_UGT: return executeICMP_UGT(Src1, Src2, Ty);
7077330f729Sjoerg case ICmpInst::ICMP_SGT: return executeICMP_SGT(Src1, Src2, Ty);
7087330f729Sjoerg case ICmpInst::ICMP_ULT: return executeICMP_ULT(Src1, Src2, Ty);
7097330f729Sjoerg case ICmpInst::ICMP_SLT: return executeICMP_SLT(Src1, Src2, Ty);
7107330f729Sjoerg case ICmpInst::ICMP_UGE: return executeICMP_UGE(Src1, Src2, Ty);
7117330f729Sjoerg case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty);
7127330f729Sjoerg case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty);
7137330f729Sjoerg case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty);
7147330f729Sjoerg case FCmpInst::FCMP_ORD: return executeFCMP_ORD(Src1, Src2, Ty);
7157330f729Sjoerg case FCmpInst::FCMP_UNO: return executeFCMP_UNO(Src1, Src2, Ty);
7167330f729Sjoerg case FCmpInst::FCMP_OEQ: return executeFCMP_OEQ(Src1, Src2, Ty);
7177330f729Sjoerg case FCmpInst::FCMP_UEQ: return executeFCMP_UEQ(Src1, Src2, Ty);
7187330f729Sjoerg case FCmpInst::FCMP_ONE: return executeFCMP_ONE(Src1, Src2, Ty);
7197330f729Sjoerg case FCmpInst::FCMP_UNE: return executeFCMP_UNE(Src1, Src2, Ty);
7207330f729Sjoerg case FCmpInst::FCMP_OLT: return executeFCMP_OLT(Src1, Src2, Ty);
7217330f729Sjoerg case FCmpInst::FCMP_ULT: return executeFCMP_ULT(Src1, Src2, Ty);
7227330f729Sjoerg case FCmpInst::FCMP_OGT: return executeFCMP_OGT(Src1, Src2, Ty);
7237330f729Sjoerg case FCmpInst::FCMP_UGT: return executeFCMP_UGT(Src1, Src2, Ty);
7247330f729Sjoerg case FCmpInst::FCMP_OLE: return executeFCMP_OLE(Src1, Src2, Ty);
7257330f729Sjoerg case FCmpInst::FCMP_ULE: return executeFCMP_ULE(Src1, Src2, Ty);
7267330f729Sjoerg case FCmpInst::FCMP_OGE: return executeFCMP_OGE(Src1, Src2, Ty);
7277330f729Sjoerg case FCmpInst::FCMP_UGE: return executeFCMP_UGE(Src1, Src2, Ty);
7287330f729Sjoerg case FCmpInst::FCMP_FALSE: return executeFCMP_BOOL(Src1, Src2, Ty, false);
7297330f729Sjoerg case FCmpInst::FCMP_TRUE: return executeFCMP_BOOL(Src1, Src2, Ty, true);
7307330f729Sjoerg default:
7317330f729Sjoerg dbgs() << "Unhandled Cmp predicate\n";
7327330f729Sjoerg llvm_unreachable(nullptr);
7337330f729Sjoerg }
7347330f729Sjoerg }
7357330f729Sjoerg
visitBinaryOperator(BinaryOperator & I)7367330f729Sjoerg void Interpreter::visitBinaryOperator(BinaryOperator &I) {
7377330f729Sjoerg ExecutionContext &SF = ECStack.back();
7387330f729Sjoerg Type *Ty = I.getOperand(0)->getType();
7397330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
7407330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
7417330f729Sjoerg GenericValue R; // Result
7427330f729Sjoerg
7437330f729Sjoerg // First process vector operation
7447330f729Sjoerg if (Ty->isVectorTy()) {
7457330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
7467330f729Sjoerg R.AggregateVal.resize(Src1.AggregateVal.size());
7477330f729Sjoerg
7487330f729Sjoerg // Macros to execute binary operation 'OP' over integer vectors
7497330f729Sjoerg #define INTEGER_VECTOR_OPERATION(OP) \
7507330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
7517330f729Sjoerg R.AggregateVal[i].IntVal = \
7527330f729Sjoerg Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
7537330f729Sjoerg
7547330f729Sjoerg // Additional macros to execute binary operations udiv/sdiv/urem/srem since
7557330f729Sjoerg // they have different notation.
7567330f729Sjoerg #define INTEGER_VECTOR_FUNCTION(OP) \
7577330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
7587330f729Sjoerg R.AggregateVal[i].IntVal = \
7597330f729Sjoerg Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
7607330f729Sjoerg
7617330f729Sjoerg // Macros to execute binary operation 'OP' over floating point type TY
7627330f729Sjoerg // (float or double) vectors
7637330f729Sjoerg #define FLOAT_VECTOR_FUNCTION(OP, TY) \
7647330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
7657330f729Sjoerg R.AggregateVal[i].TY = \
7667330f729Sjoerg Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
7677330f729Sjoerg
7687330f729Sjoerg // Macros to choose appropriate TY: float or double and run operation
7697330f729Sjoerg // execution
7707330f729Sjoerg #define FLOAT_VECTOR_OP(OP) { \
7717330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
7727330f729Sjoerg FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
7737330f729Sjoerg else { \
7747330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
7757330f729Sjoerg FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
7767330f729Sjoerg else { \
7777330f729Sjoerg dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
7787330f729Sjoerg llvm_unreachable(0); \
7797330f729Sjoerg } \
7807330f729Sjoerg } \
7817330f729Sjoerg }
7827330f729Sjoerg
7837330f729Sjoerg switch(I.getOpcode()){
7847330f729Sjoerg default:
7857330f729Sjoerg dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
7867330f729Sjoerg llvm_unreachable(nullptr);
7877330f729Sjoerg break;
7887330f729Sjoerg case Instruction::Add: INTEGER_VECTOR_OPERATION(+) break;
7897330f729Sjoerg case Instruction::Sub: INTEGER_VECTOR_OPERATION(-) break;
7907330f729Sjoerg case Instruction::Mul: INTEGER_VECTOR_OPERATION(*) break;
7917330f729Sjoerg case Instruction::UDiv: INTEGER_VECTOR_FUNCTION(udiv) break;
7927330f729Sjoerg case Instruction::SDiv: INTEGER_VECTOR_FUNCTION(sdiv) break;
7937330f729Sjoerg case Instruction::URem: INTEGER_VECTOR_FUNCTION(urem) break;
7947330f729Sjoerg case Instruction::SRem: INTEGER_VECTOR_FUNCTION(srem) break;
7957330f729Sjoerg case Instruction::And: INTEGER_VECTOR_OPERATION(&) break;
7967330f729Sjoerg case Instruction::Or: INTEGER_VECTOR_OPERATION(|) break;
7977330f729Sjoerg case Instruction::Xor: INTEGER_VECTOR_OPERATION(^) break;
7987330f729Sjoerg case Instruction::FAdd: FLOAT_VECTOR_OP(+) break;
7997330f729Sjoerg case Instruction::FSub: FLOAT_VECTOR_OP(-) break;
8007330f729Sjoerg case Instruction::FMul: FLOAT_VECTOR_OP(*) break;
8017330f729Sjoerg case Instruction::FDiv: FLOAT_VECTOR_OP(/) break;
8027330f729Sjoerg case Instruction::FRem:
8037330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
8047330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
8057330f729Sjoerg R.AggregateVal[i].FloatVal =
8067330f729Sjoerg fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
8077330f729Sjoerg else {
8087330f729Sjoerg if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
8097330f729Sjoerg for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
8107330f729Sjoerg R.AggregateVal[i].DoubleVal =
8117330f729Sjoerg fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
8127330f729Sjoerg else {
8137330f729Sjoerg dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
8147330f729Sjoerg llvm_unreachable(nullptr);
8157330f729Sjoerg }
8167330f729Sjoerg }
8177330f729Sjoerg break;
8187330f729Sjoerg }
8197330f729Sjoerg } else {
8207330f729Sjoerg switch (I.getOpcode()) {
8217330f729Sjoerg default:
8227330f729Sjoerg dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
8237330f729Sjoerg llvm_unreachable(nullptr);
8247330f729Sjoerg break;
8257330f729Sjoerg case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
8267330f729Sjoerg case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
8277330f729Sjoerg case Instruction::Mul: R.IntVal = Src1.IntVal * Src2.IntVal; break;
8287330f729Sjoerg case Instruction::FAdd: executeFAddInst(R, Src1, Src2, Ty); break;
8297330f729Sjoerg case Instruction::FSub: executeFSubInst(R, Src1, Src2, Ty); break;
8307330f729Sjoerg case Instruction::FMul: executeFMulInst(R, Src1, Src2, Ty); break;
8317330f729Sjoerg case Instruction::FDiv: executeFDivInst(R, Src1, Src2, Ty); break;
8327330f729Sjoerg case Instruction::FRem: executeFRemInst(R, Src1, Src2, Ty); break;
8337330f729Sjoerg case Instruction::UDiv: R.IntVal = Src1.IntVal.udiv(Src2.IntVal); break;
8347330f729Sjoerg case Instruction::SDiv: R.IntVal = Src1.IntVal.sdiv(Src2.IntVal); break;
8357330f729Sjoerg case Instruction::URem: R.IntVal = Src1.IntVal.urem(Src2.IntVal); break;
8367330f729Sjoerg case Instruction::SRem: R.IntVal = Src1.IntVal.srem(Src2.IntVal); break;
8377330f729Sjoerg case Instruction::And: R.IntVal = Src1.IntVal & Src2.IntVal; break;
8387330f729Sjoerg case Instruction::Or: R.IntVal = Src1.IntVal | Src2.IntVal; break;
8397330f729Sjoerg case Instruction::Xor: R.IntVal = Src1.IntVal ^ Src2.IntVal; break;
8407330f729Sjoerg }
8417330f729Sjoerg }
8427330f729Sjoerg SetValue(&I, R, SF);
8437330f729Sjoerg }
8447330f729Sjoerg
executeSelectInst(GenericValue Src1,GenericValue Src2,GenericValue Src3,Type * Ty)8457330f729Sjoerg static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
8467330f729Sjoerg GenericValue Src3, Type *Ty) {
8477330f729Sjoerg GenericValue Dest;
8487330f729Sjoerg if(Ty->isVectorTy()) {
8497330f729Sjoerg assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
8507330f729Sjoerg assert(Src2.AggregateVal.size() == Src3.AggregateVal.size());
8517330f729Sjoerg Dest.AggregateVal.resize( Src1.AggregateVal.size() );
8527330f729Sjoerg for (size_t i = 0; i < Src1.AggregateVal.size(); ++i)
8537330f729Sjoerg Dest.AggregateVal[i] = (Src1.AggregateVal[i].IntVal == 0) ?
8547330f729Sjoerg Src3.AggregateVal[i] : Src2.AggregateVal[i];
8557330f729Sjoerg } else {
8567330f729Sjoerg Dest = (Src1.IntVal == 0) ? Src3 : Src2;
8577330f729Sjoerg }
8587330f729Sjoerg return Dest;
8597330f729Sjoerg }
8607330f729Sjoerg
visitSelectInst(SelectInst & I)8617330f729Sjoerg void Interpreter::visitSelectInst(SelectInst &I) {
8627330f729Sjoerg ExecutionContext &SF = ECStack.back();
8637330f729Sjoerg Type * Ty = I.getOperand(0)->getType();
8647330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
8657330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
8667330f729Sjoerg GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
8677330f729Sjoerg GenericValue R = executeSelectInst(Src1, Src2, Src3, Ty);
8687330f729Sjoerg SetValue(&I, R, SF);
8697330f729Sjoerg }
8707330f729Sjoerg
8717330f729Sjoerg //===----------------------------------------------------------------------===//
8727330f729Sjoerg // Terminator Instruction Implementations
8737330f729Sjoerg //===----------------------------------------------------------------------===//
8747330f729Sjoerg
exitCalled(GenericValue GV)8757330f729Sjoerg void Interpreter::exitCalled(GenericValue GV) {
8767330f729Sjoerg // runAtExitHandlers() assumes there are no stack frames, but
8777330f729Sjoerg // if exit() was called, then it had a stack frame. Blow away
8787330f729Sjoerg // the stack before interpreting atexit handlers.
8797330f729Sjoerg ECStack.clear();
8807330f729Sjoerg runAtExitHandlers();
8817330f729Sjoerg exit(GV.IntVal.zextOrTrunc(32).getZExtValue());
8827330f729Sjoerg }
8837330f729Sjoerg
8847330f729Sjoerg /// Pop the last stack frame off of ECStack and then copy the result
8857330f729Sjoerg /// back into the result variable if we are not returning void. The
8867330f729Sjoerg /// result variable may be the ExitValue, or the Value of the calling
8877330f729Sjoerg /// CallInst if there was a previous stack frame. This method may
8887330f729Sjoerg /// invalidate any ECStack iterators you have. This method also takes
8897330f729Sjoerg /// care of switching to the normal destination BB, if we are returning
8907330f729Sjoerg /// from an invoke.
8917330f729Sjoerg ///
popStackAndReturnValueToCaller(Type * RetTy,GenericValue Result)8927330f729Sjoerg void Interpreter::popStackAndReturnValueToCaller(Type *RetTy,
8937330f729Sjoerg GenericValue Result) {
8947330f729Sjoerg // Pop the current stack frame.
8957330f729Sjoerg ECStack.pop_back();
8967330f729Sjoerg
8977330f729Sjoerg if (ECStack.empty()) { // Finished main. Put result into exit code...
8987330f729Sjoerg if (RetTy && !RetTy->isVoidTy()) { // Nonvoid return type?
8997330f729Sjoerg ExitValue = Result; // Capture the exit value of the program
9007330f729Sjoerg } else {
9017330f729Sjoerg memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
9027330f729Sjoerg }
9037330f729Sjoerg } else {
9047330f729Sjoerg // If we have a previous stack frame, and we have a previous call,
9057330f729Sjoerg // fill in the return value...
9067330f729Sjoerg ExecutionContext &CallingSF = ECStack.back();
907*82d56013Sjoerg if (CallingSF.Caller) {
9087330f729Sjoerg // Save result...
909*82d56013Sjoerg if (!CallingSF.Caller->getType()->isVoidTy())
910*82d56013Sjoerg SetValue(CallingSF.Caller, Result, CallingSF);
911*82d56013Sjoerg if (InvokeInst *II = dyn_cast<InvokeInst>(CallingSF.Caller))
9127330f729Sjoerg SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
913*82d56013Sjoerg CallingSF.Caller = nullptr; // We returned from the call...
9147330f729Sjoerg }
9157330f729Sjoerg }
9167330f729Sjoerg }
9177330f729Sjoerg
visitReturnInst(ReturnInst & I)9187330f729Sjoerg void Interpreter::visitReturnInst(ReturnInst &I) {
9197330f729Sjoerg ExecutionContext &SF = ECStack.back();
9207330f729Sjoerg Type *RetTy = Type::getVoidTy(I.getContext());
9217330f729Sjoerg GenericValue Result;
9227330f729Sjoerg
9237330f729Sjoerg // Save away the return value... (if we are not 'ret void')
9247330f729Sjoerg if (I.getNumOperands()) {
9257330f729Sjoerg RetTy = I.getReturnValue()->getType();
9267330f729Sjoerg Result = getOperandValue(I.getReturnValue(), SF);
9277330f729Sjoerg }
9287330f729Sjoerg
9297330f729Sjoerg popStackAndReturnValueToCaller(RetTy, Result);
9307330f729Sjoerg }
9317330f729Sjoerg
visitUnreachableInst(UnreachableInst & I)9327330f729Sjoerg void Interpreter::visitUnreachableInst(UnreachableInst &I) {
9337330f729Sjoerg report_fatal_error("Program executed an 'unreachable' instruction!");
9347330f729Sjoerg }
9357330f729Sjoerg
visitBranchInst(BranchInst & I)9367330f729Sjoerg void Interpreter::visitBranchInst(BranchInst &I) {
9377330f729Sjoerg ExecutionContext &SF = ECStack.back();
9387330f729Sjoerg BasicBlock *Dest;
9397330f729Sjoerg
9407330f729Sjoerg Dest = I.getSuccessor(0); // Uncond branches have a fixed dest...
9417330f729Sjoerg if (!I.isUnconditional()) {
9427330f729Sjoerg Value *Cond = I.getCondition();
9437330f729Sjoerg if (getOperandValue(Cond, SF).IntVal == 0) // If false cond...
9447330f729Sjoerg Dest = I.getSuccessor(1);
9457330f729Sjoerg }
9467330f729Sjoerg SwitchToNewBasicBlock(Dest, SF);
9477330f729Sjoerg }
9487330f729Sjoerg
visitSwitchInst(SwitchInst & I)9497330f729Sjoerg void Interpreter::visitSwitchInst(SwitchInst &I) {
9507330f729Sjoerg ExecutionContext &SF = ECStack.back();
9517330f729Sjoerg Value* Cond = I.getCondition();
9527330f729Sjoerg Type *ElTy = Cond->getType();
9537330f729Sjoerg GenericValue CondVal = getOperandValue(Cond, SF);
9547330f729Sjoerg
9557330f729Sjoerg // Check to see if any of the cases match...
9567330f729Sjoerg BasicBlock *Dest = nullptr;
9577330f729Sjoerg for (auto Case : I.cases()) {
9587330f729Sjoerg GenericValue CaseVal = getOperandValue(Case.getCaseValue(), SF);
9597330f729Sjoerg if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
9607330f729Sjoerg Dest = cast<BasicBlock>(Case.getCaseSuccessor());
9617330f729Sjoerg break;
9627330f729Sjoerg }
9637330f729Sjoerg }
9647330f729Sjoerg if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
9657330f729Sjoerg SwitchToNewBasicBlock(Dest, SF);
9667330f729Sjoerg }
9677330f729Sjoerg
visitIndirectBrInst(IndirectBrInst & I)9687330f729Sjoerg void Interpreter::visitIndirectBrInst(IndirectBrInst &I) {
9697330f729Sjoerg ExecutionContext &SF = ECStack.back();
9707330f729Sjoerg void *Dest = GVTOP(getOperandValue(I.getAddress(), SF));
9717330f729Sjoerg SwitchToNewBasicBlock((BasicBlock*)Dest, SF);
9727330f729Sjoerg }
9737330f729Sjoerg
9747330f729Sjoerg
9757330f729Sjoerg // SwitchToNewBasicBlock - This method is used to jump to a new basic block.
9767330f729Sjoerg // This function handles the actual updating of block and instruction iterators
9777330f729Sjoerg // as well as execution of all of the PHI nodes in the destination block.
9787330f729Sjoerg //
9797330f729Sjoerg // This method does this because all of the PHI nodes must be executed
9807330f729Sjoerg // atomically, reading their inputs before any of the results are updated. Not
9817330f729Sjoerg // doing this can cause problems if the PHI nodes depend on other PHI nodes for
9827330f729Sjoerg // their inputs. If the input PHI node is updated before it is read, incorrect
9837330f729Sjoerg // results can happen. Thus we use a two phase approach.
9847330f729Sjoerg //
SwitchToNewBasicBlock(BasicBlock * Dest,ExecutionContext & SF)9857330f729Sjoerg void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){
9867330f729Sjoerg BasicBlock *PrevBB = SF.CurBB; // Remember where we came from...
9877330f729Sjoerg SF.CurBB = Dest; // Update CurBB to branch destination
9887330f729Sjoerg SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr...
9897330f729Sjoerg
9907330f729Sjoerg if (!isa<PHINode>(SF.CurInst)) return; // Nothing fancy to do
9917330f729Sjoerg
9927330f729Sjoerg // Loop over all of the PHI nodes in the current block, reading their inputs.
9937330f729Sjoerg std::vector<GenericValue> ResultValues;
9947330f729Sjoerg
9957330f729Sjoerg for (; PHINode *PN = dyn_cast<PHINode>(SF.CurInst); ++SF.CurInst) {
9967330f729Sjoerg // Search for the value corresponding to this previous bb...
9977330f729Sjoerg int i = PN->getBasicBlockIndex(PrevBB);
9987330f729Sjoerg assert(i != -1 && "PHINode doesn't contain entry for predecessor??");
9997330f729Sjoerg Value *IncomingValue = PN->getIncomingValue(i);
10007330f729Sjoerg
10017330f729Sjoerg // Save the incoming value for this PHI node...
10027330f729Sjoerg ResultValues.push_back(getOperandValue(IncomingValue, SF));
10037330f729Sjoerg }
10047330f729Sjoerg
10057330f729Sjoerg // Now loop over all of the PHI nodes setting their values...
10067330f729Sjoerg SF.CurInst = SF.CurBB->begin();
10077330f729Sjoerg for (unsigned i = 0; isa<PHINode>(SF.CurInst); ++SF.CurInst, ++i) {
10087330f729Sjoerg PHINode *PN = cast<PHINode>(SF.CurInst);
10097330f729Sjoerg SetValue(PN, ResultValues[i], SF);
10107330f729Sjoerg }
10117330f729Sjoerg }
10127330f729Sjoerg
10137330f729Sjoerg //===----------------------------------------------------------------------===//
10147330f729Sjoerg // Memory Instruction Implementations
10157330f729Sjoerg //===----------------------------------------------------------------------===//
10167330f729Sjoerg
visitAllocaInst(AllocaInst & I)10177330f729Sjoerg void Interpreter::visitAllocaInst(AllocaInst &I) {
10187330f729Sjoerg ExecutionContext &SF = ECStack.back();
10197330f729Sjoerg
10207330f729Sjoerg Type *Ty = I.getType()->getElementType(); // Type to be allocated
10217330f729Sjoerg
10227330f729Sjoerg // Get the number of elements being allocated by the array...
10237330f729Sjoerg unsigned NumElements =
10247330f729Sjoerg getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
10257330f729Sjoerg
10267330f729Sjoerg unsigned TypeSize = (size_t)getDataLayout().getTypeAllocSize(Ty);
10277330f729Sjoerg
10287330f729Sjoerg // Avoid malloc-ing zero bytes, use max()...
10297330f729Sjoerg unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
10307330f729Sjoerg
10317330f729Sjoerg // Allocate enough memory to hold the type...
10327330f729Sjoerg void *Memory = safe_malloc(MemToAlloc);
10337330f729Sjoerg
10347330f729Sjoerg LLVM_DEBUG(dbgs() << "Allocated Type: " << *Ty << " (" << TypeSize
10357330f729Sjoerg << " bytes) x " << NumElements << " (Total: " << MemToAlloc
10367330f729Sjoerg << ") at " << uintptr_t(Memory) << '\n');
10377330f729Sjoerg
10387330f729Sjoerg GenericValue Result = PTOGV(Memory);
10397330f729Sjoerg assert(Result.PointerVal && "Null pointer returned by malloc!");
10407330f729Sjoerg SetValue(&I, Result, SF);
10417330f729Sjoerg
10427330f729Sjoerg if (I.getOpcode() == Instruction::Alloca)
10437330f729Sjoerg ECStack.back().Allocas.add(Memory);
10447330f729Sjoerg }
10457330f729Sjoerg
10467330f729Sjoerg // getElementOffset - The workhorse for getelementptr.
10477330f729Sjoerg //
executeGEPOperation(Value * Ptr,gep_type_iterator I,gep_type_iterator E,ExecutionContext & SF)10487330f729Sjoerg GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
10497330f729Sjoerg gep_type_iterator E,
10507330f729Sjoerg ExecutionContext &SF) {
10517330f729Sjoerg assert(Ptr->getType()->isPointerTy() &&
10527330f729Sjoerg "Cannot getElementOffset of a nonpointer type!");
10537330f729Sjoerg
10547330f729Sjoerg uint64_t Total = 0;
10557330f729Sjoerg
10567330f729Sjoerg for (; I != E; ++I) {
10577330f729Sjoerg if (StructType *STy = I.getStructTypeOrNull()) {
10587330f729Sjoerg const StructLayout *SLO = getDataLayout().getStructLayout(STy);
10597330f729Sjoerg
10607330f729Sjoerg const ConstantInt *CPU = cast<ConstantInt>(I.getOperand());
10617330f729Sjoerg unsigned Index = unsigned(CPU->getZExtValue());
10627330f729Sjoerg
10637330f729Sjoerg Total += SLO->getElementOffset(Index);
10647330f729Sjoerg } else {
10657330f729Sjoerg // Get the index number for the array... which must be long type...
10667330f729Sjoerg GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
10677330f729Sjoerg
10687330f729Sjoerg int64_t Idx;
10697330f729Sjoerg unsigned BitWidth =
10707330f729Sjoerg cast<IntegerType>(I.getOperand()->getType())->getBitWidth();
10717330f729Sjoerg if (BitWidth == 32)
10727330f729Sjoerg Idx = (int64_t)(int32_t)IdxGV.IntVal.getZExtValue();
10737330f729Sjoerg else {
10747330f729Sjoerg assert(BitWidth == 64 && "Invalid index type for getelementptr");
10757330f729Sjoerg Idx = (int64_t)IdxGV.IntVal.getZExtValue();
10767330f729Sjoerg }
10777330f729Sjoerg Total += getDataLayout().getTypeAllocSize(I.getIndexedType()) * Idx;
10787330f729Sjoerg }
10797330f729Sjoerg }
10807330f729Sjoerg
10817330f729Sjoerg GenericValue Result;
10827330f729Sjoerg Result.PointerVal = ((char*)getOperandValue(Ptr, SF).PointerVal) + Total;
10837330f729Sjoerg LLVM_DEBUG(dbgs() << "GEP Index " << Total << " bytes.\n");
10847330f729Sjoerg return Result;
10857330f729Sjoerg }
10867330f729Sjoerg
visitGetElementPtrInst(GetElementPtrInst & I)10877330f729Sjoerg void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
10887330f729Sjoerg ExecutionContext &SF = ECStack.back();
10897330f729Sjoerg SetValue(&I, executeGEPOperation(I.getPointerOperand(),
10907330f729Sjoerg gep_type_begin(I), gep_type_end(I), SF), SF);
10917330f729Sjoerg }
10927330f729Sjoerg
visitLoadInst(LoadInst & I)10937330f729Sjoerg void Interpreter::visitLoadInst(LoadInst &I) {
10947330f729Sjoerg ExecutionContext &SF = ECStack.back();
10957330f729Sjoerg GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
10967330f729Sjoerg GenericValue *Ptr = (GenericValue*)GVTOP(SRC);
10977330f729Sjoerg GenericValue Result;
10987330f729Sjoerg LoadValueFromMemory(Result, Ptr, I.getType());
10997330f729Sjoerg SetValue(&I, Result, SF);
11007330f729Sjoerg if (I.isVolatile() && PrintVolatile)
11017330f729Sjoerg dbgs() << "Volatile load " << I;
11027330f729Sjoerg }
11037330f729Sjoerg
visitStoreInst(StoreInst & I)11047330f729Sjoerg void Interpreter::visitStoreInst(StoreInst &I) {
11057330f729Sjoerg ExecutionContext &SF = ECStack.back();
11067330f729Sjoerg GenericValue Val = getOperandValue(I.getOperand(0), SF);
11077330f729Sjoerg GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
11087330f729Sjoerg StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC),
11097330f729Sjoerg I.getOperand(0)->getType());
11107330f729Sjoerg if (I.isVolatile() && PrintVolatile)
11117330f729Sjoerg dbgs() << "Volatile store: " << I;
11127330f729Sjoerg }
11137330f729Sjoerg
11147330f729Sjoerg //===----------------------------------------------------------------------===//
11157330f729Sjoerg // Miscellaneous Instruction Implementations
11167330f729Sjoerg //===----------------------------------------------------------------------===//
11177330f729Sjoerg
visitVAStartInst(VAStartInst & I)1118*82d56013Sjoerg void Interpreter::visitVAStartInst(VAStartInst &I) {
11197330f729Sjoerg ExecutionContext &SF = ECStack.back();
11207330f729Sjoerg GenericValue ArgIndex;
11217330f729Sjoerg ArgIndex.UIntPairVal.first = ECStack.size() - 1;
11227330f729Sjoerg ArgIndex.UIntPairVal.second = 0;
1123*82d56013Sjoerg SetValue(&I, ArgIndex, SF);
11247330f729Sjoerg }
1125*82d56013Sjoerg
visitVAEndInst(VAEndInst & I)1126*82d56013Sjoerg void Interpreter::visitVAEndInst(VAEndInst &I) {
1127*82d56013Sjoerg // va_end is a noop for the interpreter
1128*82d56013Sjoerg }
1129*82d56013Sjoerg
visitVACopyInst(VACopyInst & I)1130*82d56013Sjoerg void Interpreter::visitVACopyInst(VACopyInst &I) {
1131*82d56013Sjoerg ExecutionContext &SF = ECStack.back();
1132*82d56013Sjoerg SetValue(&I, getOperandValue(*I.arg_begin(), SF), SF);
1133*82d56013Sjoerg }
1134*82d56013Sjoerg
visitIntrinsicInst(IntrinsicInst & I)1135*82d56013Sjoerg void Interpreter::visitIntrinsicInst(IntrinsicInst &I) {
1136*82d56013Sjoerg ExecutionContext &SF = ECStack.back();
1137*82d56013Sjoerg
11387330f729Sjoerg // If it is an unknown intrinsic function, use the intrinsic lowering
11397330f729Sjoerg // class to transform it into hopefully tasty LLVM code.
11407330f729Sjoerg //
1141*82d56013Sjoerg BasicBlock::iterator Me(&I);
1142*82d56013Sjoerg BasicBlock *Parent = I.getParent();
1143*82d56013Sjoerg bool atBegin(Parent->begin() == Me);
11447330f729Sjoerg if (!atBegin)
1145*82d56013Sjoerg --Me;
1146*82d56013Sjoerg IL->LowerIntrinsicCall(&I);
11477330f729Sjoerg
11487330f729Sjoerg // Restore the CurInst pointer to the first instruction newly inserted, if
11497330f729Sjoerg // any.
11507330f729Sjoerg if (atBegin) {
11517330f729Sjoerg SF.CurInst = Parent->begin();
11527330f729Sjoerg } else {
1153*82d56013Sjoerg SF.CurInst = Me;
11547330f729Sjoerg ++SF.CurInst;
11557330f729Sjoerg }
11567330f729Sjoerg }
11577330f729Sjoerg
visitCallBase(CallBase & I)1158*82d56013Sjoerg void Interpreter::visitCallBase(CallBase &I) {
1159*82d56013Sjoerg ExecutionContext &SF = ECStack.back();
11607330f729Sjoerg
1161*82d56013Sjoerg SF.Caller = &I;
11627330f729Sjoerg std::vector<GenericValue> ArgVals;
1163*82d56013Sjoerg const unsigned NumArgs = SF.Caller->arg_size();
11647330f729Sjoerg ArgVals.reserve(NumArgs);
1165*82d56013Sjoerg for (Value *V : SF.Caller->args())
11667330f729Sjoerg ArgVals.push_back(getOperandValue(V, SF));
11677330f729Sjoerg
11687330f729Sjoerg // To handle indirect calls, we must get the pointer value from the argument
11697330f729Sjoerg // and treat it as a function pointer.
1170*82d56013Sjoerg GenericValue SRC = getOperandValue(SF.Caller->getCalledOperand(), SF);
11717330f729Sjoerg callFunction((Function*)GVTOP(SRC), ArgVals);
11727330f729Sjoerg }
11737330f729Sjoerg
11747330f729Sjoerg // auxiliary function for shift operations
getShiftAmount(uint64_t orgShiftAmount,llvm::APInt valueToShift)11757330f729Sjoerg static unsigned getShiftAmount(uint64_t orgShiftAmount,
11767330f729Sjoerg llvm::APInt valueToShift) {
11777330f729Sjoerg unsigned valueWidth = valueToShift.getBitWidth();
11787330f729Sjoerg if (orgShiftAmount < (uint64_t)valueWidth)
11797330f729Sjoerg return orgShiftAmount;
11807330f729Sjoerg // according to the llvm documentation, if orgShiftAmount > valueWidth,
11817330f729Sjoerg // the result is undfeined. but we do shift by this rule:
11827330f729Sjoerg return (NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
11837330f729Sjoerg }
11847330f729Sjoerg
11857330f729Sjoerg
visitShl(BinaryOperator & I)11867330f729Sjoerg void Interpreter::visitShl(BinaryOperator &I) {
11877330f729Sjoerg ExecutionContext &SF = ECStack.back();
11887330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
11897330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
11907330f729Sjoerg GenericValue Dest;
11917330f729Sjoerg Type *Ty = I.getType();
11927330f729Sjoerg
11937330f729Sjoerg if (Ty->isVectorTy()) {
11947330f729Sjoerg uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
11957330f729Sjoerg assert(src1Size == Src2.AggregateVal.size());
11967330f729Sjoerg for (unsigned i = 0; i < src1Size; i++) {
11977330f729Sjoerg GenericValue Result;
11987330f729Sjoerg uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
11997330f729Sjoerg llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
12007330f729Sjoerg Result.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
12017330f729Sjoerg Dest.AggregateVal.push_back(Result);
12027330f729Sjoerg }
12037330f729Sjoerg } else {
12047330f729Sjoerg // scalar
12057330f729Sjoerg uint64_t shiftAmount = Src2.IntVal.getZExtValue();
12067330f729Sjoerg llvm::APInt valueToShift = Src1.IntVal;
12077330f729Sjoerg Dest.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
12087330f729Sjoerg }
12097330f729Sjoerg
12107330f729Sjoerg SetValue(&I, Dest, SF);
12117330f729Sjoerg }
12127330f729Sjoerg
visitLShr(BinaryOperator & I)12137330f729Sjoerg void Interpreter::visitLShr(BinaryOperator &I) {
12147330f729Sjoerg ExecutionContext &SF = ECStack.back();
12157330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
12167330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
12177330f729Sjoerg GenericValue Dest;
12187330f729Sjoerg Type *Ty = I.getType();
12197330f729Sjoerg
12207330f729Sjoerg if (Ty->isVectorTy()) {
12217330f729Sjoerg uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
12227330f729Sjoerg assert(src1Size == Src2.AggregateVal.size());
12237330f729Sjoerg for (unsigned i = 0; i < src1Size; i++) {
12247330f729Sjoerg GenericValue Result;
12257330f729Sjoerg uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
12267330f729Sjoerg llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
12277330f729Sjoerg Result.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
12287330f729Sjoerg Dest.AggregateVal.push_back(Result);
12297330f729Sjoerg }
12307330f729Sjoerg } else {
12317330f729Sjoerg // scalar
12327330f729Sjoerg uint64_t shiftAmount = Src2.IntVal.getZExtValue();
12337330f729Sjoerg llvm::APInt valueToShift = Src1.IntVal;
12347330f729Sjoerg Dest.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
12357330f729Sjoerg }
12367330f729Sjoerg
12377330f729Sjoerg SetValue(&I, Dest, SF);
12387330f729Sjoerg }
12397330f729Sjoerg
visitAShr(BinaryOperator & I)12407330f729Sjoerg void Interpreter::visitAShr(BinaryOperator &I) {
12417330f729Sjoerg ExecutionContext &SF = ECStack.back();
12427330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
12437330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
12447330f729Sjoerg GenericValue Dest;
12457330f729Sjoerg Type *Ty = I.getType();
12467330f729Sjoerg
12477330f729Sjoerg if (Ty->isVectorTy()) {
12487330f729Sjoerg size_t src1Size = Src1.AggregateVal.size();
12497330f729Sjoerg assert(src1Size == Src2.AggregateVal.size());
12507330f729Sjoerg for (unsigned i = 0; i < src1Size; i++) {
12517330f729Sjoerg GenericValue Result;
12527330f729Sjoerg uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
12537330f729Sjoerg llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
12547330f729Sjoerg Result.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
12557330f729Sjoerg Dest.AggregateVal.push_back(Result);
12567330f729Sjoerg }
12577330f729Sjoerg } else {
12587330f729Sjoerg // scalar
12597330f729Sjoerg uint64_t shiftAmount = Src2.IntVal.getZExtValue();
12607330f729Sjoerg llvm::APInt valueToShift = Src1.IntVal;
12617330f729Sjoerg Dest.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
12627330f729Sjoerg }
12637330f729Sjoerg
12647330f729Sjoerg SetValue(&I, Dest, SF);
12657330f729Sjoerg }
12667330f729Sjoerg
executeTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12677330f729Sjoerg GenericValue Interpreter::executeTruncInst(Value *SrcVal, Type *DstTy,
12687330f729Sjoerg ExecutionContext &SF) {
12697330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12707330f729Sjoerg Type *SrcTy = SrcVal->getType();
12717330f729Sjoerg if (SrcTy->isVectorTy()) {
12727330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
12737330f729Sjoerg unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
12747330f729Sjoerg unsigned NumElts = Src.AggregateVal.size();
12757330f729Sjoerg // the sizes of src and dst vectors must be equal
12767330f729Sjoerg Dest.AggregateVal.resize(NumElts);
12777330f729Sjoerg for (unsigned i = 0; i < NumElts; i++)
12787330f729Sjoerg Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.trunc(DBitWidth);
12797330f729Sjoerg } else {
12807330f729Sjoerg IntegerType *DITy = cast<IntegerType>(DstTy);
12817330f729Sjoerg unsigned DBitWidth = DITy->getBitWidth();
12827330f729Sjoerg Dest.IntVal = Src.IntVal.trunc(DBitWidth);
12837330f729Sjoerg }
12847330f729Sjoerg return Dest;
12857330f729Sjoerg }
12867330f729Sjoerg
executeSExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)12877330f729Sjoerg GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy,
12887330f729Sjoerg ExecutionContext &SF) {
12897330f729Sjoerg Type *SrcTy = SrcVal->getType();
12907330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
12917330f729Sjoerg if (SrcTy->isVectorTy()) {
12927330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
12937330f729Sjoerg unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
12947330f729Sjoerg unsigned size = Src.AggregateVal.size();
12957330f729Sjoerg // the sizes of src and dst vectors must be equal.
12967330f729Sjoerg Dest.AggregateVal.resize(size);
12977330f729Sjoerg for (unsigned i = 0; i < size; i++)
12987330f729Sjoerg Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
12997330f729Sjoerg } else {
13007330f729Sjoerg auto *DITy = cast<IntegerType>(DstTy);
13017330f729Sjoerg unsigned DBitWidth = DITy->getBitWidth();
13027330f729Sjoerg Dest.IntVal = Src.IntVal.sext(DBitWidth);
13037330f729Sjoerg }
13047330f729Sjoerg return Dest;
13057330f729Sjoerg }
13067330f729Sjoerg
executeZExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13077330f729Sjoerg GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy,
13087330f729Sjoerg ExecutionContext &SF) {
13097330f729Sjoerg Type *SrcTy = SrcVal->getType();
13107330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13117330f729Sjoerg if (SrcTy->isVectorTy()) {
13127330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
13137330f729Sjoerg unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
13147330f729Sjoerg
13157330f729Sjoerg unsigned size = Src.AggregateVal.size();
13167330f729Sjoerg // the sizes of src and dst vectors must be equal.
13177330f729Sjoerg Dest.AggregateVal.resize(size);
13187330f729Sjoerg for (unsigned i = 0; i < size; i++)
13197330f729Sjoerg Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
13207330f729Sjoerg } else {
13217330f729Sjoerg auto *DITy = cast<IntegerType>(DstTy);
13227330f729Sjoerg unsigned DBitWidth = DITy->getBitWidth();
13237330f729Sjoerg Dest.IntVal = Src.IntVal.zext(DBitWidth);
13247330f729Sjoerg }
13257330f729Sjoerg return Dest;
13267330f729Sjoerg }
13277330f729Sjoerg
executeFPTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13287330f729Sjoerg GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, Type *DstTy,
13297330f729Sjoerg ExecutionContext &SF) {
13307330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13317330f729Sjoerg
1332*82d56013Sjoerg if (isa<VectorType>(SrcVal->getType())) {
13337330f729Sjoerg assert(SrcVal->getType()->getScalarType()->isDoubleTy() &&
13347330f729Sjoerg DstTy->getScalarType()->isFloatTy() &&
13357330f729Sjoerg "Invalid FPTrunc instruction");
13367330f729Sjoerg
13377330f729Sjoerg unsigned size = Src.AggregateVal.size();
13387330f729Sjoerg // the sizes of src and dst vectors must be equal.
13397330f729Sjoerg Dest.AggregateVal.resize(size);
13407330f729Sjoerg for (unsigned i = 0; i < size; i++)
13417330f729Sjoerg Dest.AggregateVal[i].FloatVal = (float)Src.AggregateVal[i].DoubleVal;
13427330f729Sjoerg } else {
13437330f729Sjoerg assert(SrcVal->getType()->isDoubleTy() && DstTy->isFloatTy() &&
13447330f729Sjoerg "Invalid FPTrunc instruction");
13457330f729Sjoerg Dest.FloatVal = (float)Src.DoubleVal;
13467330f729Sjoerg }
13477330f729Sjoerg
13487330f729Sjoerg return Dest;
13497330f729Sjoerg }
13507330f729Sjoerg
executeFPExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13517330f729Sjoerg GenericValue Interpreter::executeFPExtInst(Value *SrcVal, Type *DstTy,
13527330f729Sjoerg ExecutionContext &SF) {
13537330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13547330f729Sjoerg
1355*82d56013Sjoerg if (isa<VectorType>(SrcVal->getType())) {
13567330f729Sjoerg assert(SrcVal->getType()->getScalarType()->isFloatTy() &&
13577330f729Sjoerg DstTy->getScalarType()->isDoubleTy() && "Invalid FPExt instruction");
13587330f729Sjoerg
13597330f729Sjoerg unsigned size = Src.AggregateVal.size();
13607330f729Sjoerg // the sizes of src and dst vectors must be equal.
13617330f729Sjoerg Dest.AggregateVal.resize(size);
13627330f729Sjoerg for (unsigned i = 0; i < size; i++)
13637330f729Sjoerg Dest.AggregateVal[i].DoubleVal = (double)Src.AggregateVal[i].FloatVal;
13647330f729Sjoerg } else {
13657330f729Sjoerg assert(SrcVal->getType()->isFloatTy() && DstTy->isDoubleTy() &&
13667330f729Sjoerg "Invalid FPExt instruction");
13677330f729Sjoerg Dest.DoubleVal = (double)Src.FloatVal;
13687330f729Sjoerg }
13697330f729Sjoerg
13707330f729Sjoerg return Dest;
13717330f729Sjoerg }
13727330f729Sjoerg
executeFPToUIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)13737330f729Sjoerg GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, Type *DstTy,
13747330f729Sjoerg ExecutionContext &SF) {
13757330f729Sjoerg Type *SrcTy = SrcVal->getType();
13767330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
13777330f729Sjoerg
1378*82d56013Sjoerg if (isa<VectorType>(SrcTy)) {
13797330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
13807330f729Sjoerg Type *SrcVecTy = SrcTy->getScalarType();
13817330f729Sjoerg uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
13827330f729Sjoerg unsigned size = Src.AggregateVal.size();
13837330f729Sjoerg // the sizes of src and dst vectors must be equal.
13847330f729Sjoerg Dest.AggregateVal.resize(size);
13857330f729Sjoerg
13867330f729Sjoerg if (SrcVecTy->getTypeID() == Type::FloatTyID) {
13877330f729Sjoerg assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToUI instruction");
13887330f729Sjoerg for (unsigned i = 0; i < size; i++)
13897330f729Sjoerg Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
13907330f729Sjoerg Src.AggregateVal[i].FloatVal, DBitWidth);
13917330f729Sjoerg } else {
13927330f729Sjoerg for (unsigned i = 0; i < size; i++)
13937330f729Sjoerg Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
13947330f729Sjoerg Src.AggregateVal[i].DoubleVal, DBitWidth);
13957330f729Sjoerg }
13967330f729Sjoerg } else {
13977330f729Sjoerg // scalar
13987330f729Sjoerg uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
13997330f729Sjoerg assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
14007330f729Sjoerg
14017330f729Sjoerg if (SrcTy->getTypeID() == Type::FloatTyID)
14027330f729Sjoerg Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
14037330f729Sjoerg else {
14047330f729Sjoerg Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
14057330f729Sjoerg }
14067330f729Sjoerg }
14077330f729Sjoerg
14087330f729Sjoerg return Dest;
14097330f729Sjoerg }
14107330f729Sjoerg
executeFPToSIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14117330f729Sjoerg GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, Type *DstTy,
14127330f729Sjoerg ExecutionContext &SF) {
14137330f729Sjoerg Type *SrcTy = SrcVal->getType();
14147330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14157330f729Sjoerg
1416*82d56013Sjoerg if (isa<VectorType>(SrcTy)) {
14177330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
14187330f729Sjoerg Type *SrcVecTy = SrcTy->getScalarType();
14197330f729Sjoerg uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
14207330f729Sjoerg unsigned size = Src.AggregateVal.size();
14217330f729Sjoerg // the sizes of src and dst vectors must be equal
14227330f729Sjoerg Dest.AggregateVal.resize(size);
14237330f729Sjoerg
14247330f729Sjoerg if (SrcVecTy->getTypeID() == Type::FloatTyID) {
14257330f729Sjoerg assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToSI instruction");
14267330f729Sjoerg for (unsigned i = 0; i < size; i++)
14277330f729Sjoerg Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
14287330f729Sjoerg Src.AggregateVal[i].FloatVal, DBitWidth);
14297330f729Sjoerg } else {
14307330f729Sjoerg for (unsigned i = 0; i < size; i++)
14317330f729Sjoerg Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
14327330f729Sjoerg Src.AggregateVal[i].DoubleVal, DBitWidth);
14337330f729Sjoerg }
14347330f729Sjoerg } else {
14357330f729Sjoerg // scalar
14367330f729Sjoerg unsigned DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
14377330f729Sjoerg assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
14387330f729Sjoerg
14397330f729Sjoerg if (SrcTy->getTypeID() == Type::FloatTyID)
14407330f729Sjoerg Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
14417330f729Sjoerg else {
14427330f729Sjoerg Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
14437330f729Sjoerg }
14447330f729Sjoerg }
14457330f729Sjoerg return Dest;
14467330f729Sjoerg }
14477330f729Sjoerg
executeUIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14487330f729Sjoerg GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, Type *DstTy,
14497330f729Sjoerg ExecutionContext &SF) {
14507330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14517330f729Sjoerg
1452*82d56013Sjoerg if (isa<VectorType>(SrcVal->getType())) {
14537330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
14547330f729Sjoerg unsigned size = Src.AggregateVal.size();
14557330f729Sjoerg // the sizes of src and dst vectors must be equal
14567330f729Sjoerg Dest.AggregateVal.resize(size);
14577330f729Sjoerg
14587330f729Sjoerg if (DstVecTy->getTypeID() == Type::FloatTyID) {
14597330f729Sjoerg assert(DstVecTy->isFloatingPointTy() && "Invalid UIToFP instruction");
14607330f729Sjoerg for (unsigned i = 0; i < size; i++)
14617330f729Sjoerg Dest.AggregateVal[i].FloatVal =
14627330f729Sjoerg APIntOps::RoundAPIntToFloat(Src.AggregateVal[i].IntVal);
14637330f729Sjoerg } else {
14647330f729Sjoerg for (unsigned i = 0; i < size; i++)
14657330f729Sjoerg Dest.AggregateVal[i].DoubleVal =
14667330f729Sjoerg APIntOps::RoundAPIntToDouble(Src.AggregateVal[i].IntVal);
14677330f729Sjoerg }
14687330f729Sjoerg } else {
14697330f729Sjoerg // scalar
14707330f729Sjoerg assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
14717330f729Sjoerg if (DstTy->getTypeID() == Type::FloatTyID)
14727330f729Sjoerg Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
14737330f729Sjoerg else {
14747330f729Sjoerg Dest.DoubleVal = APIntOps::RoundAPIntToDouble(Src.IntVal);
14757330f729Sjoerg }
14767330f729Sjoerg }
14777330f729Sjoerg return Dest;
14787330f729Sjoerg }
14797330f729Sjoerg
executeSIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)14807330f729Sjoerg GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, Type *DstTy,
14817330f729Sjoerg ExecutionContext &SF) {
14827330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
14837330f729Sjoerg
1484*82d56013Sjoerg if (isa<VectorType>(SrcVal->getType())) {
14857330f729Sjoerg Type *DstVecTy = DstTy->getScalarType();
14867330f729Sjoerg unsigned size = Src.AggregateVal.size();
14877330f729Sjoerg // the sizes of src and dst vectors must be equal
14887330f729Sjoerg Dest.AggregateVal.resize(size);
14897330f729Sjoerg
14907330f729Sjoerg if (DstVecTy->getTypeID() == Type::FloatTyID) {
14917330f729Sjoerg assert(DstVecTy->isFloatingPointTy() && "Invalid SIToFP instruction");
14927330f729Sjoerg for (unsigned i = 0; i < size; i++)
14937330f729Sjoerg Dest.AggregateVal[i].FloatVal =
14947330f729Sjoerg APIntOps::RoundSignedAPIntToFloat(Src.AggregateVal[i].IntVal);
14957330f729Sjoerg } else {
14967330f729Sjoerg for (unsigned i = 0; i < size; i++)
14977330f729Sjoerg Dest.AggregateVal[i].DoubleVal =
14987330f729Sjoerg APIntOps::RoundSignedAPIntToDouble(Src.AggregateVal[i].IntVal);
14997330f729Sjoerg }
15007330f729Sjoerg } else {
15017330f729Sjoerg // scalar
15027330f729Sjoerg assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
15037330f729Sjoerg
15047330f729Sjoerg if (DstTy->getTypeID() == Type::FloatTyID)
15057330f729Sjoerg Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
15067330f729Sjoerg else {
15077330f729Sjoerg Dest.DoubleVal = APIntOps::RoundSignedAPIntToDouble(Src.IntVal);
15087330f729Sjoerg }
15097330f729Sjoerg }
15107330f729Sjoerg
15117330f729Sjoerg return Dest;
15127330f729Sjoerg }
15137330f729Sjoerg
executePtrToIntInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)15147330f729Sjoerg GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, Type *DstTy,
15157330f729Sjoerg ExecutionContext &SF) {
15167330f729Sjoerg uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
15177330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
15187330f729Sjoerg assert(SrcVal->getType()->isPointerTy() && "Invalid PtrToInt instruction");
15197330f729Sjoerg
15207330f729Sjoerg Dest.IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
15217330f729Sjoerg return Dest;
15227330f729Sjoerg }
15237330f729Sjoerg
executeIntToPtrInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)15247330f729Sjoerg GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, Type *DstTy,
15257330f729Sjoerg ExecutionContext &SF) {
15267330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
15277330f729Sjoerg assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
15287330f729Sjoerg
15297330f729Sjoerg uint32_t PtrSize = getDataLayout().getPointerSizeInBits();
15307330f729Sjoerg if (PtrSize != Src.IntVal.getBitWidth())
15317330f729Sjoerg Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
15327330f729Sjoerg
15337330f729Sjoerg Dest.PointerVal = PointerTy(intptr_t(Src.IntVal.getZExtValue()));
15347330f729Sjoerg return Dest;
15357330f729Sjoerg }
15367330f729Sjoerg
executeBitCastInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)15377330f729Sjoerg GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy,
15387330f729Sjoerg ExecutionContext &SF) {
15397330f729Sjoerg
15407330f729Sjoerg // This instruction supports bitwise conversion of vectors to integers and
15417330f729Sjoerg // to vectors of other types (as long as they have the same size)
15427330f729Sjoerg Type *SrcTy = SrcVal->getType();
15437330f729Sjoerg GenericValue Dest, Src = getOperandValue(SrcVal, SF);
15447330f729Sjoerg
1545*82d56013Sjoerg if (isa<VectorType>(SrcTy) || isa<VectorType>(DstTy)) {
15467330f729Sjoerg // vector src bitcast to vector dst or vector src bitcast to scalar dst or
15477330f729Sjoerg // scalar src bitcast to vector dst
15487330f729Sjoerg bool isLittleEndian = getDataLayout().isLittleEndian();
15497330f729Sjoerg GenericValue TempDst, TempSrc, SrcVec;
15507330f729Sjoerg Type *SrcElemTy;
15517330f729Sjoerg Type *DstElemTy;
15527330f729Sjoerg unsigned SrcBitSize;
15537330f729Sjoerg unsigned DstBitSize;
15547330f729Sjoerg unsigned SrcNum;
15557330f729Sjoerg unsigned DstNum;
15567330f729Sjoerg
1557*82d56013Sjoerg if (isa<VectorType>(SrcTy)) {
15587330f729Sjoerg SrcElemTy = SrcTy->getScalarType();
15597330f729Sjoerg SrcBitSize = SrcTy->getScalarSizeInBits();
15607330f729Sjoerg SrcNum = Src.AggregateVal.size();
15617330f729Sjoerg SrcVec = Src;
15627330f729Sjoerg } else {
15637330f729Sjoerg // if src is scalar value, make it vector <1 x type>
15647330f729Sjoerg SrcElemTy = SrcTy;
15657330f729Sjoerg SrcBitSize = SrcTy->getPrimitiveSizeInBits();
15667330f729Sjoerg SrcNum = 1;
15677330f729Sjoerg SrcVec.AggregateVal.push_back(Src);
15687330f729Sjoerg }
15697330f729Sjoerg
1570*82d56013Sjoerg if (isa<VectorType>(DstTy)) {
15717330f729Sjoerg DstElemTy = DstTy->getScalarType();
15727330f729Sjoerg DstBitSize = DstTy->getScalarSizeInBits();
15737330f729Sjoerg DstNum = (SrcNum * SrcBitSize) / DstBitSize;
15747330f729Sjoerg } else {
15757330f729Sjoerg DstElemTy = DstTy;
15767330f729Sjoerg DstBitSize = DstTy->getPrimitiveSizeInBits();
15777330f729Sjoerg DstNum = 1;
15787330f729Sjoerg }
15797330f729Sjoerg
15807330f729Sjoerg if (SrcNum * SrcBitSize != DstNum * DstBitSize)
15817330f729Sjoerg llvm_unreachable("Invalid BitCast");
15827330f729Sjoerg
15837330f729Sjoerg // If src is floating point, cast to integer first.
15847330f729Sjoerg TempSrc.AggregateVal.resize(SrcNum);
15857330f729Sjoerg if (SrcElemTy->isFloatTy()) {
15867330f729Sjoerg for (unsigned i = 0; i < SrcNum; i++)
15877330f729Sjoerg TempSrc.AggregateVal[i].IntVal =
15887330f729Sjoerg APInt::floatToBits(SrcVec.AggregateVal[i].FloatVal);
15897330f729Sjoerg
15907330f729Sjoerg } else if (SrcElemTy->isDoubleTy()) {
15917330f729Sjoerg for (unsigned i = 0; i < SrcNum; i++)
15927330f729Sjoerg TempSrc.AggregateVal[i].IntVal =
15937330f729Sjoerg APInt::doubleToBits(SrcVec.AggregateVal[i].DoubleVal);
15947330f729Sjoerg } else if (SrcElemTy->isIntegerTy()) {
15957330f729Sjoerg for (unsigned i = 0; i < SrcNum; i++)
15967330f729Sjoerg TempSrc.AggregateVal[i].IntVal = SrcVec.AggregateVal[i].IntVal;
15977330f729Sjoerg } else {
15987330f729Sjoerg // Pointers are not allowed as the element type of vector.
15997330f729Sjoerg llvm_unreachable("Invalid Bitcast");
16007330f729Sjoerg }
16017330f729Sjoerg
16027330f729Sjoerg // now TempSrc is integer type vector
16037330f729Sjoerg if (DstNum < SrcNum) {
16047330f729Sjoerg // Example: bitcast <4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>
16057330f729Sjoerg unsigned Ratio = SrcNum / DstNum;
16067330f729Sjoerg unsigned SrcElt = 0;
16077330f729Sjoerg for (unsigned i = 0; i < DstNum; i++) {
16087330f729Sjoerg GenericValue Elt;
16097330f729Sjoerg Elt.IntVal = 0;
16107330f729Sjoerg Elt.IntVal = Elt.IntVal.zext(DstBitSize);
16117330f729Sjoerg unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
16127330f729Sjoerg for (unsigned j = 0; j < Ratio; j++) {
16137330f729Sjoerg APInt Tmp;
16147330f729Sjoerg Tmp = Tmp.zext(SrcBitSize);
16157330f729Sjoerg Tmp = TempSrc.AggregateVal[SrcElt++].IntVal;
16167330f729Sjoerg Tmp = Tmp.zext(DstBitSize);
16177330f729Sjoerg Tmp <<= ShiftAmt;
16187330f729Sjoerg ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
16197330f729Sjoerg Elt.IntVal |= Tmp;
16207330f729Sjoerg }
16217330f729Sjoerg TempDst.AggregateVal.push_back(Elt);
16227330f729Sjoerg }
16237330f729Sjoerg } else {
16247330f729Sjoerg // Example: bitcast <2 x i64> <i64 0, i64 1> to <4 x i32>
16257330f729Sjoerg unsigned Ratio = DstNum / SrcNum;
16267330f729Sjoerg for (unsigned i = 0; i < SrcNum; i++) {
16277330f729Sjoerg unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
16287330f729Sjoerg for (unsigned j = 0; j < Ratio; j++) {
16297330f729Sjoerg GenericValue Elt;
16307330f729Sjoerg Elt.IntVal = Elt.IntVal.zext(SrcBitSize);
16317330f729Sjoerg Elt.IntVal = TempSrc.AggregateVal[i].IntVal;
16327330f729Sjoerg Elt.IntVal.lshrInPlace(ShiftAmt);
16337330f729Sjoerg // it could be DstBitSize == SrcBitSize, so check it
16347330f729Sjoerg if (DstBitSize < SrcBitSize)
16357330f729Sjoerg Elt.IntVal = Elt.IntVal.trunc(DstBitSize);
16367330f729Sjoerg ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
16377330f729Sjoerg TempDst.AggregateVal.push_back(Elt);
16387330f729Sjoerg }
16397330f729Sjoerg }
16407330f729Sjoerg }
16417330f729Sjoerg
16427330f729Sjoerg // convert result from integer to specified type
1643*82d56013Sjoerg if (isa<VectorType>(DstTy)) {
16447330f729Sjoerg if (DstElemTy->isDoubleTy()) {
16457330f729Sjoerg Dest.AggregateVal.resize(DstNum);
16467330f729Sjoerg for (unsigned i = 0; i < DstNum; i++)
16477330f729Sjoerg Dest.AggregateVal[i].DoubleVal =
16487330f729Sjoerg TempDst.AggregateVal[i].IntVal.bitsToDouble();
16497330f729Sjoerg } else if (DstElemTy->isFloatTy()) {
16507330f729Sjoerg Dest.AggregateVal.resize(DstNum);
16517330f729Sjoerg for (unsigned i = 0; i < DstNum; i++)
16527330f729Sjoerg Dest.AggregateVal[i].FloatVal =
16537330f729Sjoerg TempDst.AggregateVal[i].IntVal.bitsToFloat();
16547330f729Sjoerg } else {
16557330f729Sjoerg Dest = TempDst;
16567330f729Sjoerg }
16577330f729Sjoerg } else {
16587330f729Sjoerg if (DstElemTy->isDoubleTy())
16597330f729Sjoerg Dest.DoubleVal = TempDst.AggregateVal[0].IntVal.bitsToDouble();
16607330f729Sjoerg else if (DstElemTy->isFloatTy()) {
16617330f729Sjoerg Dest.FloatVal = TempDst.AggregateVal[0].IntVal.bitsToFloat();
16627330f729Sjoerg } else {
16637330f729Sjoerg Dest.IntVal = TempDst.AggregateVal[0].IntVal;
16647330f729Sjoerg }
16657330f729Sjoerg }
1666*82d56013Sjoerg } else { // if (isa<VectorType>(SrcTy)) || isa<VectorType>(DstTy))
16677330f729Sjoerg
16687330f729Sjoerg // scalar src bitcast to scalar dst
16697330f729Sjoerg if (DstTy->isPointerTy()) {
16707330f729Sjoerg assert(SrcTy->isPointerTy() && "Invalid BitCast");
16717330f729Sjoerg Dest.PointerVal = Src.PointerVal;
16727330f729Sjoerg } else if (DstTy->isIntegerTy()) {
16737330f729Sjoerg if (SrcTy->isFloatTy())
16747330f729Sjoerg Dest.IntVal = APInt::floatToBits(Src.FloatVal);
16757330f729Sjoerg else if (SrcTy->isDoubleTy()) {
16767330f729Sjoerg Dest.IntVal = APInt::doubleToBits(Src.DoubleVal);
16777330f729Sjoerg } else if (SrcTy->isIntegerTy()) {
16787330f729Sjoerg Dest.IntVal = Src.IntVal;
16797330f729Sjoerg } else {
16807330f729Sjoerg llvm_unreachable("Invalid BitCast");
16817330f729Sjoerg }
16827330f729Sjoerg } else if (DstTy->isFloatTy()) {
16837330f729Sjoerg if (SrcTy->isIntegerTy())
16847330f729Sjoerg Dest.FloatVal = Src.IntVal.bitsToFloat();
16857330f729Sjoerg else {
16867330f729Sjoerg Dest.FloatVal = Src.FloatVal;
16877330f729Sjoerg }
16887330f729Sjoerg } else if (DstTy->isDoubleTy()) {
16897330f729Sjoerg if (SrcTy->isIntegerTy())
16907330f729Sjoerg Dest.DoubleVal = Src.IntVal.bitsToDouble();
16917330f729Sjoerg else {
16927330f729Sjoerg Dest.DoubleVal = Src.DoubleVal;
16937330f729Sjoerg }
16947330f729Sjoerg } else {
16957330f729Sjoerg llvm_unreachable("Invalid Bitcast");
16967330f729Sjoerg }
16977330f729Sjoerg }
16987330f729Sjoerg
16997330f729Sjoerg return Dest;
17007330f729Sjoerg }
17017330f729Sjoerg
visitTruncInst(TruncInst & I)17027330f729Sjoerg void Interpreter::visitTruncInst(TruncInst &I) {
17037330f729Sjoerg ExecutionContext &SF = ECStack.back();
17047330f729Sjoerg SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
17057330f729Sjoerg }
17067330f729Sjoerg
visitSExtInst(SExtInst & I)17077330f729Sjoerg void Interpreter::visitSExtInst(SExtInst &I) {
17087330f729Sjoerg ExecutionContext &SF = ECStack.back();
17097330f729Sjoerg SetValue(&I, executeSExtInst(I.getOperand(0), I.getType(), SF), SF);
17107330f729Sjoerg }
17117330f729Sjoerg
visitZExtInst(ZExtInst & I)17127330f729Sjoerg void Interpreter::visitZExtInst(ZExtInst &I) {
17137330f729Sjoerg ExecutionContext &SF = ECStack.back();
17147330f729Sjoerg SetValue(&I, executeZExtInst(I.getOperand(0), I.getType(), SF), SF);
17157330f729Sjoerg }
17167330f729Sjoerg
visitFPTruncInst(FPTruncInst & I)17177330f729Sjoerg void Interpreter::visitFPTruncInst(FPTruncInst &I) {
17187330f729Sjoerg ExecutionContext &SF = ECStack.back();
17197330f729Sjoerg SetValue(&I, executeFPTruncInst(I.getOperand(0), I.getType(), SF), SF);
17207330f729Sjoerg }
17217330f729Sjoerg
visitFPExtInst(FPExtInst & I)17227330f729Sjoerg void Interpreter::visitFPExtInst(FPExtInst &I) {
17237330f729Sjoerg ExecutionContext &SF = ECStack.back();
17247330f729Sjoerg SetValue(&I, executeFPExtInst(I.getOperand(0), I.getType(), SF), SF);
17257330f729Sjoerg }
17267330f729Sjoerg
visitUIToFPInst(UIToFPInst & I)17277330f729Sjoerg void Interpreter::visitUIToFPInst(UIToFPInst &I) {
17287330f729Sjoerg ExecutionContext &SF = ECStack.back();
17297330f729Sjoerg SetValue(&I, executeUIToFPInst(I.getOperand(0), I.getType(), SF), SF);
17307330f729Sjoerg }
17317330f729Sjoerg
visitSIToFPInst(SIToFPInst & I)17327330f729Sjoerg void Interpreter::visitSIToFPInst(SIToFPInst &I) {
17337330f729Sjoerg ExecutionContext &SF = ECStack.back();
17347330f729Sjoerg SetValue(&I, executeSIToFPInst(I.getOperand(0), I.getType(), SF), SF);
17357330f729Sjoerg }
17367330f729Sjoerg
visitFPToUIInst(FPToUIInst & I)17377330f729Sjoerg void Interpreter::visitFPToUIInst(FPToUIInst &I) {
17387330f729Sjoerg ExecutionContext &SF = ECStack.back();
17397330f729Sjoerg SetValue(&I, executeFPToUIInst(I.getOperand(0), I.getType(), SF), SF);
17407330f729Sjoerg }
17417330f729Sjoerg
visitFPToSIInst(FPToSIInst & I)17427330f729Sjoerg void Interpreter::visitFPToSIInst(FPToSIInst &I) {
17437330f729Sjoerg ExecutionContext &SF = ECStack.back();
17447330f729Sjoerg SetValue(&I, executeFPToSIInst(I.getOperand(0), I.getType(), SF), SF);
17457330f729Sjoerg }
17467330f729Sjoerg
visitPtrToIntInst(PtrToIntInst & I)17477330f729Sjoerg void Interpreter::visitPtrToIntInst(PtrToIntInst &I) {
17487330f729Sjoerg ExecutionContext &SF = ECStack.back();
17497330f729Sjoerg SetValue(&I, executePtrToIntInst(I.getOperand(0), I.getType(), SF), SF);
17507330f729Sjoerg }
17517330f729Sjoerg
visitIntToPtrInst(IntToPtrInst & I)17527330f729Sjoerg void Interpreter::visitIntToPtrInst(IntToPtrInst &I) {
17537330f729Sjoerg ExecutionContext &SF = ECStack.back();
17547330f729Sjoerg SetValue(&I, executeIntToPtrInst(I.getOperand(0), I.getType(), SF), SF);
17557330f729Sjoerg }
17567330f729Sjoerg
visitBitCastInst(BitCastInst & I)17577330f729Sjoerg void Interpreter::visitBitCastInst(BitCastInst &I) {
17587330f729Sjoerg ExecutionContext &SF = ECStack.back();
17597330f729Sjoerg SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
17607330f729Sjoerg }
17617330f729Sjoerg
17627330f729Sjoerg #define IMPLEMENT_VAARG(TY) \
17637330f729Sjoerg case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
17647330f729Sjoerg
visitVAArgInst(VAArgInst & I)17657330f729Sjoerg void Interpreter::visitVAArgInst(VAArgInst &I) {
17667330f729Sjoerg ExecutionContext &SF = ECStack.back();
17677330f729Sjoerg
17687330f729Sjoerg // Get the incoming valist parameter. LLI treats the valist as a
17697330f729Sjoerg // (ec-stack-depth var-arg-index) pair.
17707330f729Sjoerg GenericValue VAList = getOperandValue(I.getOperand(0), SF);
17717330f729Sjoerg GenericValue Dest;
17727330f729Sjoerg GenericValue Src = ECStack[VAList.UIntPairVal.first]
17737330f729Sjoerg .VarArgs[VAList.UIntPairVal.second];
17747330f729Sjoerg Type *Ty = I.getType();
17757330f729Sjoerg switch (Ty->getTypeID()) {
17767330f729Sjoerg case Type::IntegerTyID:
17777330f729Sjoerg Dest.IntVal = Src.IntVal;
17787330f729Sjoerg break;
17797330f729Sjoerg IMPLEMENT_VAARG(Pointer);
17807330f729Sjoerg IMPLEMENT_VAARG(Float);
17817330f729Sjoerg IMPLEMENT_VAARG(Double);
17827330f729Sjoerg default:
17837330f729Sjoerg dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
17847330f729Sjoerg llvm_unreachable(nullptr);
17857330f729Sjoerg }
17867330f729Sjoerg
17877330f729Sjoerg // Set the Value of this Instruction.
17887330f729Sjoerg SetValue(&I, Dest, SF);
17897330f729Sjoerg
17907330f729Sjoerg // Move the pointer to the next vararg.
17917330f729Sjoerg ++VAList.UIntPairVal.second;
17927330f729Sjoerg }
17937330f729Sjoerg
visitExtractElementInst(ExtractElementInst & I)17947330f729Sjoerg void Interpreter::visitExtractElementInst(ExtractElementInst &I) {
17957330f729Sjoerg ExecutionContext &SF = ECStack.back();
17967330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
17977330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
17987330f729Sjoerg GenericValue Dest;
17997330f729Sjoerg
18007330f729Sjoerg Type *Ty = I.getType();
18017330f729Sjoerg const unsigned indx = unsigned(Src2.IntVal.getZExtValue());
18027330f729Sjoerg
18037330f729Sjoerg if(Src1.AggregateVal.size() > indx) {
18047330f729Sjoerg switch (Ty->getTypeID()) {
18057330f729Sjoerg default:
18067330f729Sjoerg dbgs() << "Unhandled destination type for extractelement instruction: "
18077330f729Sjoerg << *Ty << "\n";
18087330f729Sjoerg llvm_unreachable(nullptr);
18097330f729Sjoerg break;
18107330f729Sjoerg case Type::IntegerTyID:
18117330f729Sjoerg Dest.IntVal = Src1.AggregateVal[indx].IntVal;
18127330f729Sjoerg break;
18137330f729Sjoerg case Type::FloatTyID:
18147330f729Sjoerg Dest.FloatVal = Src1.AggregateVal[indx].FloatVal;
18157330f729Sjoerg break;
18167330f729Sjoerg case Type::DoubleTyID:
18177330f729Sjoerg Dest.DoubleVal = Src1.AggregateVal[indx].DoubleVal;
18187330f729Sjoerg break;
18197330f729Sjoerg }
18207330f729Sjoerg } else {
18217330f729Sjoerg dbgs() << "Invalid index in extractelement instruction\n";
18227330f729Sjoerg }
18237330f729Sjoerg
18247330f729Sjoerg SetValue(&I, Dest, SF);
18257330f729Sjoerg }
18267330f729Sjoerg
visitInsertElementInst(InsertElementInst & I)18277330f729Sjoerg void Interpreter::visitInsertElementInst(InsertElementInst &I) {
18287330f729Sjoerg ExecutionContext &SF = ECStack.back();
18297330f729Sjoerg VectorType *Ty = cast<VectorType>(I.getType());
18307330f729Sjoerg
18317330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
18327330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
18337330f729Sjoerg GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
18347330f729Sjoerg GenericValue Dest;
18357330f729Sjoerg
18367330f729Sjoerg Type *TyContained = Ty->getElementType();
18377330f729Sjoerg
18387330f729Sjoerg const unsigned indx = unsigned(Src3.IntVal.getZExtValue());
18397330f729Sjoerg Dest.AggregateVal = Src1.AggregateVal;
18407330f729Sjoerg
18417330f729Sjoerg if(Src1.AggregateVal.size() <= indx)
18427330f729Sjoerg llvm_unreachable("Invalid index in insertelement instruction");
18437330f729Sjoerg switch (TyContained->getTypeID()) {
18447330f729Sjoerg default:
18457330f729Sjoerg llvm_unreachable("Unhandled dest type for insertelement instruction");
18467330f729Sjoerg case Type::IntegerTyID:
18477330f729Sjoerg Dest.AggregateVal[indx].IntVal = Src2.IntVal;
18487330f729Sjoerg break;
18497330f729Sjoerg case Type::FloatTyID:
18507330f729Sjoerg Dest.AggregateVal[indx].FloatVal = Src2.FloatVal;
18517330f729Sjoerg break;
18527330f729Sjoerg case Type::DoubleTyID:
18537330f729Sjoerg Dest.AggregateVal[indx].DoubleVal = Src2.DoubleVal;
18547330f729Sjoerg break;
18557330f729Sjoerg }
18567330f729Sjoerg SetValue(&I, Dest, SF);
18577330f729Sjoerg }
18587330f729Sjoerg
visitShuffleVectorInst(ShuffleVectorInst & I)18597330f729Sjoerg void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){
18607330f729Sjoerg ExecutionContext &SF = ECStack.back();
18617330f729Sjoerg
18627330f729Sjoerg VectorType *Ty = cast<VectorType>(I.getType());
18637330f729Sjoerg
18647330f729Sjoerg GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
18657330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
18667330f729Sjoerg GenericValue Dest;
18677330f729Sjoerg
18687330f729Sjoerg // There is no need to check types of src1 and src2, because the compiled
18697330f729Sjoerg // bytecode can't contain different types for src1 and src2 for a
18707330f729Sjoerg // shufflevector instruction.
18717330f729Sjoerg
18727330f729Sjoerg Type *TyContained = Ty->getElementType();
18737330f729Sjoerg unsigned src1Size = (unsigned)Src1.AggregateVal.size();
18747330f729Sjoerg unsigned src2Size = (unsigned)Src2.AggregateVal.size();
1875*82d56013Sjoerg unsigned src3Size = I.getShuffleMask().size();
18767330f729Sjoerg
18777330f729Sjoerg Dest.AggregateVal.resize(src3Size);
18787330f729Sjoerg
18797330f729Sjoerg switch (TyContained->getTypeID()) {
18807330f729Sjoerg default:
18817330f729Sjoerg llvm_unreachable("Unhandled dest type for insertelement instruction");
18827330f729Sjoerg break;
18837330f729Sjoerg case Type::IntegerTyID:
18847330f729Sjoerg for( unsigned i=0; i<src3Size; i++) {
1885*82d56013Sjoerg unsigned j = std::max(0, I.getMaskValue(i));
18867330f729Sjoerg if(j < src1Size)
18877330f729Sjoerg Dest.AggregateVal[i].IntVal = Src1.AggregateVal[j].IntVal;
18887330f729Sjoerg else if(j < src1Size + src2Size)
18897330f729Sjoerg Dest.AggregateVal[i].IntVal = Src2.AggregateVal[j-src1Size].IntVal;
18907330f729Sjoerg else
18917330f729Sjoerg // The selector may not be greater than sum of lengths of first and
18927330f729Sjoerg // second operands and llasm should not allow situation like
18937330f729Sjoerg // %tmp = shufflevector <2 x i32> <i32 3, i32 4>, <2 x i32> undef,
18947330f729Sjoerg // <2 x i32> < i32 0, i32 5 >,
18957330f729Sjoerg // where i32 5 is invalid, but let it be additional check here:
18967330f729Sjoerg llvm_unreachable("Invalid mask in shufflevector instruction");
18977330f729Sjoerg }
18987330f729Sjoerg break;
18997330f729Sjoerg case Type::FloatTyID:
19007330f729Sjoerg for( unsigned i=0; i<src3Size; i++) {
1901*82d56013Sjoerg unsigned j = std::max(0, I.getMaskValue(i));
19027330f729Sjoerg if(j < src1Size)
19037330f729Sjoerg Dest.AggregateVal[i].FloatVal = Src1.AggregateVal[j].FloatVal;
19047330f729Sjoerg else if(j < src1Size + src2Size)
19057330f729Sjoerg Dest.AggregateVal[i].FloatVal = Src2.AggregateVal[j-src1Size].FloatVal;
19067330f729Sjoerg else
19077330f729Sjoerg llvm_unreachable("Invalid mask in shufflevector instruction");
19087330f729Sjoerg }
19097330f729Sjoerg break;
19107330f729Sjoerg case Type::DoubleTyID:
19117330f729Sjoerg for( unsigned i=0; i<src3Size; i++) {
1912*82d56013Sjoerg unsigned j = std::max(0, I.getMaskValue(i));
19137330f729Sjoerg if(j < src1Size)
19147330f729Sjoerg Dest.AggregateVal[i].DoubleVal = Src1.AggregateVal[j].DoubleVal;
19157330f729Sjoerg else if(j < src1Size + src2Size)
19167330f729Sjoerg Dest.AggregateVal[i].DoubleVal =
19177330f729Sjoerg Src2.AggregateVal[j-src1Size].DoubleVal;
19187330f729Sjoerg else
19197330f729Sjoerg llvm_unreachable("Invalid mask in shufflevector instruction");
19207330f729Sjoerg }
19217330f729Sjoerg break;
19227330f729Sjoerg }
19237330f729Sjoerg SetValue(&I, Dest, SF);
19247330f729Sjoerg }
19257330f729Sjoerg
visitExtractValueInst(ExtractValueInst & I)19267330f729Sjoerg void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
19277330f729Sjoerg ExecutionContext &SF = ECStack.back();
19287330f729Sjoerg Value *Agg = I.getAggregateOperand();
19297330f729Sjoerg GenericValue Dest;
19307330f729Sjoerg GenericValue Src = getOperandValue(Agg, SF);
19317330f729Sjoerg
19327330f729Sjoerg ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
19337330f729Sjoerg unsigned Num = I.getNumIndices();
19347330f729Sjoerg GenericValue *pSrc = &Src;
19357330f729Sjoerg
19367330f729Sjoerg for (unsigned i = 0 ; i < Num; ++i) {
19377330f729Sjoerg pSrc = &pSrc->AggregateVal[*IdxBegin];
19387330f729Sjoerg ++IdxBegin;
19397330f729Sjoerg }
19407330f729Sjoerg
19417330f729Sjoerg Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
19427330f729Sjoerg switch (IndexedType->getTypeID()) {
19437330f729Sjoerg default:
19447330f729Sjoerg llvm_unreachable("Unhandled dest type for extractelement instruction");
19457330f729Sjoerg break;
19467330f729Sjoerg case Type::IntegerTyID:
19477330f729Sjoerg Dest.IntVal = pSrc->IntVal;
19487330f729Sjoerg break;
19497330f729Sjoerg case Type::FloatTyID:
19507330f729Sjoerg Dest.FloatVal = pSrc->FloatVal;
19517330f729Sjoerg break;
19527330f729Sjoerg case Type::DoubleTyID:
19537330f729Sjoerg Dest.DoubleVal = pSrc->DoubleVal;
19547330f729Sjoerg break;
19557330f729Sjoerg case Type::ArrayTyID:
19567330f729Sjoerg case Type::StructTyID:
1957*82d56013Sjoerg case Type::FixedVectorTyID:
1958*82d56013Sjoerg case Type::ScalableVectorTyID:
19597330f729Sjoerg Dest.AggregateVal = pSrc->AggregateVal;
19607330f729Sjoerg break;
19617330f729Sjoerg case Type::PointerTyID:
19627330f729Sjoerg Dest.PointerVal = pSrc->PointerVal;
19637330f729Sjoerg break;
19647330f729Sjoerg }
19657330f729Sjoerg
19667330f729Sjoerg SetValue(&I, Dest, SF);
19677330f729Sjoerg }
19687330f729Sjoerg
visitInsertValueInst(InsertValueInst & I)19697330f729Sjoerg void Interpreter::visitInsertValueInst(InsertValueInst &I) {
19707330f729Sjoerg
19717330f729Sjoerg ExecutionContext &SF = ECStack.back();
19727330f729Sjoerg Value *Agg = I.getAggregateOperand();
19737330f729Sjoerg
19747330f729Sjoerg GenericValue Src1 = getOperandValue(Agg, SF);
19757330f729Sjoerg GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
19767330f729Sjoerg GenericValue Dest = Src1; // Dest is a slightly changed Src1
19777330f729Sjoerg
19787330f729Sjoerg ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
19797330f729Sjoerg unsigned Num = I.getNumIndices();
19807330f729Sjoerg
19817330f729Sjoerg GenericValue *pDest = &Dest;
19827330f729Sjoerg for (unsigned i = 0 ; i < Num; ++i) {
19837330f729Sjoerg pDest = &pDest->AggregateVal[*IdxBegin];
19847330f729Sjoerg ++IdxBegin;
19857330f729Sjoerg }
19867330f729Sjoerg // pDest points to the target value in the Dest now
19877330f729Sjoerg
19887330f729Sjoerg Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
19897330f729Sjoerg
19907330f729Sjoerg switch (IndexedType->getTypeID()) {
19917330f729Sjoerg default:
19927330f729Sjoerg llvm_unreachable("Unhandled dest type for insertelement instruction");
19937330f729Sjoerg break;
19947330f729Sjoerg case Type::IntegerTyID:
19957330f729Sjoerg pDest->IntVal = Src2.IntVal;
19967330f729Sjoerg break;
19977330f729Sjoerg case Type::FloatTyID:
19987330f729Sjoerg pDest->FloatVal = Src2.FloatVal;
19997330f729Sjoerg break;
20007330f729Sjoerg case Type::DoubleTyID:
20017330f729Sjoerg pDest->DoubleVal = Src2.DoubleVal;
20027330f729Sjoerg break;
20037330f729Sjoerg case Type::ArrayTyID:
20047330f729Sjoerg case Type::StructTyID:
2005*82d56013Sjoerg case Type::FixedVectorTyID:
2006*82d56013Sjoerg case Type::ScalableVectorTyID:
20077330f729Sjoerg pDest->AggregateVal = Src2.AggregateVal;
20087330f729Sjoerg break;
20097330f729Sjoerg case Type::PointerTyID:
20107330f729Sjoerg pDest->PointerVal = Src2.PointerVal;
20117330f729Sjoerg break;
20127330f729Sjoerg }
20137330f729Sjoerg
20147330f729Sjoerg SetValue(&I, Dest, SF);
20157330f729Sjoerg }
20167330f729Sjoerg
getConstantExprValue(ConstantExpr * CE,ExecutionContext & SF)20177330f729Sjoerg GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
20187330f729Sjoerg ExecutionContext &SF) {
20197330f729Sjoerg switch (CE->getOpcode()) {
20207330f729Sjoerg case Instruction::Trunc:
20217330f729Sjoerg return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
20227330f729Sjoerg case Instruction::ZExt:
20237330f729Sjoerg return executeZExtInst(CE->getOperand(0), CE->getType(), SF);
20247330f729Sjoerg case Instruction::SExt:
20257330f729Sjoerg return executeSExtInst(CE->getOperand(0), CE->getType(), SF);
20267330f729Sjoerg case Instruction::FPTrunc:
20277330f729Sjoerg return executeFPTruncInst(CE->getOperand(0), CE->getType(), SF);
20287330f729Sjoerg case Instruction::FPExt:
20297330f729Sjoerg return executeFPExtInst(CE->getOperand(0), CE->getType(), SF);
20307330f729Sjoerg case Instruction::UIToFP:
20317330f729Sjoerg return executeUIToFPInst(CE->getOperand(0), CE->getType(), SF);
20327330f729Sjoerg case Instruction::SIToFP:
20337330f729Sjoerg return executeSIToFPInst(CE->getOperand(0), CE->getType(), SF);
20347330f729Sjoerg case Instruction::FPToUI:
20357330f729Sjoerg return executeFPToUIInst(CE->getOperand(0), CE->getType(), SF);
20367330f729Sjoerg case Instruction::FPToSI:
20377330f729Sjoerg return executeFPToSIInst(CE->getOperand(0), CE->getType(), SF);
20387330f729Sjoerg case Instruction::PtrToInt:
20397330f729Sjoerg return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
20407330f729Sjoerg case Instruction::IntToPtr:
20417330f729Sjoerg return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
20427330f729Sjoerg case Instruction::BitCast:
20437330f729Sjoerg return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
20447330f729Sjoerg case Instruction::GetElementPtr:
20457330f729Sjoerg return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
20467330f729Sjoerg gep_type_end(CE), SF);
20477330f729Sjoerg case Instruction::FCmp:
20487330f729Sjoerg case Instruction::ICmp:
20497330f729Sjoerg return executeCmpInst(CE->getPredicate(),
20507330f729Sjoerg getOperandValue(CE->getOperand(0), SF),
20517330f729Sjoerg getOperandValue(CE->getOperand(1), SF),
20527330f729Sjoerg CE->getOperand(0)->getType());
20537330f729Sjoerg case Instruction::Select:
20547330f729Sjoerg return executeSelectInst(getOperandValue(CE->getOperand(0), SF),
20557330f729Sjoerg getOperandValue(CE->getOperand(1), SF),
20567330f729Sjoerg getOperandValue(CE->getOperand(2), SF),
20577330f729Sjoerg CE->getOperand(0)->getType());
20587330f729Sjoerg default :
20597330f729Sjoerg break;
20607330f729Sjoerg }
20617330f729Sjoerg
20627330f729Sjoerg // The cases below here require a GenericValue parameter for the result
20637330f729Sjoerg // so we initialize one, compute it and then return it.
20647330f729Sjoerg GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
20657330f729Sjoerg GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
20667330f729Sjoerg GenericValue Dest;
20677330f729Sjoerg Type * Ty = CE->getOperand(0)->getType();
20687330f729Sjoerg switch (CE->getOpcode()) {
20697330f729Sjoerg case Instruction::Add: Dest.IntVal = Op0.IntVal + Op1.IntVal; break;
20707330f729Sjoerg case Instruction::Sub: Dest.IntVal = Op0.IntVal - Op1.IntVal; break;
20717330f729Sjoerg case Instruction::Mul: Dest.IntVal = Op0.IntVal * Op1.IntVal; break;
20727330f729Sjoerg case Instruction::FAdd: executeFAddInst(Dest, Op0, Op1, Ty); break;
20737330f729Sjoerg case Instruction::FSub: executeFSubInst(Dest, Op0, Op1, Ty); break;
20747330f729Sjoerg case Instruction::FMul: executeFMulInst(Dest, Op0, Op1, Ty); break;
20757330f729Sjoerg case Instruction::FDiv: executeFDivInst(Dest, Op0, Op1, Ty); break;
20767330f729Sjoerg case Instruction::FRem: executeFRemInst(Dest, Op0, Op1, Ty); break;
20777330f729Sjoerg case Instruction::SDiv: Dest.IntVal = Op0.IntVal.sdiv(Op1.IntVal); break;
20787330f729Sjoerg case Instruction::UDiv: Dest.IntVal = Op0.IntVal.udiv(Op1.IntVal); break;
20797330f729Sjoerg case Instruction::URem: Dest.IntVal = Op0.IntVal.urem(Op1.IntVal); break;
20807330f729Sjoerg case Instruction::SRem: Dest.IntVal = Op0.IntVal.srem(Op1.IntVal); break;
20817330f729Sjoerg case Instruction::And: Dest.IntVal = Op0.IntVal & Op1.IntVal; break;
20827330f729Sjoerg case Instruction::Or: Dest.IntVal = Op0.IntVal | Op1.IntVal; break;
20837330f729Sjoerg case Instruction::Xor: Dest.IntVal = Op0.IntVal ^ Op1.IntVal; break;
20847330f729Sjoerg case Instruction::Shl:
20857330f729Sjoerg Dest.IntVal = Op0.IntVal.shl(Op1.IntVal.getZExtValue());
20867330f729Sjoerg break;
20877330f729Sjoerg case Instruction::LShr:
20887330f729Sjoerg Dest.IntVal = Op0.IntVal.lshr(Op1.IntVal.getZExtValue());
20897330f729Sjoerg break;
20907330f729Sjoerg case Instruction::AShr:
20917330f729Sjoerg Dest.IntVal = Op0.IntVal.ashr(Op1.IntVal.getZExtValue());
20927330f729Sjoerg break;
20937330f729Sjoerg default:
20947330f729Sjoerg dbgs() << "Unhandled ConstantExpr: " << *CE << "\n";
20957330f729Sjoerg llvm_unreachable("Unhandled ConstantExpr");
20967330f729Sjoerg }
20977330f729Sjoerg return Dest;
20987330f729Sjoerg }
20997330f729Sjoerg
getOperandValue(Value * V,ExecutionContext & SF)21007330f729Sjoerg GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
21017330f729Sjoerg if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
21027330f729Sjoerg return getConstantExprValue(CE, SF);
21037330f729Sjoerg } else if (Constant *CPV = dyn_cast<Constant>(V)) {
21047330f729Sjoerg return getConstantValue(CPV);
21057330f729Sjoerg } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
21067330f729Sjoerg return PTOGV(getPointerToGlobal(GV));
21077330f729Sjoerg } else {
21087330f729Sjoerg return SF.Values[V];
21097330f729Sjoerg }
21107330f729Sjoerg }
21117330f729Sjoerg
21127330f729Sjoerg //===----------------------------------------------------------------------===//
21137330f729Sjoerg // Dispatch and Execution Code
21147330f729Sjoerg //===----------------------------------------------------------------------===//
21157330f729Sjoerg
21167330f729Sjoerg //===----------------------------------------------------------------------===//
21177330f729Sjoerg // callFunction - Execute the specified function...
21187330f729Sjoerg //
callFunction(Function * F,ArrayRef<GenericValue> ArgVals)21197330f729Sjoerg void Interpreter::callFunction(Function *F, ArrayRef<GenericValue> ArgVals) {
2120*82d56013Sjoerg assert((ECStack.empty() || !ECStack.back().Caller ||
2121*82d56013Sjoerg ECStack.back().Caller->arg_size() == ArgVals.size()) &&
21227330f729Sjoerg "Incorrect number of arguments passed into function call!");
21237330f729Sjoerg // Make a new stack frame... and fill it in.
21247330f729Sjoerg ECStack.emplace_back();
21257330f729Sjoerg ExecutionContext &StackFrame = ECStack.back();
21267330f729Sjoerg StackFrame.CurFunction = F;
21277330f729Sjoerg
21287330f729Sjoerg // Special handling for external functions.
21297330f729Sjoerg if (F->isDeclaration()) {
21307330f729Sjoerg GenericValue Result = callExternalFunction (F, ArgVals);
21317330f729Sjoerg // Simulate a 'ret' instruction of the appropriate type.
21327330f729Sjoerg popStackAndReturnValueToCaller (F->getReturnType (), Result);
21337330f729Sjoerg return;
21347330f729Sjoerg }
21357330f729Sjoerg
21367330f729Sjoerg // Get pointers to first LLVM BB & Instruction in function.
21377330f729Sjoerg StackFrame.CurBB = &F->front();
21387330f729Sjoerg StackFrame.CurInst = StackFrame.CurBB->begin();
21397330f729Sjoerg
21407330f729Sjoerg // Run through the function arguments and initialize their values...
21417330f729Sjoerg assert((ArgVals.size() == F->arg_size() ||
21427330f729Sjoerg (ArgVals.size() > F->arg_size() && F->getFunctionType()->isVarArg()))&&
21437330f729Sjoerg "Invalid number of values passed to function invocation!");
21447330f729Sjoerg
21457330f729Sjoerg // Handle non-varargs arguments...
21467330f729Sjoerg unsigned i = 0;
21477330f729Sjoerg for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
21487330f729Sjoerg AI != E; ++AI, ++i)
21497330f729Sjoerg SetValue(&*AI, ArgVals[i], StackFrame);
21507330f729Sjoerg
21517330f729Sjoerg // Handle varargs arguments...
21527330f729Sjoerg StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end());
21537330f729Sjoerg }
21547330f729Sjoerg
21557330f729Sjoerg
run()21567330f729Sjoerg void Interpreter::run() {
21577330f729Sjoerg while (!ECStack.empty()) {
21587330f729Sjoerg // Interpret a single instruction & increment the "PC".
21597330f729Sjoerg ExecutionContext &SF = ECStack.back(); // Current stack frame
21607330f729Sjoerg Instruction &I = *SF.CurInst++; // Increment before execute
21617330f729Sjoerg
21627330f729Sjoerg // Track the number of dynamic instructions executed.
21637330f729Sjoerg ++NumDynamicInsts;
21647330f729Sjoerg
21657330f729Sjoerg LLVM_DEBUG(dbgs() << "About to interpret: " << I << "\n");
21667330f729Sjoerg visit(I); // Dispatch to one of the visit* methods...
21677330f729Sjoerg }
21687330f729Sjoerg }
2169