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