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