1*9880d681SAndroid Build Coastguard Worker //===-- Execution.cpp - Implement code to simulate the program ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the actual instruction interpreter.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "Interpreter.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/APInt.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/IntrinsicLowering.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GetElementPtrTypeIterator.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
27*9880d681SAndroid Build Coastguard Worker #include <algorithm>
28*9880d681SAndroid Build Coastguard Worker #include <cmath>
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "interpreter"
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
36*9880d681SAndroid Build Coastguard Worker cl::desc("make the interpreter print every volatile load and store"));
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
39*9880d681SAndroid Build Coastguard Worker // Various Helper Functions
40*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
41*9880d681SAndroid Build Coastguard Worker
SetValue(Value * V,GenericValue Val,ExecutionContext & SF)42*9880d681SAndroid Build Coastguard Worker static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
43*9880d681SAndroid Build Coastguard Worker SF.Values[V] = Val;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
47*9880d681SAndroid Build Coastguard Worker // Binary Instruction Implementations
48*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
51*9880d681SAndroid Build Coastguard Worker case Type::TY##TyID: \
52*9880d681SAndroid Build Coastguard Worker Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
53*9880d681SAndroid Build Coastguard Worker break
54*9880d681SAndroid Build Coastguard Worker
executeFAddInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)55*9880d681SAndroid Build Coastguard Worker static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
56*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
57*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
58*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(+, Float);
59*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(+, Double);
60*9880d681SAndroid Build Coastguard Worker default:
61*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
62*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
executeFSubInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)66*9880d681SAndroid Build Coastguard Worker static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
67*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
68*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
69*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(-, Float);
70*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(-, Double);
71*9880d681SAndroid Build Coastguard Worker default:
72*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
73*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker
executeFMulInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)77*9880d681SAndroid Build Coastguard Worker static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
78*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
79*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
80*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(*, Float);
81*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(*, Double);
82*9880d681SAndroid Build Coastguard Worker default:
83*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
84*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
executeFDivInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)88*9880d681SAndroid Build Coastguard Worker static void executeFDivInst(GenericValue &Dest, GenericValue Src1,
89*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
90*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
91*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(/, Float);
92*9880d681SAndroid Build Coastguard Worker IMPLEMENT_BINARY_OPERATOR(/, Double);
93*9880d681SAndroid Build Coastguard Worker default:
94*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
95*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker
executeFRemInst(GenericValue & Dest,GenericValue Src1,GenericValue Src2,Type * Ty)99*9880d681SAndroid Build Coastguard Worker static void executeFRemInst(GenericValue &Dest, GenericValue Src1,
100*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
101*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
102*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
103*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal);
104*9880d681SAndroid Build Coastguard Worker break;
105*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
106*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal);
107*9880d681SAndroid Build Coastguard Worker break;
108*9880d681SAndroid Build Coastguard Worker default:
109*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
110*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_INTEGER_ICMP(OP, TY) \
115*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID: \
116*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \
117*9880d681SAndroid Build Coastguard Worker break;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY) \
120*9880d681SAndroid Build Coastguard Worker case Type::VectorTyID: { \
121*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
122*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
123*9880d681SAndroid Build Coastguard Worker for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
124*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1, \
125*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].IntVal.OP(Src2.AggregateVal[_i].IntVal));\
126*9880d681SAndroid Build Coastguard Worker } break;
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker // Handle pointers specially because they must be compared with only as much
129*9880d681SAndroid Build Coastguard Worker // width as the host has. We _do not_ want to be comparing 64 bit values when
130*9880d681SAndroid Build Coastguard Worker // running on a 32-bit target, otherwise the upper 32 bits might mess up
131*9880d681SAndroid Build Coastguard Worker // comparisons if they contain garbage.
132*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_POINTER_ICMP(OP) \
133*9880d681SAndroid Build Coastguard Worker case Type::PointerTyID: \
134*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,(void*)(intptr_t)Src1.PointerVal OP \
135*9880d681SAndroid Build Coastguard Worker (void*)(intptr_t)Src2.PointerVal); \
136*9880d681SAndroid Build Coastguard Worker break;
137*9880d681SAndroid Build Coastguard Worker
executeICMP_EQ(GenericValue Src1,GenericValue Src2,Type * Ty)138*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
139*9880d681SAndroid Build Coastguard Worker Type *Ty) {
140*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
141*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
142*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(eq,Ty);
143*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(eq,Ty);
144*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(==);
145*9880d681SAndroid Build Coastguard Worker default:
146*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
147*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker return Dest;
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker
executeICMP_NE(GenericValue Src1,GenericValue Src2,Type * Ty)152*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
153*9880d681SAndroid Build Coastguard Worker Type *Ty) {
154*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
155*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
156*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(ne,Ty);
157*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(ne,Ty);
158*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(!=);
159*9880d681SAndroid Build Coastguard Worker default:
160*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
161*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker return Dest;
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker
executeICMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)166*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
167*9880d681SAndroid Build Coastguard Worker Type *Ty) {
168*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
169*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
170*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(ult,Ty);
171*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(ult,Ty);
172*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(<);
173*9880d681SAndroid Build Coastguard Worker default:
174*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
175*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker return Dest;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
executeICMP_SLT(GenericValue Src1,GenericValue Src2,Type * Ty)180*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
181*9880d681SAndroid Build Coastguard Worker Type *Ty) {
182*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
183*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
184*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(slt,Ty);
185*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(slt,Ty);
186*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(<);
187*9880d681SAndroid Build Coastguard Worker default:
188*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
189*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker return Dest;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
executeICMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)194*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
195*9880d681SAndroid Build Coastguard Worker Type *Ty) {
196*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
197*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
198*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(ugt,Ty);
199*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(ugt,Ty);
200*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(>);
201*9880d681SAndroid Build Coastguard Worker default:
202*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
203*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker return Dest;
206*9880d681SAndroid Build Coastguard Worker }
207*9880d681SAndroid Build Coastguard Worker
executeICMP_SGT(GenericValue Src1,GenericValue Src2,Type * Ty)208*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
209*9880d681SAndroid Build Coastguard Worker Type *Ty) {
210*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
211*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
212*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(sgt,Ty);
213*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(sgt,Ty);
214*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(>);
215*9880d681SAndroid Build Coastguard Worker default:
216*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
217*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker return Dest;
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
executeICMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)222*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
223*9880d681SAndroid Build Coastguard Worker Type *Ty) {
224*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
225*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
226*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(ule,Ty);
227*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(ule,Ty);
228*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(<=);
229*9880d681SAndroid Build Coastguard Worker default:
230*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
231*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker return Dest;
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
executeICMP_SLE(GenericValue Src1,GenericValue Src2,Type * Ty)236*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
237*9880d681SAndroid Build Coastguard Worker Type *Ty) {
238*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
239*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
240*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(sle,Ty);
241*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(sle,Ty);
242*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(<=);
243*9880d681SAndroid Build Coastguard Worker default:
244*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
245*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
246*9880d681SAndroid Build Coastguard Worker }
247*9880d681SAndroid Build Coastguard Worker return Dest;
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
executeICMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)250*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
251*9880d681SAndroid Build Coastguard Worker Type *Ty) {
252*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
253*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
254*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(uge,Ty);
255*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(uge,Ty);
256*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(>=);
257*9880d681SAndroid Build Coastguard Worker default:
258*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
259*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker return Dest;
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
executeICMP_SGE(GenericValue Src1,GenericValue Src2,Type * Ty)264*9880d681SAndroid Build Coastguard Worker static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
265*9880d681SAndroid Build Coastguard Worker Type *Ty) {
266*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
267*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
268*9880d681SAndroid Build Coastguard Worker IMPLEMENT_INTEGER_ICMP(sge,Ty);
269*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_INTEGER_ICMP(sge,Ty);
270*9880d681SAndroid Build Coastguard Worker IMPLEMENT_POINTER_ICMP(>=);
271*9880d681SAndroid Build Coastguard Worker default:
272*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
273*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker return Dest;
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker
visitICmpInst(ICmpInst & I)278*9880d681SAndroid Build Coastguard Worker void Interpreter::visitICmpInst(ICmpInst &I) {
279*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
280*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getOperand(0)->getType();
281*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
282*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
283*9880d681SAndroid Build Coastguard Worker GenericValue R; // Result
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker switch (I.getPredicate()) {
286*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
287*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
288*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
289*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
290*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
291*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
292*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
293*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
294*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
295*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
296*9880d681SAndroid Build Coastguard Worker default:
297*9880d681SAndroid Build Coastguard Worker dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
298*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker SetValue(&I, R, SF);
302*9880d681SAndroid Build Coastguard Worker }
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_FCMP(OP, TY) \
305*9880d681SAndroid Build Coastguard Worker case Type::TY##TyID: \
306*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,Src1.TY##Val OP Src2.TY##Val); \
307*9880d681SAndroid Build Coastguard Worker break
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_VECTOR_FCMP_T(OP, TY) \
310*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
311*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
312*9880d681SAndroid Build Coastguard Worker for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
313*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1, \
314*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].TY##Val OP Src2.AggregateVal[_i].TY##Val);\
315*9880d681SAndroid Build Coastguard Worker break;
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_VECTOR_FCMP(OP) \
318*9880d681SAndroid Build Coastguard Worker case Type::VectorTyID: \
319*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
320*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
321*9880d681SAndroid Build Coastguard Worker } else { \
322*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
323*9880d681SAndroid Build Coastguard Worker }
324*9880d681SAndroid Build Coastguard Worker
executeFCMP_OEQ(GenericValue Src1,GenericValue Src2,Type * Ty)325*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
326*9880d681SAndroid Build Coastguard Worker Type *Ty) {
327*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
328*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
329*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(==, Float);
330*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(==, Double);
331*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(==);
332*9880d681SAndroid Build Coastguard Worker default:
333*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
334*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker return Dest;
337*9880d681SAndroid Build Coastguard Worker }
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_SCALAR_NANS(TY, X,Y) \
340*9880d681SAndroid Build Coastguard Worker if (TY->isFloatTy()) { \
341*9880d681SAndroid Build Coastguard Worker if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
342*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,false); \
343*9880d681SAndroid Build Coastguard Worker return Dest; \
344*9880d681SAndroid Build Coastguard Worker } \
345*9880d681SAndroid Build Coastguard Worker } else { \
346*9880d681SAndroid Build Coastguard Worker if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
347*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,false); \
348*9880d681SAndroid Build Coastguard Worker return Dest; \
349*9880d681SAndroid Build Coastguard Worker } \
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker #define MASK_VECTOR_NANS_T(X,Y, TZ, FLAG) \
353*9880d681SAndroid Build Coastguard Worker assert(X.AggregateVal.size() == Y.AggregateVal.size()); \
354*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( X.AggregateVal.size() ); \
355*9880d681SAndroid Build Coastguard Worker for( uint32_t _i=0;_i<X.AggregateVal.size();_i++) { \
356*9880d681SAndroid Build Coastguard Worker if (X.AggregateVal[_i].TZ##Val != X.AggregateVal[_i].TZ##Val || \
357*9880d681SAndroid Build Coastguard Worker Y.AggregateVal[_i].TZ##Val != Y.AggregateVal[_i].TZ##Val) \
358*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,FLAG); \
359*9880d681SAndroid Build Coastguard Worker else { \
360*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,!FLAG); \
361*9880d681SAndroid Build Coastguard Worker } \
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker #define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
365*9880d681SAndroid Build Coastguard Worker if (TY->isVectorTy()) { \
366*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
367*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
368*9880d681SAndroid Build Coastguard Worker } else { \
369*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
370*9880d681SAndroid Build Coastguard Worker } \
371*9880d681SAndroid Build Coastguard Worker } \
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker
executeFCMP_ONE(GenericValue Src1,GenericValue Src2,Type * Ty)375*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
376*9880d681SAndroid Build Coastguard Worker Type *Ty)
377*9880d681SAndroid Build Coastguard Worker {
378*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
379*9880d681SAndroid Build Coastguard Worker // if input is scalar value and Src1 or Src2 is NaN return false
380*9880d681SAndroid Build Coastguard Worker IMPLEMENT_SCALAR_NANS(Ty, Src1, Src2)
381*9880d681SAndroid Build Coastguard Worker // if vector input detect NaNs and fill mask
382*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, false)
383*9880d681SAndroid Build Coastguard Worker GenericValue DestMask = Dest;
384*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
385*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(!=, Float);
386*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(!=, Double);
387*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(!=);
388*9880d681SAndroid Build Coastguard Worker default:
389*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
390*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker // in vector case mask out NaN elements
393*9880d681SAndroid Build Coastguard Worker if (Ty->isVectorTy())
394*9880d681SAndroid Build Coastguard Worker for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
395*9880d681SAndroid Build Coastguard Worker if (DestMask.AggregateVal[_i].IntVal == false)
396*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,false);
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker return Dest;
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker
executeFCMP_OLE(GenericValue Src1,GenericValue Src2,Type * Ty)401*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
402*9880d681SAndroid Build Coastguard Worker Type *Ty) {
403*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
404*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
405*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(<=, Float);
406*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(<=, Double);
407*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(<=);
408*9880d681SAndroid Build Coastguard Worker default:
409*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
410*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
411*9880d681SAndroid Build Coastguard Worker }
412*9880d681SAndroid Build Coastguard Worker return Dest;
413*9880d681SAndroid Build Coastguard Worker }
414*9880d681SAndroid Build Coastguard Worker
executeFCMP_OGE(GenericValue Src1,GenericValue Src2,Type * Ty)415*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
416*9880d681SAndroid Build Coastguard Worker Type *Ty) {
417*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
418*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
419*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(>=, Float);
420*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(>=, Double);
421*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(>=);
422*9880d681SAndroid Build Coastguard Worker default:
423*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
424*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
425*9880d681SAndroid Build Coastguard Worker }
426*9880d681SAndroid Build Coastguard Worker return Dest;
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker
executeFCMP_OLT(GenericValue Src1,GenericValue Src2,Type * Ty)429*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
430*9880d681SAndroid Build Coastguard Worker Type *Ty) {
431*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
432*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
433*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(<, Float);
434*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(<, Double);
435*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(<);
436*9880d681SAndroid Build Coastguard Worker default:
437*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
438*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker return Dest;
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
executeFCMP_OGT(GenericValue Src1,GenericValue Src2,Type * Ty)443*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
444*9880d681SAndroid Build Coastguard Worker Type *Ty) {
445*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
446*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
447*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(>, Float);
448*9880d681SAndroid Build Coastguard Worker IMPLEMENT_FCMP(>, Double);
449*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_FCMP(>);
450*9880d681SAndroid Build Coastguard Worker default:
451*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
452*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
453*9880d681SAndroid Build Coastguard Worker }
454*9880d681SAndroid Build Coastguard Worker return Dest;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_UNORDERED(TY, X,Y) \
458*9880d681SAndroid Build Coastguard Worker if (TY->isFloatTy()) { \
459*9880d681SAndroid Build Coastguard Worker if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
460*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,true); \
461*9880d681SAndroid Build Coastguard Worker return Dest; \
462*9880d681SAndroid Build Coastguard Worker } \
463*9880d681SAndroid Build Coastguard Worker } else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
464*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,true); \
465*9880d681SAndroid Build Coastguard Worker return Dest; \
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
469*9880d681SAndroid Build Coastguard Worker if (TY->isVectorTy()) { \
470*9880d681SAndroid Build Coastguard Worker GenericValue DestMask = Dest; \
471*9880d681SAndroid Build Coastguard Worker Dest = FUNC(Src1, Src2, Ty); \
472*9880d681SAndroid Build Coastguard Worker for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
473*9880d681SAndroid Build Coastguard Worker if (DestMask.AggregateVal[_i].IntVal == true) \
474*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1, true); \
475*9880d681SAndroid Build Coastguard Worker return Dest; \
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker
executeFCMP_UEQ(GenericValue Src1,GenericValue Src2,Type * Ty)478*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
479*9880d681SAndroid Build Coastguard Worker Type *Ty) {
480*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
481*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
482*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
483*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OEQ)
484*9880d681SAndroid Build Coastguard Worker return executeFCMP_OEQ(Src1, Src2, Ty);
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker }
487*9880d681SAndroid Build Coastguard Worker
executeFCMP_UNE(GenericValue Src1,GenericValue Src2,Type * Ty)488*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2,
489*9880d681SAndroid Build Coastguard Worker Type *Ty) {
490*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
491*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
492*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
493*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_ONE)
494*9880d681SAndroid Build Coastguard Worker return executeFCMP_ONE(Src1, Src2, Ty);
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker
executeFCMP_ULE(GenericValue Src1,GenericValue Src2,Type * Ty)497*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2,
498*9880d681SAndroid Build Coastguard Worker Type *Ty) {
499*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
500*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
501*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
502*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLE)
503*9880d681SAndroid Build Coastguard Worker return executeFCMP_OLE(Src1, Src2, Ty);
504*9880d681SAndroid Build Coastguard Worker }
505*9880d681SAndroid Build Coastguard Worker
executeFCMP_UGE(GenericValue Src1,GenericValue Src2,Type * Ty)506*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2,
507*9880d681SAndroid Build Coastguard Worker Type *Ty) {
508*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
509*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
510*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
511*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGE)
512*9880d681SAndroid Build Coastguard Worker return executeFCMP_OGE(Src1, Src2, Ty);
513*9880d681SAndroid Build Coastguard Worker }
514*9880d681SAndroid Build Coastguard Worker
executeFCMP_ULT(GenericValue Src1,GenericValue Src2,Type * Ty)515*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2,
516*9880d681SAndroid Build Coastguard Worker Type *Ty) {
517*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
518*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
519*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
520*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLT)
521*9880d681SAndroid Build Coastguard Worker return executeFCMP_OLT(Src1, Src2, Ty);
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker
executeFCMP_UGT(GenericValue Src1,GenericValue Src2,Type * Ty)524*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2,
525*9880d681SAndroid Build Coastguard Worker Type *Ty) {
526*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
527*9880d681SAndroid Build Coastguard Worker IMPLEMENT_UNORDERED(Ty, Src1, Src2)
528*9880d681SAndroid Build Coastguard Worker MASK_VECTOR_NANS(Ty, Src1, Src2, true)
529*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGT)
530*9880d681SAndroid Build Coastguard Worker return executeFCMP_OGT(Src1, Src2, Ty);
531*9880d681SAndroid Build Coastguard Worker }
532*9880d681SAndroid Build Coastguard Worker
executeFCMP_ORD(GenericValue Src1,GenericValue Src2,Type * Ty)533*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
534*9880d681SAndroid Build Coastguard Worker Type *Ty) {
535*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
536*9880d681SAndroid Build Coastguard Worker if(Ty->isVectorTy()) {
537*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
538*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() );
539*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
540*9880d681SAndroid Build Coastguard Worker for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
541*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,
542*9880d681SAndroid Build Coastguard Worker ( (Src1.AggregateVal[_i].FloatVal ==
543*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].FloatVal) &&
544*9880d681SAndroid Build Coastguard Worker (Src2.AggregateVal[_i].FloatVal ==
545*9880d681SAndroid Build Coastguard Worker Src2.AggregateVal[_i].FloatVal)));
546*9880d681SAndroid Build Coastguard Worker } else {
547*9880d681SAndroid Build Coastguard Worker for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
548*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,
549*9880d681SAndroid Build Coastguard Worker ( (Src1.AggregateVal[_i].DoubleVal ==
550*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].DoubleVal) &&
551*9880d681SAndroid Build Coastguard Worker (Src2.AggregateVal[_i].DoubleVal ==
552*9880d681SAndroid Build Coastguard Worker Src2.AggregateVal[_i].DoubleVal)));
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker } else if (Ty->isFloatTy())
555*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,(Src1.FloatVal == Src1.FloatVal &&
556*9880d681SAndroid Build Coastguard Worker Src2.FloatVal == Src2.FloatVal));
557*9880d681SAndroid Build Coastguard Worker else {
558*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,(Src1.DoubleVal == Src1.DoubleVal &&
559*9880d681SAndroid Build Coastguard Worker Src2.DoubleVal == Src2.DoubleVal));
560*9880d681SAndroid Build Coastguard Worker }
561*9880d681SAndroid Build Coastguard Worker return Dest;
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker
executeFCMP_UNO(GenericValue Src1,GenericValue Src2,Type * Ty)564*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
565*9880d681SAndroid Build Coastguard Worker Type *Ty) {
566*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
567*9880d681SAndroid Build Coastguard Worker if(Ty->isVectorTy()) {
568*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
569*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() );
570*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
571*9880d681SAndroid Build Coastguard Worker for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
572*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,
573*9880d681SAndroid Build Coastguard Worker ( (Src1.AggregateVal[_i].FloatVal !=
574*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].FloatVal) ||
575*9880d681SAndroid Build Coastguard Worker (Src2.AggregateVal[_i].FloatVal !=
576*9880d681SAndroid Build Coastguard Worker Src2.AggregateVal[_i].FloatVal)));
577*9880d681SAndroid Build Coastguard Worker } else {
578*9880d681SAndroid Build Coastguard Worker for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
579*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,
580*9880d681SAndroid Build Coastguard Worker ( (Src1.AggregateVal[_i].DoubleVal !=
581*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[_i].DoubleVal) ||
582*9880d681SAndroid Build Coastguard Worker (Src2.AggregateVal[_i].DoubleVal !=
583*9880d681SAndroid Build Coastguard Worker Src2.AggregateVal[_i].DoubleVal)));
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker } else if (Ty->isFloatTy())
586*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,(Src1.FloatVal != Src1.FloatVal ||
587*9880d681SAndroid Build Coastguard Worker Src2.FloatVal != Src2.FloatVal));
588*9880d681SAndroid Build Coastguard Worker else {
589*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1,(Src1.DoubleVal != Src1.DoubleVal ||
590*9880d681SAndroid Build Coastguard Worker Src2.DoubleVal != Src2.DoubleVal));
591*9880d681SAndroid Build Coastguard Worker }
592*9880d681SAndroid Build Coastguard Worker return Dest;
593*9880d681SAndroid Build Coastguard Worker }
594*9880d681SAndroid Build Coastguard Worker
executeFCMP_BOOL(GenericValue Src1,GenericValue Src2,Type * Ty,const bool val)595*9880d681SAndroid Build Coastguard Worker static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2,
596*9880d681SAndroid Build Coastguard Worker Type *Ty, const bool val) {
597*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
598*9880d681SAndroid Build Coastguard Worker if(Ty->isVectorTy()) {
599*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
600*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() );
601*9880d681SAndroid Build Coastguard Worker for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
602*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[_i].IntVal = APInt(1,val);
603*9880d681SAndroid Build Coastguard Worker } else {
604*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(1, val);
605*9880d681SAndroid Build Coastguard Worker }
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker return Dest;
608*9880d681SAndroid Build Coastguard Worker }
609*9880d681SAndroid Build Coastguard Worker
visitFCmpInst(FCmpInst & I)610*9880d681SAndroid Build Coastguard Worker void Interpreter::visitFCmpInst(FCmpInst &I) {
611*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
612*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getOperand(0)->getType();
613*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
614*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
615*9880d681SAndroid Build Coastguard Worker GenericValue R; // Result
616*9880d681SAndroid Build Coastguard Worker
617*9880d681SAndroid Build Coastguard Worker switch (I.getPredicate()) {
618*9880d681SAndroid Build Coastguard Worker default:
619*9880d681SAndroid Build Coastguard Worker dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
620*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
621*9880d681SAndroid Build Coastguard Worker break;
622*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
623*9880d681SAndroid Build Coastguard Worker break;
624*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_TRUE: R = executeFCMP_BOOL(Src1, Src2, Ty, true);
625*9880d681SAndroid Build Coastguard Worker break;
626*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ORD: R = executeFCMP_ORD(Src1, Src2, Ty); break;
627*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UNO: R = executeFCMP_UNO(Src1, Src2, Ty); break;
628*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UEQ: R = executeFCMP_UEQ(Src1, Src2, Ty); break;
629*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OEQ: R = executeFCMP_OEQ(Src1, Src2, Ty); break;
630*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UNE: R = executeFCMP_UNE(Src1, Src2, Ty); break;
631*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ONE: R = executeFCMP_ONE(Src1, Src2, Ty); break;
632*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ULT: R = executeFCMP_ULT(Src1, Src2, Ty); break;
633*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OLT: R = executeFCMP_OLT(Src1, Src2, Ty); break;
634*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UGT: R = executeFCMP_UGT(Src1, Src2, Ty); break;
635*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OGT: R = executeFCMP_OGT(Src1, Src2, Ty); break;
636*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ULE: R = executeFCMP_ULE(Src1, Src2, Ty); break;
637*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OLE: R = executeFCMP_OLE(Src1, Src2, Ty); break;
638*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UGE: R = executeFCMP_UGE(Src1, Src2, Ty); break;
639*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OGE: R = executeFCMP_OGE(Src1, Src2, Ty); break;
640*9880d681SAndroid Build Coastguard Worker }
641*9880d681SAndroid Build Coastguard Worker
642*9880d681SAndroid Build Coastguard Worker SetValue(&I, R, SF);
643*9880d681SAndroid Build Coastguard Worker }
644*9880d681SAndroid Build Coastguard Worker
executeCmpInst(unsigned predicate,GenericValue Src1,GenericValue Src2,Type * Ty)645*9880d681SAndroid Build Coastguard Worker static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
646*9880d681SAndroid Build Coastguard Worker GenericValue Src2, Type *Ty) {
647*9880d681SAndroid Build Coastguard Worker GenericValue Result;
648*9880d681SAndroid Build Coastguard Worker switch (predicate) {
649*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty);
650*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_NE: return executeICMP_NE(Src1, Src2, Ty);
651*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_UGT: return executeICMP_UGT(Src1, Src2, Ty);
652*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SGT: return executeICMP_SGT(Src1, Src2, Ty);
653*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_ULT: return executeICMP_ULT(Src1, Src2, Ty);
654*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SLT: return executeICMP_SLT(Src1, Src2, Ty);
655*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_UGE: return executeICMP_UGE(Src1, Src2, Ty);
656*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty);
657*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty);
658*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty);
659*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ORD: return executeFCMP_ORD(Src1, Src2, Ty);
660*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UNO: return executeFCMP_UNO(Src1, Src2, Ty);
661*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OEQ: return executeFCMP_OEQ(Src1, Src2, Ty);
662*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UEQ: return executeFCMP_UEQ(Src1, Src2, Ty);
663*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ONE: return executeFCMP_ONE(Src1, Src2, Ty);
664*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UNE: return executeFCMP_UNE(Src1, Src2, Ty);
665*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OLT: return executeFCMP_OLT(Src1, Src2, Ty);
666*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ULT: return executeFCMP_ULT(Src1, Src2, Ty);
667*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OGT: return executeFCMP_OGT(Src1, Src2, Ty);
668*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UGT: return executeFCMP_UGT(Src1, Src2, Ty);
669*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OLE: return executeFCMP_OLE(Src1, Src2, Ty);
670*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_ULE: return executeFCMP_ULE(Src1, Src2, Ty);
671*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_OGE: return executeFCMP_OGE(Src1, Src2, Ty);
672*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_UGE: return executeFCMP_UGE(Src1, Src2, Ty);
673*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_FALSE: return executeFCMP_BOOL(Src1, Src2, Ty, false);
674*9880d681SAndroid Build Coastguard Worker case FCmpInst::FCMP_TRUE: return executeFCMP_BOOL(Src1, Src2, Ty, true);
675*9880d681SAndroid Build Coastguard Worker default:
676*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled Cmp predicate\n";
677*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
678*9880d681SAndroid Build Coastguard Worker }
679*9880d681SAndroid Build Coastguard Worker }
680*9880d681SAndroid Build Coastguard Worker
visitBinaryOperator(BinaryOperator & I)681*9880d681SAndroid Build Coastguard Worker void Interpreter::visitBinaryOperator(BinaryOperator &I) {
682*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
683*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getOperand(0)->getType();
684*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
685*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
686*9880d681SAndroid Build Coastguard Worker GenericValue R; // Result
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker // First process vector operation
689*9880d681SAndroid Build Coastguard Worker if (Ty->isVectorTy()) {
690*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
691*9880d681SAndroid Build Coastguard Worker R.AggregateVal.resize(Src1.AggregateVal.size());
692*9880d681SAndroid Build Coastguard Worker
693*9880d681SAndroid Build Coastguard Worker // Macros to execute binary operation 'OP' over integer vectors
694*9880d681SAndroid Build Coastguard Worker #define INTEGER_VECTOR_OPERATION(OP) \
695*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
696*9880d681SAndroid Build Coastguard Worker R.AggregateVal[i].IntVal = \
697*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker // Additional macros to execute binary operations udiv/sdiv/urem/srem since
700*9880d681SAndroid Build Coastguard Worker // they have different notation.
701*9880d681SAndroid Build Coastguard Worker #define INTEGER_VECTOR_FUNCTION(OP) \
702*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
703*9880d681SAndroid Build Coastguard Worker R.AggregateVal[i].IntVal = \
704*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker // Macros to execute binary operation 'OP' over floating point type TY
707*9880d681SAndroid Build Coastguard Worker // (float or double) vectors
708*9880d681SAndroid Build Coastguard Worker #define FLOAT_VECTOR_FUNCTION(OP, TY) \
709*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
710*9880d681SAndroid Build Coastguard Worker R.AggregateVal[i].TY = \
711*9880d681SAndroid Build Coastguard Worker Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Worker // Macros to choose appropriate TY: float or double and run operation
714*9880d681SAndroid Build Coastguard Worker // execution
715*9880d681SAndroid Build Coastguard Worker #define FLOAT_VECTOR_OP(OP) { \
716*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
717*9880d681SAndroid Build Coastguard Worker FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
718*9880d681SAndroid Build Coastguard Worker else { \
719*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
720*9880d681SAndroid Build Coastguard Worker FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
721*9880d681SAndroid Build Coastguard Worker else { \
722*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
723*9880d681SAndroid Build Coastguard Worker llvm_unreachable(0); \
724*9880d681SAndroid Build Coastguard Worker } \
725*9880d681SAndroid Build Coastguard Worker } \
726*9880d681SAndroid Build Coastguard Worker }
727*9880d681SAndroid Build Coastguard Worker
728*9880d681SAndroid Build Coastguard Worker switch(I.getOpcode()){
729*9880d681SAndroid Build Coastguard Worker default:
730*9880d681SAndroid Build Coastguard Worker dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
731*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
732*9880d681SAndroid Build Coastguard Worker break;
733*9880d681SAndroid Build Coastguard Worker case Instruction::Add: INTEGER_VECTOR_OPERATION(+) break;
734*9880d681SAndroid Build Coastguard Worker case Instruction::Sub: INTEGER_VECTOR_OPERATION(-) break;
735*9880d681SAndroid Build Coastguard Worker case Instruction::Mul: INTEGER_VECTOR_OPERATION(*) break;
736*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv: INTEGER_VECTOR_FUNCTION(udiv) break;
737*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv: INTEGER_VECTOR_FUNCTION(sdiv) break;
738*9880d681SAndroid Build Coastguard Worker case Instruction::URem: INTEGER_VECTOR_FUNCTION(urem) break;
739*9880d681SAndroid Build Coastguard Worker case Instruction::SRem: INTEGER_VECTOR_FUNCTION(srem) break;
740*9880d681SAndroid Build Coastguard Worker case Instruction::And: INTEGER_VECTOR_OPERATION(&) break;
741*9880d681SAndroid Build Coastguard Worker case Instruction::Or: INTEGER_VECTOR_OPERATION(|) break;
742*9880d681SAndroid Build Coastguard Worker case Instruction::Xor: INTEGER_VECTOR_OPERATION(^) break;
743*9880d681SAndroid Build Coastguard Worker case Instruction::FAdd: FLOAT_VECTOR_OP(+) break;
744*9880d681SAndroid Build Coastguard Worker case Instruction::FSub: FLOAT_VECTOR_OP(-) break;
745*9880d681SAndroid Build Coastguard Worker case Instruction::FMul: FLOAT_VECTOR_OP(*) break;
746*9880d681SAndroid Build Coastguard Worker case Instruction::FDiv: FLOAT_VECTOR_OP(/) break;
747*9880d681SAndroid Build Coastguard Worker case Instruction::FRem:
748*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
749*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
750*9880d681SAndroid Build Coastguard Worker R.AggregateVal[i].FloatVal =
751*9880d681SAndroid Build Coastguard Worker fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
752*9880d681SAndroid Build Coastguard Worker else {
753*9880d681SAndroid Build Coastguard Worker if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
754*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
755*9880d681SAndroid Build Coastguard Worker R.AggregateVal[i].DoubleVal =
756*9880d681SAndroid Build Coastguard Worker fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
757*9880d681SAndroid Build Coastguard Worker else {
758*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
759*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
760*9880d681SAndroid Build Coastguard Worker }
761*9880d681SAndroid Build Coastguard Worker }
762*9880d681SAndroid Build Coastguard Worker break;
763*9880d681SAndroid Build Coastguard Worker }
764*9880d681SAndroid Build Coastguard Worker } else {
765*9880d681SAndroid Build Coastguard Worker switch (I.getOpcode()) {
766*9880d681SAndroid Build Coastguard Worker default:
767*9880d681SAndroid Build Coastguard Worker dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
768*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
769*9880d681SAndroid Build Coastguard Worker break;
770*9880d681SAndroid Build Coastguard Worker case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
771*9880d681SAndroid Build Coastguard Worker case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
772*9880d681SAndroid Build Coastguard Worker case Instruction::Mul: R.IntVal = Src1.IntVal * Src2.IntVal; break;
773*9880d681SAndroid Build Coastguard Worker case Instruction::FAdd: executeFAddInst(R, Src1, Src2, Ty); break;
774*9880d681SAndroid Build Coastguard Worker case Instruction::FSub: executeFSubInst(R, Src1, Src2, Ty); break;
775*9880d681SAndroid Build Coastguard Worker case Instruction::FMul: executeFMulInst(R, Src1, Src2, Ty); break;
776*9880d681SAndroid Build Coastguard Worker case Instruction::FDiv: executeFDivInst(R, Src1, Src2, Ty); break;
777*9880d681SAndroid Build Coastguard Worker case Instruction::FRem: executeFRemInst(R, Src1, Src2, Ty); break;
778*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv: R.IntVal = Src1.IntVal.udiv(Src2.IntVal); break;
779*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv: R.IntVal = Src1.IntVal.sdiv(Src2.IntVal); break;
780*9880d681SAndroid Build Coastguard Worker case Instruction::URem: R.IntVal = Src1.IntVal.urem(Src2.IntVal); break;
781*9880d681SAndroid Build Coastguard Worker case Instruction::SRem: R.IntVal = Src1.IntVal.srem(Src2.IntVal); break;
782*9880d681SAndroid Build Coastguard Worker case Instruction::And: R.IntVal = Src1.IntVal & Src2.IntVal; break;
783*9880d681SAndroid Build Coastguard Worker case Instruction::Or: R.IntVal = Src1.IntVal | Src2.IntVal; break;
784*9880d681SAndroid Build Coastguard Worker case Instruction::Xor: R.IntVal = Src1.IntVal ^ Src2.IntVal; break;
785*9880d681SAndroid Build Coastguard Worker }
786*9880d681SAndroid Build Coastguard Worker }
787*9880d681SAndroid Build Coastguard Worker SetValue(&I, R, SF);
788*9880d681SAndroid Build Coastguard Worker }
789*9880d681SAndroid Build Coastguard Worker
executeSelectInst(GenericValue Src1,GenericValue Src2,GenericValue Src3,Type * Ty)790*9880d681SAndroid Build Coastguard Worker static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
791*9880d681SAndroid Build Coastguard Worker GenericValue Src3, Type *Ty) {
792*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
793*9880d681SAndroid Build Coastguard Worker if(Ty->isVectorTy()) {
794*9880d681SAndroid Build Coastguard Worker assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
795*9880d681SAndroid Build Coastguard Worker assert(Src2.AggregateVal.size() == Src3.AggregateVal.size());
796*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize( Src1.AggregateVal.size() );
797*9880d681SAndroid Build Coastguard Worker for (size_t i = 0; i < Src1.AggregateVal.size(); ++i)
798*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i] = (Src1.AggregateVal[i].IntVal == 0) ?
799*9880d681SAndroid Build Coastguard Worker Src3.AggregateVal[i] : Src2.AggregateVal[i];
800*9880d681SAndroid Build Coastguard Worker } else {
801*9880d681SAndroid Build Coastguard Worker Dest = (Src1.IntVal == 0) ? Src3 : Src2;
802*9880d681SAndroid Build Coastguard Worker }
803*9880d681SAndroid Build Coastguard Worker return Dest;
804*9880d681SAndroid Build Coastguard Worker }
805*9880d681SAndroid Build Coastguard Worker
visitSelectInst(SelectInst & I)806*9880d681SAndroid Build Coastguard Worker void Interpreter::visitSelectInst(SelectInst &I) {
807*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
808*9880d681SAndroid Build Coastguard Worker Type * Ty = I.getOperand(0)->getType();
809*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
810*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
811*9880d681SAndroid Build Coastguard Worker GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
812*9880d681SAndroid Build Coastguard Worker GenericValue R = executeSelectInst(Src1, Src2, Src3, Ty);
813*9880d681SAndroid Build Coastguard Worker SetValue(&I, R, SF);
814*9880d681SAndroid Build Coastguard Worker }
815*9880d681SAndroid Build Coastguard Worker
816*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
817*9880d681SAndroid Build Coastguard Worker // Terminator Instruction Implementations
818*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
819*9880d681SAndroid Build Coastguard Worker
exitCalled(GenericValue GV)820*9880d681SAndroid Build Coastguard Worker void Interpreter::exitCalled(GenericValue GV) {
821*9880d681SAndroid Build Coastguard Worker // runAtExitHandlers() assumes there are no stack frames, but
822*9880d681SAndroid Build Coastguard Worker // if exit() was called, then it had a stack frame. Blow away
823*9880d681SAndroid Build Coastguard Worker // the stack before interpreting atexit handlers.
824*9880d681SAndroid Build Coastguard Worker ECStack.clear();
825*9880d681SAndroid Build Coastguard Worker runAtExitHandlers();
826*9880d681SAndroid Build Coastguard Worker exit(GV.IntVal.zextOrTrunc(32).getZExtValue());
827*9880d681SAndroid Build Coastguard Worker }
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker /// Pop the last stack frame off of ECStack and then copy the result
830*9880d681SAndroid Build Coastguard Worker /// back into the result variable if we are not returning void. The
831*9880d681SAndroid Build Coastguard Worker /// result variable may be the ExitValue, or the Value of the calling
832*9880d681SAndroid Build Coastguard Worker /// CallInst if there was a previous stack frame. This method may
833*9880d681SAndroid Build Coastguard Worker /// invalidate any ECStack iterators you have. This method also takes
834*9880d681SAndroid Build Coastguard Worker /// care of switching to the normal destination BB, if we are returning
835*9880d681SAndroid Build Coastguard Worker /// from an invoke.
836*9880d681SAndroid Build Coastguard Worker ///
popStackAndReturnValueToCaller(Type * RetTy,GenericValue Result)837*9880d681SAndroid Build Coastguard Worker void Interpreter::popStackAndReturnValueToCaller(Type *RetTy,
838*9880d681SAndroid Build Coastguard Worker GenericValue Result) {
839*9880d681SAndroid Build Coastguard Worker // Pop the current stack frame.
840*9880d681SAndroid Build Coastguard Worker ECStack.pop_back();
841*9880d681SAndroid Build Coastguard Worker
842*9880d681SAndroid Build Coastguard Worker if (ECStack.empty()) { // Finished main. Put result into exit code...
843*9880d681SAndroid Build Coastguard Worker if (RetTy && !RetTy->isVoidTy()) { // Nonvoid return type?
844*9880d681SAndroid Build Coastguard Worker ExitValue = Result; // Capture the exit value of the program
845*9880d681SAndroid Build Coastguard Worker } else {
846*9880d681SAndroid Build Coastguard Worker memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
847*9880d681SAndroid Build Coastguard Worker }
848*9880d681SAndroid Build Coastguard Worker } else {
849*9880d681SAndroid Build Coastguard Worker // If we have a previous stack frame, and we have a previous call,
850*9880d681SAndroid Build Coastguard Worker // fill in the return value...
851*9880d681SAndroid Build Coastguard Worker ExecutionContext &CallingSF = ECStack.back();
852*9880d681SAndroid Build Coastguard Worker if (Instruction *I = CallingSF.Caller.getInstruction()) {
853*9880d681SAndroid Build Coastguard Worker // Save result...
854*9880d681SAndroid Build Coastguard Worker if (!CallingSF.Caller.getType()->isVoidTy())
855*9880d681SAndroid Build Coastguard Worker SetValue(I, Result, CallingSF);
856*9880d681SAndroid Build Coastguard Worker if (InvokeInst *II = dyn_cast<InvokeInst> (I))
857*9880d681SAndroid Build Coastguard Worker SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
858*9880d681SAndroid Build Coastguard Worker CallingSF.Caller = CallSite(); // We returned from the call...
859*9880d681SAndroid Build Coastguard Worker }
860*9880d681SAndroid Build Coastguard Worker }
861*9880d681SAndroid Build Coastguard Worker }
862*9880d681SAndroid Build Coastguard Worker
visitReturnInst(ReturnInst & I)863*9880d681SAndroid Build Coastguard Worker void Interpreter::visitReturnInst(ReturnInst &I) {
864*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
865*9880d681SAndroid Build Coastguard Worker Type *RetTy = Type::getVoidTy(I.getContext());
866*9880d681SAndroid Build Coastguard Worker GenericValue Result;
867*9880d681SAndroid Build Coastguard Worker
868*9880d681SAndroid Build Coastguard Worker // Save away the return value... (if we are not 'ret void')
869*9880d681SAndroid Build Coastguard Worker if (I.getNumOperands()) {
870*9880d681SAndroid Build Coastguard Worker RetTy = I.getReturnValue()->getType();
871*9880d681SAndroid Build Coastguard Worker Result = getOperandValue(I.getReturnValue(), SF);
872*9880d681SAndroid Build Coastguard Worker }
873*9880d681SAndroid Build Coastguard Worker
874*9880d681SAndroid Build Coastguard Worker popStackAndReturnValueToCaller(RetTy, Result);
875*9880d681SAndroid Build Coastguard Worker }
876*9880d681SAndroid Build Coastguard Worker
visitUnreachableInst(UnreachableInst & I)877*9880d681SAndroid Build Coastguard Worker void Interpreter::visitUnreachableInst(UnreachableInst &I) {
878*9880d681SAndroid Build Coastguard Worker report_fatal_error("Program executed an 'unreachable' instruction!");
879*9880d681SAndroid Build Coastguard Worker }
880*9880d681SAndroid Build Coastguard Worker
visitBranchInst(BranchInst & I)881*9880d681SAndroid Build Coastguard Worker void Interpreter::visitBranchInst(BranchInst &I) {
882*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
883*9880d681SAndroid Build Coastguard Worker BasicBlock *Dest;
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker Dest = I.getSuccessor(0); // Uncond branches have a fixed dest...
886*9880d681SAndroid Build Coastguard Worker if (!I.isUnconditional()) {
887*9880d681SAndroid Build Coastguard Worker Value *Cond = I.getCondition();
888*9880d681SAndroid Build Coastguard Worker if (getOperandValue(Cond, SF).IntVal == 0) // If false cond...
889*9880d681SAndroid Build Coastguard Worker Dest = I.getSuccessor(1);
890*9880d681SAndroid Build Coastguard Worker }
891*9880d681SAndroid Build Coastguard Worker SwitchToNewBasicBlock(Dest, SF);
892*9880d681SAndroid Build Coastguard Worker }
893*9880d681SAndroid Build Coastguard Worker
visitSwitchInst(SwitchInst & I)894*9880d681SAndroid Build Coastguard Worker void Interpreter::visitSwitchInst(SwitchInst &I) {
895*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
896*9880d681SAndroid Build Coastguard Worker Value* Cond = I.getCondition();
897*9880d681SAndroid Build Coastguard Worker Type *ElTy = Cond->getType();
898*9880d681SAndroid Build Coastguard Worker GenericValue CondVal = getOperandValue(Cond, SF);
899*9880d681SAndroid Build Coastguard Worker
900*9880d681SAndroid Build Coastguard Worker // Check to see if any of the cases match...
901*9880d681SAndroid Build Coastguard Worker BasicBlock *Dest = nullptr;
902*9880d681SAndroid Build Coastguard Worker for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
903*9880d681SAndroid Build Coastguard Worker GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF);
904*9880d681SAndroid Build Coastguard Worker if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
905*9880d681SAndroid Build Coastguard Worker Dest = cast<BasicBlock>(i.getCaseSuccessor());
906*9880d681SAndroid Build Coastguard Worker break;
907*9880d681SAndroid Build Coastguard Worker }
908*9880d681SAndroid Build Coastguard Worker }
909*9880d681SAndroid Build Coastguard Worker if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
910*9880d681SAndroid Build Coastguard Worker SwitchToNewBasicBlock(Dest, SF);
911*9880d681SAndroid Build Coastguard Worker }
912*9880d681SAndroid Build Coastguard Worker
visitIndirectBrInst(IndirectBrInst & I)913*9880d681SAndroid Build Coastguard Worker void Interpreter::visitIndirectBrInst(IndirectBrInst &I) {
914*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
915*9880d681SAndroid Build Coastguard Worker void *Dest = GVTOP(getOperandValue(I.getAddress(), SF));
916*9880d681SAndroid Build Coastguard Worker SwitchToNewBasicBlock((BasicBlock*)Dest, SF);
917*9880d681SAndroid Build Coastguard Worker }
918*9880d681SAndroid Build Coastguard Worker
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker // SwitchToNewBasicBlock - This method is used to jump to a new basic block.
921*9880d681SAndroid Build Coastguard Worker // This function handles the actual updating of block and instruction iterators
922*9880d681SAndroid Build Coastguard Worker // as well as execution of all of the PHI nodes in the destination block.
923*9880d681SAndroid Build Coastguard Worker //
924*9880d681SAndroid Build Coastguard Worker // This method does this because all of the PHI nodes must be executed
925*9880d681SAndroid Build Coastguard Worker // atomically, reading their inputs before any of the results are updated. Not
926*9880d681SAndroid Build Coastguard Worker // doing this can cause problems if the PHI nodes depend on other PHI nodes for
927*9880d681SAndroid Build Coastguard Worker // their inputs. If the input PHI node is updated before it is read, incorrect
928*9880d681SAndroid Build Coastguard Worker // results can happen. Thus we use a two phase approach.
929*9880d681SAndroid Build Coastguard Worker //
SwitchToNewBasicBlock(BasicBlock * Dest,ExecutionContext & SF)930*9880d681SAndroid Build Coastguard Worker void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){
931*9880d681SAndroid Build Coastguard Worker BasicBlock *PrevBB = SF.CurBB; // Remember where we came from...
932*9880d681SAndroid Build Coastguard Worker SF.CurBB = Dest; // Update CurBB to branch destination
933*9880d681SAndroid Build Coastguard Worker SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr...
934*9880d681SAndroid Build Coastguard Worker
935*9880d681SAndroid Build Coastguard Worker if (!isa<PHINode>(SF.CurInst)) return; // Nothing fancy to do
936*9880d681SAndroid Build Coastguard Worker
937*9880d681SAndroid Build Coastguard Worker // Loop over all of the PHI nodes in the current block, reading their inputs.
938*9880d681SAndroid Build Coastguard Worker std::vector<GenericValue> ResultValues;
939*9880d681SAndroid Build Coastguard Worker
940*9880d681SAndroid Build Coastguard Worker for (; PHINode *PN = dyn_cast<PHINode>(SF.CurInst); ++SF.CurInst) {
941*9880d681SAndroid Build Coastguard Worker // Search for the value corresponding to this previous bb...
942*9880d681SAndroid Build Coastguard Worker int i = PN->getBasicBlockIndex(PrevBB);
943*9880d681SAndroid Build Coastguard Worker assert(i != -1 && "PHINode doesn't contain entry for predecessor??");
944*9880d681SAndroid Build Coastguard Worker Value *IncomingValue = PN->getIncomingValue(i);
945*9880d681SAndroid Build Coastguard Worker
946*9880d681SAndroid Build Coastguard Worker // Save the incoming value for this PHI node...
947*9880d681SAndroid Build Coastguard Worker ResultValues.push_back(getOperandValue(IncomingValue, SF));
948*9880d681SAndroid Build Coastguard Worker }
949*9880d681SAndroid Build Coastguard Worker
950*9880d681SAndroid Build Coastguard Worker // Now loop over all of the PHI nodes setting their values...
951*9880d681SAndroid Build Coastguard Worker SF.CurInst = SF.CurBB->begin();
952*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; isa<PHINode>(SF.CurInst); ++SF.CurInst, ++i) {
953*9880d681SAndroid Build Coastguard Worker PHINode *PN = cast<PHINode>(SF.CurInst);
954*9880d681SAndroid Build Coastguard Worker SetValue(PN, ResultValues[i], SF);
955*9880d681SAndroid Build Coastguard Worker }
956*9880d681SAndroid Build Coastguard Worker }
957*9880d681SAndroid Build Coastguard Worker
958*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
959*9880d681SAndroid Build Coastguard Worker // Memory Instruction Implementations
960*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
961*9880d681SAndroid Build Coastguard Worker
visitAllocaInst(AllocaInst & I)962*9880d681SAndroid Build Coastguard Worker void Interpreter::visitAllocaInst(AllocaInst &I) {
963*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
964*9880d681SAndroid Build Coastguard Worker
965*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType()->getElementType(); // Type to be allocated
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker // Get the number of elements being allocated by the array...
968*9880d681SAndroid Build Coastguard Worker unsigned NumElements =
969*9880d681SAndroid Build Coastguard Worker getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker unsigned TypeSize = (size_t)getDataLayout().getTypeAllocSize(Ty);
972*9880d681SAndroid Build Coastguard Worker
973*9880d681SAndroid Build Coastguard Worker // Avoid malloc-ing zero bytes, use max()...
974*9880d681SAndroid Build Coastguard Worker unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
975*9880d681SAndroid Build Coastguard Worker
976*9880d681SAndroid Build Coastguard Worker // Allocate enough memory to hold the type...
977*9880d681SAndroid Build Coastguard Worker void *Memory = malloc(MemToAlloc);
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Allocated Type: " << *Ty << " (" << TypeSize << " bytes) x "
980*9880d681SAndroid Build Coastguard Worker << NumElements << " (Total: " << MemToAlloc << ") at "
981*9880d681SAndroid Build Coastguard Worker << uintptr_t(Memory) << '\n');
982*9880d681SAndroid Build Coastguard Worker
983*9880d681SAndroid Build Coastguard Worker GenericValue Result = PTOGV(Memory);
984*9880d681SAndroid Build Coastguard Worker assert(Result.PointerVal && "Null pointer returned by malloc!");
985*9880d681SAndroid Build Coastguard Worker SetValue(&I, Result, SF);
986*9880d681SAndroid Build Coastguard Worker
987*9880d681SAndroid Build Coastguard Worker if (I.getOpcode() == Instruction::Alloca)
988*9880d681SAndroid Build Coastguard Worker ECStack.back().Allocas.add(Memory);
989*9880d681SAndroid Build Coastguard Worker }
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker // getElementOffset - The workhorse for getelementptr.
992*9880d681SAndroid Build Coastguard Worker //
executeGEPOperation(Value * Ptr,gep_type_iterator I,gep_type_iterator E,ExecutionContext & SF)993*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
994*9880d681SAndroid Build Coastguard Worker gep_type_iterator E,
995*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
996*9880d681SAndroid Build Coastguard Worker assert(Ptr->getType()->isPointerTy() &&
997*9880d681SAndroid Build Coastguard Worker "Cannot getElementOffset of a nonpointer type!");
998*9880d681SAndroid Build Coastguard Worker
999*9880d681SAndroid Build Coastguard Worker uint64_t Total = 0;
1000*9880d681SAndroid Build Coastguard Worker
1001*9880d681SAndroid Build Coastguard Worker for (; I != E; ++I) {
1002*9880d681SAndroid Build Coastguard Worker if (StructType *STy = dyn_cast<StructType>(*I)) {
1003*9880d681SAndroid Build Coastguard Worker const StructLayout *SLO = getDataLayout().getStructLayout(STy);
1004*9880d681SAndroid Build Coastguard Worker
1005*9880d681SAndroid Build Coastguard Worker const ConstantInt *CPU = cast<ConstantInt>(I.getOperand());
1006*9880d681SAndroid Build Coastguard Worker unsigned Index = unsigned(CPU->getZExtValue());
1007*9880d681SAndroid Build Coastguard Worker
1008*9880d681SAndroid Build Coastguard Worker Total += SLO->getElementOffset(Index);
1009*9880d681SAndroid Build Coastguard Worker } else {
1010*9880d681SAndroid Build Coastguard Worker SequentialType *ST = cast<SequentialType>(*I);
1011*9880d681SAndroid Build Coastguard Worker // Get the index number for the array... which must be long type...
1012*9880d681SAndroid Build Coastguard Worker GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
1013*9880d681SAndroid Build Coastguard Worker
1014*9880d681SAndroid Build Coastguard Worker int64_t Idx;
1015*9880d681SAndroid Build Coastguard Worker unsigned BitWidth =
1016*9880d681SAndroid Build Coastguard Worker cast<IntegerType>(I.getOperand()->getType())->getBitWidth();
1017*9880d681SAndroid Build Coastguard Worker if (BitWidth == 32)
1018*9880d681SAndroid Build Coastguard Worker Idx = (int64_t)(int32_t)IdxGV.IntVal.getZExtValue();
1019*9880d681SAndroid Build Coastguard Worker else {
1020*9880d681SAndroid Build Coastguard Worker assert(BitWidth == 64 && "Invalid index type for getelementptr");
1021*9880d681SAndroid Build Coastguard Worker Idx = (int64_t)IdxGV.IntVal.getZExtValue();
1022*9880d681SAndroid Build Coastguard Worker }
1023*9880d681SAndroid Build Coastguard Worker Total += getDataLayout().getTypeAllocSize(ST->getElementType()) * Idx;
1024*9880d681SAndroid Build Coastguard Worker }
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker GenericValue Result;
1028*9880d681SAndroid Build Coastguard Worker Result.PointerVal = ((char*)getOperandValue(Ptr, SF).PointerVal) + Total;
1029*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "GEP Index " << Total << " bytes.\n");
1030*9880d681SAndroid Build Coastguard Worker return Result;
1031*9880d681SAndroid Build Coastguard Worker }
1032*9880d681SAndroid Build Coastguard Worker
visitGetElementPtrInst(GetElementPtrInst & I)1033*9880d681SAndroid Build Coastguard Worker void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
1034*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1035*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeGEPOperation(I.getPointerOperand(),
1036*9880d681SAndroid Build Coastguard Worker gep_type_begin(I), gep_type_end(I), SF), SF);
1037*9880d681SAndroid Build Coastguard Worker }
1038*9880d681SAndroid Build Coastguard Worker
visitLoadInst(LoadInst & I)1039*9880d681SAndroid Build Coastguard Worker void Interpreter::visitLoadInst(LoadInst &I) {
1040*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1041*9880d681SAndroid Build Coastguard Worker GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
1042*9880d681SAndroid Build Coastguard Worker GenericValue *Ptr = (GenericValue*)GVTOP(SRC);
1043*9880d681SAndroid Build Coastguard Worker GenericValue Result;
1044*9880d681SAndroid Build Coastguard Worker LoadValueFromMemory(Result, Ptr, I.getType());
1045*9880d681SAndroid Build Coastguard Worker SetValue(&I, Result, SF);
1046*9880d681SAndroid Build Coastguard Worker if (I.isVolatile() && PrintVolatile)
1047*9880d681SAndroid Build Coastguard Worker dbgs() << "Volatile load " << I;
1048*9880d681SAndroid Build Coastguard Worker }
1049*9880d681SAndroid Build Coastguard Worker
visitStoreInst(StoreInst & I)1050*9880d681SAndroid Build Coastguard Worker void Interpreter::visitStoreInst(StoreInst &I) {
1051*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1052*9880d681SAndroid Build Coastguard Worker GenericValue Val = getOperandValue(I.getOperand(0), SF);
1053*9880d681SAndroid Build Coastguard Worker GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
1054*9880d681SAndroid Build Coastguard Worker StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC),
1055*9880d681SAndroid Build Coastguard Worker I.getOperand(0)->getType());
1056*9880d681SAndroid Build Coastguard Worker if (I.isVolatile() && PrintVolatile)
1057*9880d681SAndroid Build Coastguard Worker dbgs() << "Volatile store: " << I;
1058*9880d681SAndroid Build Coastguard Worker }
1059*9880d681SAndroid Build Coastguard Worker
1060*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1061*9880d681SAndroid Build Coastguard Worker // Miscellaneous Instruction Implementations
1062*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1063*9880d681SAndroid Build Coastguard Worker
visitCallSite(CallSite CS)1064*9880d681SAndroid Build Coastguard Worker void Interpreter::visitCallSite(CallSite CS) {
1065*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1066*9880d681SAndroid Build Coastguard Worker
1067*9880d681SAndroid Build Coastguard Worker // Check to see if this is an intrinsic function call...
1068*9880d681SAndroid Build Coastguard Worker Function *F = CS.getCalledFunction();
1069*9880d681SAndroid Build Coastguard Worker if (F && F->isDeclaration())
1070*9880d681SAndroid Build Coastguard Worker switch (F->getIntrinsicID()) {
1071*9880d681SAndroid Build Coastguard Worker case Intrinsic::not_intrinsic:
1072*9880d681SAndroid Build Coastguard Worker break;
1073*9880d681SAndroid Build Coastguard Worker case Intrinsic::vastart: { // va_start
1074*9880d681SAndroid Build Coastguard Worker GenericValue ArgIndex;
1075*9880d681SAndroid Build Coastguard Worker ArgIndex.UIntPairVal.first = ECStack.size() - 1;
1076*9880d681SAndroid Build Coastguard Worker ArgIndex.UIntPairVal.second = 0;
1077*9880d681SAndroid Build Coastguard Worker SetValue(CS.getInstruction(), ArgIndex, SF);
1078*9880d681SAndroid Build Coastguard Worker return;
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker case Intrinsic::vaend: // va_end is a noop for the interpreter
1081*9880d681SAndroid Build Coastguard Worker return;
1082*9880d681SAndroid Build Coastguard Worker case Intrinsic::vacopy: // va_copy: dest = src
1083*9880d681SAndroid Build Coastguard Worker SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF);
1084*9880d681SAndroid Build Coastguard Worker return;
1085*9880d681SAndroid Build Coastguard Worker default:
1086*9880d681SAndroid Build Coastguard Worker // If it is an unknown intrinsic function, use the intrinsic lowering
1087*9880d681SAndroid Build Coastguard Worker // class to transform it into hopefully tasty LLVM code.
1088*9880d681SAndroid Build Coastguard Worker //
1089*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator me(CS.getInstruction());
1090*9880d681SAndroid Build Coastguard Worker BasicBlock *Parent = CS.getInstruction()->getParent();
1091*9880d681SAndroid Build Coastguard Worker bool atBegin(Parent->begin() == me);
1092*9880d681SAndroid Build Coastguard Worker if (!atBegin)
1093*9880d681SAndroid Build Coastguard Worker --me;
1094*9880d681SAndroid Build Coastguard Worker IL->LowerIntrinsicCall(cast<CallInst>(CS.getInstruction()));
1095*9880d681SAndroid Build Coastguard Worker
1096*9880d681SAndroid Build Coastguard Worker // Restore the CurInst pointer to the first instruction newly inserted, if
1097*9880d681SAndroid Build Coastguard Worker // any.
1098*9880d681SAndroid Build Coastguard Worker if (atBegin) {
1099*9880d681SAndroid Build Coastguard Worker SF.CurInst = Parent->begin();
1100*9880d681SAndroid Build Coastguard Worker } else {
1101*9880d681SAndroid Build Coastguard Worker SF.CurInst = me;
1102*9880d681SAndroid Build Coastguard Worker ++SF.CurInst;
1103*9880d681SAndroid Build Coastguard Worker }
1104*9880d681SAndroid Build Coastguard Worker return;
1105*9880d681SAndroid Build Coastguard Worker }
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Worker
1108*9880d681SAndroid Build Coastguard Worker SF.Caller = CS;
1109*9880d681SAndroid Build Coastguard Worker std::vector<GenericValue> ArgVals;
1110*9880d681SAndroid Build Coastguard Worker const unsigned NumArgs = SF.Caller.arg_size();
1111*9880d681SAndroid Build Coastguard Worker ArgVals.reserve(NumArgs);
1112*9880d681SAndroid Build Coastguard Worker uint16_t pNum = 1;
1113*9880d681SAndroid Build Coastguard Worker for (CallSite::arg_iterator i = SF.Caller.arg_begin(),
1114*9880d681SAndroid Build Coastguard Worker e = SF.Caller.arg_end(); i != e; ++i, ++pNum) {
1115*9880d681SAndroid Build Coastguard Worker Value *V = *i;
1116*9880d681SAndroid Build Coastguard Worker ArgVals.push_back(getOperandValue(V, SF));
1117*9880d681SAndroid Build Coastguard Worker }
1118*9880d681SAndroid Build Coastguard Worker
1119*9880d681SAndroid Build Coastguard Worker // To handle indirect calls, we must get the pointer value from the argument
1120*9880d681SAndroid Build Coastguard Worker // and treat it as a function pointer.
1121*9880d681SAndroid Build Coastguard Worker GenericValue SRC = getOperandValue(SF.Caller.getCalledValue(), SF);
1122*9880d681SAndroid Build Coastguard Worker callFunction((Function*)GVTOP(SRC), ArgVals);
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker
1125*9880d681SAndroid Build Coastguard Worker // auxiliary function for shift operations
getShiftAmount(uint64_t orgShiftAmount,llvm::APInt valueToShift)1126*9880d681SAndroid Build Coastguard Worker static unsigned getShiftAmount(uint64_t orgShiftAmount,
1127*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift) {
1128*9880d681SAndroid Build Coastguard Worker unsigned valueWidth = valueToShift.getBitWidth();
1129*9880d681SAndroid Build Coastguard Worker if (orgShiftAmount < (uint64_t)valueWidth)
1130*9880d681SAndroid Build Coastguard Worker return orgShiftAmount;
1131*9880d681SAndroid Build Coastguard Worker // according to the llvm documentation, if orgShiftAmount > valueWidth,
1132*9880d681SAndroid Build Coastguard Worker // the result is undfeined. but we do shift by this rule:
1133*9880d681SAndroid Build Coastguard Worker return (NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
1134*9880d681SAndroid Build Coastguard Worker }
1135*9880d681SAndroid Build Coastguard Worker
1136*9880d681SAndroid Build Coastguard Worker
visitShl(BinaryOperator & I)1137*9880d681SAndroid Build Coastguard Worker void Interpreter::visitShl(BinaryOperator &I) {
1138*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1139*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1140*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1141*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1142*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1143*9880d681SAndroid Build Coastguard Worker
1144*9880d681SAndroid Build Coastguard Worker if (Ty->isVectorTy()) {
1145*9880d681SAndroid Build Coastguard Worker uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
1146*9880d681SAndroid Build Coastguard Worker assert(src1Size == Src2.AggregateVal.size());
1147*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < src1Size; i++) {
1148*9880d681SAndroid Build Coastguard Worker GenericValue Result;
1149*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
1150*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
1151*9880d681SAndroid Build Coastguard Worker Result.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
1152*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.push_back(Result);
1153*9880d681SAndroid Build Coastguard Worker }
1154*9880d681SAndroid Build Coastguard Worker } else {
1155*9880d681SAndroid Build Coastguard Worker // scalar
1156*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.IntVal.getZExtValue();
1157*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.IntVal;
1158*9880d681SAndroid Build Coastguard Worker Dest.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
1159*9880d681SAndroid Build Coastguard Worker }
1160*9880d681SAndroid Build Coastguard Worker
1161*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1162*9880d681SAndroid Build Coastguard Worker }
1163*9880d681SAndroid Build Coastguard Worker
visitLShr(BinaryOperator & I)1164*9880d681SAndroid Build Coastguard Worker void Interpreter::visitLShr(BinaryOperator &I) {
1165*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1166*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1167*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1168*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1169*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Worker if (Ty->isVectorTy()) {
1172*9880d681SAndroid Build Coastguard Worker uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
1173*9880d681SAndroid Build Coastguard Worker assert(src1Size == Src2.AggregateVal.size());
1174*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < src1Size; i++) {
1175*9880d681SAndroid Build Coastguard Worker GenericValue Result;
1176*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
1177*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
1178*9880d681SAndroid Build Coastguard Worker Result.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
1179*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.push_back(Result);
1180*9880d681SAndroid Build Coastguard Worker }
1181*9880d681SAndroid Build Coastguard Worker } else {
1182*9880d681SAndroid Build Coastguard Worker // scalar
1183*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.IntVal.getZExtValue();
1184*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.IntVal;
1185*9880d681SAndroid Build Coastguard Worker Dest.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
1186*9880d681SAndroid Build Coastguard Worker }
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1189*9880d681SAndroid Build Coastguard Worker }
1190*9880d681SAndroid Build Coastguard Worker
visitAShr(BinaryOperator & I)1191*9880d681SAndroid Build Coastguard Worker void Interpreter::visitAShr(BinaryOperator &I) {
1192*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1193*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1194*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1195*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1196*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1197*9880d681SAndroid Build Coastguard Worker
1198*9880d681SAndroid Build Coastguard Worker if (Ty->isVectorTy()) {
1199*9880d681SAndroid Build Coastguard Worker size_t src1Size = Src1.AggregateVal.size();
1200*9880d681SAndroid Build Coastguard Worker assert(src1Size == Src2.AggregateVal.size());
1201*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < src1Size; i++) {
1202*9880d681SAndroid Build Coastguard Worker GenericValue Result;
1203*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
1204*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
1205*9880d681SAndroid Build Coastguard Worker Result.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
1206*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.push_back(Result);
1207*9880d681SAndroid Build Coastguard Worker }
1208*9880d681SAndroid Build Coastguard Worker } else {
1209*9880d681SAndroid Build Coastguard Worker // scalar
1210*9880d681SAndroid Build Coastguard Worker uint64_t shiftAmount = Src2.IntVal.getZExtValue();
1211*9880d681SAndroid Build Coastguard Worker llvm::APInt valueToShift = Src1.IntVal;
1212*9880d681SAndroid Build Coastguard Worker Dest.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
1213*9880d681SAndroid Build Coastguard Worker }
1214*9880d681SAndroid Build Coastguard Worker
1215*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1216*9880d681SAndroid Build Coastguard Worker }
1217*9880d681SAndroid Build Coastguard Worker
executeTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1218*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeTruncInst(Value *SrcVal, Type *DstTy,
1219*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1220*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1221*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1222*9880d681SAndroid Build Coastguard Worker if (SrcTy->isVectorTy()) {
1223*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1224*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1225*9880d681SAndroid Build Coastguard Worker unsigned NumElts = Src.AggregateVal.size();
1226*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal
1227*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(NumElts);
1228*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < NumElts; i++)
1229*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.trunc(DBitWidth);
1230*9880d681SAndroid Build Coastguard Worker } else {
1231*9880d681SAndroid Build Coastguard Worker IntegerType *DITy = cast<IntegerType>(DstTy);
1232*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = DITy->getBitWidth();
1233*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src.IntVal.trunc(DBitWidth);
1234*9880d681SAndroid Build Coastguard Worker }
1235*9880d681SAndroid Build Coastguard Worker return Dest;
1236*9880d681SAndroid Build Coastguard Worker }
1237*9880d681SAndroid Build Coastguard Worker
executeSExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1238*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy,
1239*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1240*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1241*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1242*9880d681SAndroid Build Coastguard Worker if (SrcTy->isVectorTy()) {
1243*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1244*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1245*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1246*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal.
1247*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1248*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1249*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
1250*9880d681SAndroid Build Coastguard Worker } else {
1251*9880d681SAndroid Build Coastguard Worker auto *DITy = cast<IntegerType>(DstTy);
1252*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = DITy->getBitWidth();
1253*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src.IntVal.sext(DBitWidth);
1254*9880d681SAndroid Build Coastguard Worker }
1255*9880d681SAndroid Build Coastguard Worker return Dest;
1256*9880d681SAndroid Build Coastguard Worker }
1257*9880d681SAndroid Build Coastguard Worker
executeZExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1258*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy,
1259*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1260*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1261*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1262*9880d681SAndroid Build Coastguard Worker if (SrcTy->isVectorTy()) {
1263*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1264*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1265*9880d681SAndroid Build Coastguard Worker
1266*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1267*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal.
1268*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1269*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1270*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
1271*9880d681SAndroid Build Coastguard Worker } else {
1272*9880d681SAndroid Build Coastguard Worker auto *DITy = cast<IntegerType>(DstTy);
1273*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = DITy->getBitWidth();
1274*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src.IntVal.zext(DBitWidth);
1275*9880d681SAndroid Build Coastguard Worker }
1276*9880d681SAndroid Build Coastguard Worker return Dest;
1277*9880d681SAndroid Build Coastguard Worker }
1278*9880d681SAndroid Build Coastguard Worker
executeFPTruncInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1279*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, Type *DstTy,
1280*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1281*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1282*9880d681SAndroid Build Coastguard Worker
1283*9880d681SAndroid Build Coastguard Worker if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
1284*9880d681SAndroid Build Coastguard Worker assert(SrcVal->getType()->getScalarType()->isDoubleTy() &&
1285*9880d681SAndroid Build Coastguard Worker DstTy->getScalarType()->isFloatTy() &&
1286*9880d681SAndroid Build Coastguard Worker "Invalid FPTrunc instruction");
1287*9880d681SAndroid Build Coastguard Worker
1288*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1289*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal.
1290*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1291*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1292*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal = (float)Src.AggregateVal[i].DoubleVal;
1293*9880d681SAndroid Build Coastguard Worker } else {
1294*9880d681SAndroid Build Coastguard Worker assert(SrcVal->getType()->isDoubleTy() && DstTy->isFloatTy() &&
1295*9880d681SAndroid Build Coastguard Worker "Invalid FPTrunc instruction");
1296*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = (float)Src.DoubleVal;
1297*9880d681SAndroid Build Coastguard Worker }
1298*9880d681SAndroid Build Coastguard Worker
1299*9880d681SAndroid Build Coastguard Worker return Dest;
1300*9880d681SAndroid Build Coastguard Worker }
1301*9880d681SAndroid Build Coastguard Worker
executeFPExtInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1302*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeFPExtInst(Value *SrcVal, Type *DstTy,
1303*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1304*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1305*9880d681SAndroid Build Coastguard Worker
1306*9880d681SAndroid Build Coastguard Worker if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
1307*9880d681SAndroid Build Coastguard Worker assert(SrcVal->getType()->getScalarType()->isFloatTy() &&
1308*9880d681SAndroid Build Coastguard Worker DstTy->getScalarType()->isDoubleTy() && "Invalid FPExt instruction");
1309*9880d681SAndroid Build Coastguard Worker
1310*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1311*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal.
1312*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1313*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1314*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal = (double)Src.AggregateVal[i].FloatVal;
1315*9880d681SAndroid Build Coastguard Worker } else {
1316*9880d681SAndroid Build Coastguard Worker assert(SrcVal->getType()->isFloatTy() && DstTy->isDoubleTy() &&
1317*9880d681SAndroid Build Coastguard Worker "Invalid FPExt instruction");
1318*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = (double)Src.FloatVal;
1319*9880d681SAndroid Build Coastguard Worker }
1320*9880d681SAndroid Build Coastguard Worker
1321*9880d681SAndroid Build Coastguard Worker return Dest;
1322*9880d681SAndroid Build Coastguard Worker }
1323*9880d681SAndroid Build Coastguard Worker
executeFPToUIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1324*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, Type *DstTy,
1325*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1326*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1327*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1328*9880d681SAndroid Build Coastguard Worker
1329*9880d681SAndroid Build Coastguard Worker if (SrcTy->getTypeID() == Type::VectorTyID) {
1330*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1331*9880d681SAndroid Build Coastguard Worker Type *SrcVecTy = SrcTy->getScalarType();
1332*9880d681SAndroid Build Coastguard Worker uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1333*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1334*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal.
1335*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1336*9880d681SAndroid Build Coastguard Worker
1337*9880d681SAndroid Build Coastguard Worker if (SrcVecTy->getTypeID() == Type::FloatTyID) {
1338*9880d681SAndroid Build Coastguard Worker assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToUI instruction");
1339*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1340*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
1341*9880d681SAndroid Build Coastguard Worker Src.AggregateVal[i].FloatVal, DBitWidth);
1342*9880d681SAndroid Build Coastguard Worker } else {
1343*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1344*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
1345*9880d681SAndroid Build Coastguard Worker Src.AggregateVal[i].DoubleVal, DBitWidth);
1346*9880d681SAndroid Build Coastguard Worker }
1347*9880d681SAndroid Build Coastguard Worker } else {
1348*9880d681SAndroid Build Coastguard Worker // scalar
1349*9880d681SAndroid Build Coastguard Worker uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1350*9880d681SAndroid Build Coastguard Worker assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
1351*9880d681SAndroid Build Coastguard Worker
1352*9880d681SAndroid Build Coastguard Worker if (SrcTy->getTypeID() == Type::FloatTyID)
1353*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
1354*9880d681SAndroid Build Coastguard Worker else {
1355*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
1356*9880d681SAndroid Build Coastguard Worker }
1357*9880d681SAndroid Build Coastguard Worker }
1358*9880d681SAndroid Build Coastguard Worker
1359*9880d681SAndroid Build Coastguard Worker return Dest;
1360*9880d681SAndroid Build Coastguard Worker }
1361*9880d681SAndroid Build Coastguard Worker
executeFPToSIInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1362*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, Type *DstTy,
1363*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1364*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1365*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1366*9880d681SAndroid Build Coastguard Worker
1367*9880d681SAndroid Build Coastguard Worker if (SrcTy->getTypeID() == Type::VectorTyID) {
1368*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1369*9880d681SAndroid Build Coastguard Worker Type *SrcVecTy = SrcTy->getScalarType();
1370*9880d681SAndroid Build Coastguard Worker uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
1371*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1372*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal
1373*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1374*9880d681SAndroid Build Coastguard Worker
1375*9880d681SAndroid Build Coastguard Worker if (SrcVecTy->getTypeID() == Type::FloatTyID) {
1376*9880d681SAndroid Build Coastguard Worker assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToSI instruction");
1377*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1378*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
1379*9880d681SAndroid Build Coastguard Worker Src.AggregateVal[i].FloatVal, DBitWidth);
1380*9880d681SAndroid Build Coastguard Worker } else {
1381*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1382*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
1383*9880d681SAndroid Build Coastguard Worker Src.AggregateVal[i].DoubleVal, DBitWidth);
1384*9880d681SAndroid Build Coastguard Worker }
1385*9880d681SAndroid Build Coastguard Worker } else {
1386*9880d681SAndroid Build Coastguard Worker // scalar
1387*9880d681SAndroid Build Coastguard Worker unsigned DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1388*9880d681SAndroid Build Coastguard Worker assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
1389*9880d681SAndroid Build Coastguard Worker
1390*9880d681SAndroid Build Coastguard Worker if (SrcTy->getTypeID() == Type::FloatTyID)
1391*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
1392*9880d681SAndroid Build Coastguard Worker else {
1393*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
1394*9880d681SAndroid Build Coastguard Worker }
1395*9880d681SAndroid Build Coastguard Worker }
1396*9880d681SAndroid Build Coastguard Worker return Dest;
1397*9880d681SAndroid Build Coastguard Worker }
1398*9880d681SAndroid Build Coastguard Worker
executeUIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1399*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, Type *DstTy,
1400*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1401*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1402*9880d681SAndroid Build Coastguard Worker
1403*9880d681SAndroid Build Coastguard Worker if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
1404*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1405*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1406*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal
1407*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1408*9880d681SAndroid Build Coastguard Worker
1409*9880d681SAndroid Build Coastguard Worker if (DstVecTy->getTypeID() == Type::FloatTyID) {
1410*9880d681SAndroid Build Coastguard Worker assert(DstVecTy->isFloatingPointTy() && "Invalid UIToFP instruction");
1411*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1412*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal =
1413*9880d681SAndroid Build Coastguard Worker APIntOps::RoundAPIntToFloat(Src.AggregateVal[i].IntVal);
1414*9880d681SAndroid Build Coastguard Worker } else {
1415*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1416*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal =
1417*9880d681SAndroid Build Coastguard Worker APIntOps::RoundAPIntToDouble(Src.AggregateVal[i].IntVal);
1418*9880d681SAndroid Build Coastguard Worker }
1419*9880d681SAndroid Build Coastguard Worker } else {
1420*9880d681SAndroid Build Coastguard Worker // scalar
1421*9880d681SAndroid Build Coastguard Worker assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
1422*9880d681SAndroid Build Coastguard Worker if (DstTy->getTypeID() == Type::FloatTyID)
1423*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
1424*9880d681SAndroid Build Coastguard Worker else {
1425*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = APIntOps::RoundAPIntToDouble(Src.IntVal);
1426*9880d681SAndroid Build Coastguard Worker }
1427*9880d681SAndroid Build Coastguard Worker }
1428*9880d681SAndroid Build Coastguard Worker return Dest;
1429*9880d681SAndroid Build Coastguard Worker }
1430*9880d681SAndroid Build Coastguard Worker
executeSIToFPInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1431*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, Type *DstTy,
1432*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1433*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1434*9880d681SAndroid Build Coastguard Worker
1435*9880d681SAndroid Build Coastguard Worker if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
1436*9880d681SAndroid Build Coastguard Worker Type *DstVecTy = DstTy->getScalarType();
1437*9880d681SAndroid Build Coastguard Worker unsigned size = Src.AggregateVal.size();
1438*9880d681SAndroid Build Coastguard Worker // the sizes of src and dst vectors must be equal
1439*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(size);
1440*9880d681SAndroid Build Coastguard Worker
1441*9880d681SAndroid Build Coastguard Worker if (DstVecTy->getTypeID() == Type::FloatTyID) {
1442*9880d681SAndroid Build Coastguard Worker assert(DstVecTy->isFloatingPointTy() && "Invalid SIToFP instruction");
1443*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1444*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal =
1445*9880d681SAndroid Build Coastguard Worker APIntOps::RoundSignedAPIntToFloat(Src.AggregateVal[i].IntVal);
1446*9880d681SAndroid Build Coastguard Worker } else {
1447*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
1448*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal =
1449*9880d681SAndroid Build Coastguard Worker APIntOps::RoundSignedAPIntToDouble(Src.AggregateVal[i].IntVal);
1450*9880d681SAndroid Build Coastguard Worker }
1451*9880d681SAndroid Build Coastguard Worker } else {
1452*9880d681SAndroid Build Coastguard Worker // scalar
1453*9880d681SAndroid Build Coastguard Worker assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
1454*9880d681SAndroid Build Coastguard Worker
1455*9880d681SAndroid Build Coastguard Worker if (DstTy->getTypeID() == Type::FloatTyID)
1456*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
1457*9880d681SAndroid Build Coastguard Worker else {
1458*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = APIntOps::RoundSignedAPIntToDouble(Src.IntVal);
1459*9880d681SAndroid Build Coastguard Worker }
1460*9880d681SAndroid Build Coastguard Worker }
1461*9880d681SAndroid Build Coastguard Worker
1462*9880d681SAndroid Build Coastguard Worker return Dest;
1463*9880d681SAndroid Build Coastguard Worker }
1464*9880d681SAndroid Build Coastguard Worker
executePtrToIntInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1465*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, Type *DstTy,
1466*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1467*9880d681SAndroid Build Coastguard Worker uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
1468*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1469*9880d681SAndroid Build Coastguard Worker assert(SrcVal->getType()->isPointerTy() && "Invalid PtrToInt instruction");
1470*9880d681SAndroid Build Coastguard Worker
1471*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
1472*9880d681SAndroid Build Coastguard Worker return Dest;
1473*9880d681SAndroid Build Coastguard Worker }
1474*9880d681SAndroid Build Coastguard Worker
executeIntToPtrInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1475*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, Type *DstTy,
1476*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1477*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1478*9880d681SAndroid Build Coastguard Worker assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
1479*9880d681SAndroid Build Coastguard Worker
1480*9880d681SAndroid Build Coastguard Worker uint32_t PtrSize = getDataLayout().getPointerSizeInBits();
1481*9880d681SAndroid Build Coastguard Worker if (PtrSize != Src.IntVal.getBitWidth())
1482*9880d681SAndroid Build Coastguard Worker Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
1483*9880d681SAndroid Build Coastguard Worker
1484*9880d681SAndroid Build Coastguard Worker Dest.PointerVal = PointerTy(intptr_t(Src.IntVal.getZExtValue()));
1485*9880d681SAndroid Build Coastguard Worker return Dest;
1486*9880d681SAndroid Build Coastguard Worker }
1487*9880d681SAndroid Build Coastguard Worker
executeBitCastInst(Value * SrcVal,Type * DstTy,ExecutionContext & SF)1488*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy,
1489*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1490*9880d681SAndroid Build Coastguard Worker
1491*9880d681SAndroid Build Coastguard Worker // This instruction supports bitwise conversion of vectors to integers and
1492*9880d681SAndroid Build Coastguard Worker // to vectors of other types (as long as they have the same size)
1493*9880d681SAndroid Build Coastguard Worker Type *SrcTy = SrcVal->getType();
1494*9880d681SAndroid Build Coastguard Worker GenericValue Dest, Src = getOperandValue(SrcVal, SF);
1495*9880d681SAndroid Build Coastguard Worker
1496*9880d681SAndroid Build Coastguard Worker if ((SrcTy->getTypeID() == Type::VectorTyID) ||
1497*9880d681SAndroid Build Coastguard Worker (DstTy->getTypeID() == Type::VectorTyID)) {
1498*9880d681SAndroid Build Coastguard Worker // vector src bitcast to vector dst or vector src bitcast to scalar dst or
1499*9880d681SAndroid Build Coastguard Worker // scalar src bitcast to vector dst
1500*9880d681SAndroid Build Coastguard Worker bool isLittleEndian = getDataLayout().isLittleEndian();
1501*9880d681SAndroid Build Coastguard Worker GenericValue TempDst, TempSrc, SrcVec;
1502*9880d681SAndroid Build Coastguard Worker Type *SrcElemTy;
1503*9880d681SAndroid Build Coastguard Worker Type *DstElemTy;
1504*9880d681SAndroid Build Coastguard Worker unsigned SrcBitSize;
1505*9880d681SAndroid Build Coastguard Worker unsigned DstBitSize;
1506*9880d681SAndroid Build Coastguard Worker unsigned SrcNum;
1507*9880d681SAndroid Build Coastguard Worker unsigned DstNum;
1508*9880d681SAndroid Build Coastguard Worker
1509*9880d681SAndroid Build Coastguard Worker if (SrcTy->getTypeID() == Type::VectorTyID) {
1510*9880d681SAndroid Build Coastguard Worker SrcElemTy = SrcTy->getScalarType();
1511*9880d681SAndroid Build Coastguard Worker SrcBitSize = SrcTy->getScalarSizeInBits();
1512*9880d681SAndroid Build Coastguard Worker SrcNum = Src.AggregateVal.size();
1513*9880d681SAndroid Build Coastguard Worker SrcVec = Src;
1514*9880d681SAndroid Build Coastguard Worker } else {
1515*9880d681SAndroid Build Coastguard Worker // if src is scalar value, make it vector <1 x type>
1516*9880d681SAndroid Build Coastguard Worker SrcElemTy = SrcTy;
1517*9880d681SAndroid Build Coastguard Worker SrcBitSize = SrcTy->getPrimitiveSizeInBits();
1518*9880d681SAndroid Build Coastguard Worker SrcNum = 1;
1519*9880d681SAndroid Build Coastguard Worker SrcVec.AggregateVal.push_back(Src);
1520*9880d681SAndroid Build Coastguard Worker }
1521*9880d681SAndroid Build Coastguard Worker
1522*9880d681SAndroid Build Coastguard Worker if (DstTy->getTypeID() == Type::VectorTyID) {
1523*9880d681SAndroid Build Coastguard Worker DstElemTy = DstTy->getScalarType();
1524*9880d681SAndroid Build Coastguard Worker DstBitSize = DstTy->getScalarSizeInBits();
1525*9880d681SAndroid Build Coastguard Worker DstNum = (SrcNum * SrcBitSize) / DstBitSize;
1526*9880d681SAndroid Build Coastguard Worker } else {
1527*9880d681SAndroid Build Coastguard Worker DstElemTy = DstTy;
1528*9880d681SAndroid Build Coastguard Worker DstBitSize = DstTy->getPrimitiveSizeInBits();
1529*9880d681SAndroid Build Coastguard Worker DstNum = 1;
1530*9880d681SAndroid Build Coastguard Worker }
1531*9880d681SAndroid Build Coastguard Worker
1532*9880d681SAndroid Build Coastguard Worker if (SrcNum * SrcBitSize != DstNum * DstBitSize)
1533*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid BitCast");
1534*9880d681SAndroid Build Coastguard Worker
1535*9880d681SAndroid Build Coastguard Worker // If src is floating point, cast to integer first.
1536*9880d681SAndroid Build Coastguard Worker TempSrc.AggregateVal.resize(SrcNum);
1537*9880d681SAndroid Build Coastguard Worker if (SrcElemTy->isFloatTy()) {
1538*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < SrcNum; i++)
1539*9880d681SAndroid Build Coastguard Worker TempSrc.AggregateVal[i].IntVal =
1540*9880d681SAndroid Build Coastguard Worker APInt::floatToBits(SrcVec.AggregateVal[i].FloatVal);
1541*9880d681SAndroid Build Coastguard Worker
1542*9880d681SAndroid Build Coastguard Worker } else if (SrcElemTy->isDoubleTy()) {
1543*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < SrcNum; i++)
1544*9880d681SAndroid Build Coastguard Worker TempSrc.AggregateVal[i].IntVal =
1545*9880d681SAndroid Build Coastguard Worker APInt::doubleToBits(SrcVec.AggregateVal[i].DoubleVal);
1546*9880d681SAndroid Build Coastguard Worker } else if (SrcElemTy->isIntegerTy()) {
1547*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < SrcNum; i++)
1548*9880d681SAndroid Build Coastguard Worker TempSrc.AggregateVal[i].IntVal = SrcVec.AggregateVal[i].IntVal;
1549*9880d681SAndroid Build Coastguard Worker } else {
1550*9880d681SAndroid Build Coastguard Worker // Pointers are not allowed as the element type of vector.
1551*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid Bitcast");
1552*9880d681SAndroid Build Coastguard Worker }
1553*9880d681SAndroid Build Coastguard Worker
1554*9880d681SAndroid Build Coastguard Worker // now TempSrc is integer type vector
1555*9880d681SAndroid Build Coastguard Worker if (DstNum < SrcNum) {
1556*9880d681SAndroid Build Coastguard Worker // Example: bitcast <4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>
1557*9880d681SAndroid Build Coastguard Worker unsigned Ratio = SrcNum / DstNum;
1558*9880d681SAndroid Build Coastguard Worker unsigned SrcElt = 0;
1559*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < DstNum; i++) {
1560*9880d681SAndroid Build Coastguard Worker GenericValue Elt;
1561*9880d681SAndroid Build Coastguard Worker Elt.IntVal = 0;
1562*9880d681SAndroid Build Coastguard Worker Elt.IntVal = Elt.IntVal.zext(DstBitSize);
1563*9880d681SAndroid Build Coastguard Worker unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
1564*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < Ratio; j++) {
1565*9880d681SAndroid Build Coastguard Worker APInt Tmp;
1566*9880d681SAndroid Build Coastguard Worker Tmp = Tmp.zext(SrcBitSize);
1567*9880d681SAndroid Build Coastguard Worker Tmp = TempSrc.AggregateVal[SrcElt++].IntVal;
1568*9880d681SAndroid Build Coastguard Worker Tmp = Tmp.zext(DstBitSize);
1569*9880d681SAndroid Build Coastguard Worker Tmp = Tmp.shl(ShiftAmt);
1570*9880d681SAndroid Build Coastguard Worker ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
1571*9880d681SAndroid Build Coastguard Worker Elt.IntVal |= Tmp;
1572*9880d681SAndroid Build Coastguard Worker }
1573*9880d681SAndroid Build Coastguard Worker TempDst.AggregateVal.push_back(Elt);
1574*9880d681SAndroid Build Coastguard Worker }
1575*9880d681SAndroid Build Coastguard Worker } else {
1576*9880d681SAndroid Build Coastguard Worker // Example: bitcast <2 x i64> <i64 0, i64 1> to <4 x i32>
1577*9880d681SAndroid Build Coastguard Worker unsigned Ratio = DstNum / SrcNum;
1578*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < SrcNum; i++) {
1579*9880d681SAndroid Build Coastguard Worker unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
1580*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < Ratio; j++) {
1581*9880d681SAndroid Build Coastguard Worker GenericValue Elt;
1582*9880d681SAndroid Build Coastguard Worker Elt.IntVal = Elt.IntVal.zext(SrcBitSize);
1583*9880d681SAndroid Build Coastguard Worker Elt.IntVal = TempSrc.AggregateVal[i].IntVal;
1584*9880d681SAndroid Build Coastguard Worker Elt.IntVal = Elt.IntVal.lshr(ShiftAmt);
1585*9880d681SAndroid Build Coastguard Worker // it could be DstBitSize == SrcBitSize, so check it
1586*9880d681SAndroid Build Coastguard Worker if (DstBitSize < SrcBitSize)
1587*9880d681SAndroid Build Coastguard Worker Elt.IntVal = Elt.IntVal.trunc(DstBitSize);
1588*9880d681SAndroid Build Coastguard Worker ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
1589*9880d681SAndroid Build Coastguard Worker TempDst.AggregateVal.push_back(Elt);
1590*9880d681SAndroid Build Coastguard Worker }
1591*9880d681SAndroid Build Coastguard Worker }
1592*9880d681SAndroid Build Coastguard Worker }
1593*9880d681SAndroid Build Coastguard Worker
1594*9880d681SAndroid Build Coastguard Worker // convert result from integer to specified type
1595*9880d681SAndroid Build Coastguard Worker if (DstTy->getTypeID() == Type::VectorTyID) {
1596*9880d681SAndroid Build Coastguard Worker if (DstElemTy->isDoubleTy()) {
1597*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(DstNum);
1598*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < DstNum; i++)
1599*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal =
1600*9880d681SAndroid Build Coastguard Worker TempDst.AggregateVal[i].IntVal.bitsToDouble();
1601*9880d681SAndroid Build Coastguard Worker } else if (DstElemTy->isFloatTy()) {
1602*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(DstNum);
1603*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < DstNum; i++)
1604*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal =
1605*9880d681SAndroid Build Coastguard Worker TempDst.AggregateVal[i].IntVal.bitsToFloat();
1606*9880d681SAndroid Build Coastguard Worker } else {
1607*9880d681SAndroid Build Coastguard Worker Dest = TempDst;
1608*9880d681SAndroid Build Coastguard Worker }
1609*9880d681SAndroid Build Coastguard Worker } else {
1610*9880d681SAndroid Build Coastguard Worker if (DstElemTy->isDoubleTy())
1611*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = TempDst.AggregateVal[0].IntVal.bitsToDouble();
1612*9880d681SAndroid Build Coastguard Worker else if (DstElemTy->isFloatTy()) {
1613*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = TempDst.AggregateVal[0].IntVal.bitsToFloat();
1614*9880d681SAndroid Build Coastguard Worker } else {
1615*9880d681SAndroid Build Coastguard Worker Dest.IntVal = TempDst.AggregateVal[0].IntVal;
1616*9880d681SAndroid Build Coastguard Worker }
1617*9880d681SAndroid Build Coastguard Worker }
1618*9880d681SAndroid Build Coastguard Worker } else { // if ((SrcTy->getTypeID() == Type::VectorTyID) ||
1619*9880d681SAndroid Build Coastguard Worker // (DstTy->getTypeID() == Type::VectorTyID))
1620*9880d681SAndroid Build Coastguard Worker
1621*9880d681SAndroid Build Coastguard Worker // scalar src bitcast to scalar dst
1622*9880d681SAndroid Build Coastguard Worker if (DstTy->isPointerTy()) {
1623*9880d681SAndroid Build Coastguard Worker assert(SrcTy->isPointerTy() && "Invalid BitCast");
1624*9880d681SAndroid Build Coastguard Worker Dest.PointerVal = Src.PointerVal;
1625*9880d681SAndroid Build Coastguard Worker } else if (DstTy->isIntegerTy()) {
1626*9880d681SAndroid Build Coastguard Worker if (SrcTy->isFloatTy())
1627*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt::floatToBits(Src.FloatVal);
1628*9880d681SAndroid Build Coastguard Worker else if (SrcTy->isDoubleTy()) {
1629*9880d681SAndroid Build Coastguard Worker Dest.IntVal = APInt::doubleToBits(Src.DoubleVal);
1630*9880d681SAndroid Build Coastguard Worker } else if (SrcTy->isIntegerTy()) {
1631*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src.IntVal;
1632*9880d681SAndroid Build Coastguard Worker } else {
1633*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid BitCast");
1634*9880d681SAndroid Build Coastguard Worker }
1635*9880d681SAndroid Build Coastguard Worker } else if (DstTy->isFloatTy()) {
1636*9880d681SAndroid Build Coastguard Worker if (SrcTy->isIntegerTy())
1637*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = Src.IntVal.bitsToFloat();
1638*9880d681SAndroid Build Coastguard Worker else {
1639*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = Src.FloatVal;
1640*9880d681SAndroid Build Coastguard Worker }
1641*9880d681SAndroid Build Coastguard Worker } else if (DstTy->isDoubleTy()) {
1642*9880d681SAndroid Build Coastguard Worker if (SrcTy->isIntegerTy())
1643*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = Src.IntVal.bitsToDouble();
1644*9880d681SAndroid Build Coastguard Worker else {
1645*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = Src.DoubleVal;
1646*9880d681SAndroid Build Coastguard Worker }
1647*9880d681SAndroid Build Coastguard Worker } else {
1648*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid Bitcast");
1649*9880d681SAndroid Build Coastguard Worker }
1650*9880d681SAndroid Build Coastguard Worker }
1651*9880d681SAndroid Build Coastguard Worker
1652*9880d681SAndroid Build Coastguard Worker return Dest;
1653*9880d681SAndroid Build Coastguard Worker }
1654*9880d681SAndroid Build Coastguard Worker
visitTruncInst(TruncInst & I)1655*9880d681SAndroid Build Coastguard Worker void Interpreter::visitTruncInst(TruncInst &I) {
1656*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1657*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
1658*9880d681SAndroid Build Coastguard Worker }
1659*9880d681SAndroid Build Coastguard Worker
visitSExtInst(SExtInst & I)1660*9880d681SAndroid Build Coastguard Worker void Interpreter::visitSExtInst(SExtInst &I) {
1661*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1662*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeSExtInst(I.getOperand(0), I.getType(), SF), SF);
1663*9880d681SAndroid Build Coastguard Worker }
1664*9880d681SAndroid Build Coastguard Worker
visitZExtInst(ZExtInst & I)1665*9880d681SAndroid Build Coastguard Worker void Interpreter::visitZExtInst(ZExtInst &I) {
1666*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1667*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeZExtInst(I.getOperand(0), I.getType(), SF), SF);
1668*9880d681SAndroid Build Coastguard Worker }
1669*9880d681SAndroid Build Coastguard Worker
visitFPTruncInst(FPTruncInst & I)1670*9880d681SAndroid Build Coastguard Worker void Interpreter::visitFPTruncInst(FPTruncInst &I) {
1671*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1672*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeFPTruncInst(I.getOperand(0), I.getType(), SF), SF);
1673*9880d681SAndroid Build Coastguard Worker }
1674*9880d681SAndroid Build Coastguard Worker
visitFPExtInst(FPExtInst & I)1675*9880d681SAndroid Build Coastguard Worker void Interpreter::visitFPExtInst(FPExtInst &I) {
1676*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1677*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeFPExtInst(I.getOperand(0), I.getType(), SF), SF);
1678*9880d681SAndroid Build Coastguard Worker }
1679*9880d681SAndroid Build Coastguard Worker
visitUIToFPInst(UIToFPInst & I)1680*9880d681SAndroid Build Coastguard Worker void Interpreter::visitUIToFPInst(UIToFPInst &I) {
1681*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1682*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeUIToFPInst(I.getOperand(0), I.getType(), SF), SF);
1683*9880d681SAndroid Build Coastguard Worker }
1684*9880d681SAndroid Build Coastguard Worker
visitSIToFPInst(SIToFPInst & I)1685*9880d681SAndroid Build Coastguard Worker void Interpreter::visitSIToFPInst(SIToFPInst &I) {
1686*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1687*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeSIToFPInst(I.getOperand(0), I.getType(), SF), SF);
1688*9880d681SAndroid Build Coastguard Worker }
1689*9880d681SAndroid Build Coastguard Worker
visitFPToUIInst(FPToUIInst & I)1690*9880d681SAndroid Build Coastguard Worker void Interpreter::visitFPToUIInst(FPToUIInst &I) {
1691*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1692*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeFPToUIInst(I.getOperand(0), I.getType(), SF), SF);
1693*9880d681SAndroid Build Coastguard Worker }
1694*9880d681SAndroid Build Coastguard Worker
visitFPToSIInst(FPToSIInst & I)1695*9880d681SAndroid Build Coastguard Worker void Interpreter::visitFPToSIInst(FPToSIInst &I) {
1696*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1697*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeFPToSIInst(I.getOperand(0), I.getType(), SF), SF);
1698*9880d681SAndroid Build Coastguard Worker }
1699*9880d681SAndroid Build Coastguard Worker
visitPtrToIntInst(PtrToIntInst & I)1700*9880d681SAndroid Build Coastguard Worker void Interpreter::visitPtrToIntInst(PtrToIntInst &I) {
1701*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1702*9880d681SAndroid Build Coastguard Worker SetValue(&I, executePtrToIntInst(I.getOperand(0), I.getType(), SF), SF);
1703*9880d681SAndroid Build Coastguard Worker }
1704*9880d681SAndroid Build Coastguard Worker
visitIntToPtrInst(IntToPtrInst & I)1705*9880d681SAndroid Build Coastguard Worker void Interpreter::visitIntToPtrInst(IntToPtrInst &I) {
1706*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1707*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeIntToPtrInst(I.getOperand(0), I.getType(), SF), SF);
1708*9880d681SAndroid Build Coastguard Worker }
1709*9880d681SAndroid Build Coastguard Worker
visitBitCastInst(BitCastInst & I)1710*9880d681SAndroid Build Coastguard Worker void Interpreter::visitBitCastInst(BitCastInst &I) {
1711*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1712*9880d681SAndroid Build Coastguard Worker SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
1713*9880d681SAndroid Build Coastguard Worker }
1714*9880d681SAndroid Build Coastguard Worker
1715*9880d681SAndroid Build Coastguard Worker #define IMPLEMENT_VAARG(TY) \
1716*9880d681SAndroid Build Coastguard Worker case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
1717*9880d681SAndroid Build Coastguard Worker
visitVAArgInst(VAArgInst & I)1718*9880d681SAndroid Build Coastguard Worker void Interpreter::visitVAArgInst(VAArgInst &I) {
1719*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1720*9880d681SAndroid Build Coastguard Worker
1721*9880d681SAndroid Build Coastguard Worker // Get the incoming valist parameter. LLI treats the valist as a
1722*9880d681SAndroid Build Coastguard Worker // (ec-stack-depth var-arg-index) pair.
1723*9880d681SAndroid Build Coastguard Worker GenericValue VAList = getOperandValue(I.getOperand(0), SF);
1724*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1725*9880d681SAndroid Build Coastguard Worker GenericValue Src = ECStack[VAList.UIntPairVal.first]
1726*9880d681SAndroid Build Coastguard Worker .VarArgs[VAList.UIntPairVal.second];
1727*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1728*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
1729*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1730*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src.IntVal;
1731*9880d681SAndroid Build Coastguard Worker break;
1732*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VAARG(Pointer);
1733*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VAARG(Float);
1734*9880d681SAndroid Build Coastguard Worker IMPLEMENT_VAARG(Double);
1735*9880d681SAndroid Build Coastguard Worker default:
1736*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
1737*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
1738*9880d681SAndroid Build Coastguard Worker }
1739*9880d681SAndroid Build Coastguard Worker
1740*9880d681SAndroid Build Coastguard Worker // Set the Value of this Instruction.
1741*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1742*9880d681SAndroid Build Coastguard Worker
1743*9880d681SAndroid Build Coastguard Worker // Move the pointer to the next vararg.
1744*9880d681SAndroid Build Coastguard Worker ++VAList.UIntPairVal.second;
1745*9880d681SAndroid Build Coastguard Worker }
1746*9880d681SAndroid Build Coastguard Worker
visitExtractElementInst(ExtractElementInst & I)1747*9880d681SAndroid Build Coastguard Worker void Interpreter::visitExtractElementInst(ExtractElementInst &I) {
1748*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1749*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1750*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1751*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1752*9880d681SAndroid Build Coastguard Worker
1753*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1754*9880d681SAndroid Build Coastguard Worker const unsigned indx = unsigned(Src2.IntVal.getZExtValue());
1755*9880d681SAndroid Build Coastguard Worker
1756*9880d681SAndroid Build Coastguard Worker if(Src1.AggregateVal.size() > indx) {
1757*9880d681SAndroid Build Coastguard Worker switch (Ty->getTypeID()) {
1758*9880d681SAndroid Build Coastguard Worker default:
1759*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled destination type for extractelement instruction: "
1760*9880d681SAndroid Build Coastguard Worker << *Ty << "\n";
1761*9880d681SAndroid Build Coastguard Worker llvm_unreachable(nullptr);
1762*9880d681SAndroid Build Coastguard Worker break;
1763*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1764*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Src1.AggregateVal[indx].IntVal;
1765*9880d681SAndroid Build Coastguard Worker break;
1766*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
1767*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = Src1.AggregateVal[indx].FloatVal;
1768*9880d681SAndroid Build Coastguard Worker break;
1769*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
1770*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = Src1.AggregateVal[indx].DoubleVal;
1771*9880d681SAndroid Build Coastguard Worker break;
1772*9880d681SAndroid Build Coastguard Worker }
1773*9880d681SAndroid Build Coastguard Worker } else {
1774*9880d681SAndroid Build Coastguard Worker dbgs() << "Invalid index in extractelement instruction\n";
1775*9880d681SAndroid Build Coastguard Worker }
1776*9880d681SAndroid Build Coastguard Worker
1777*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1778*9880d681SAndroid Build Coastguard Worker }
1779*9880d681SAndroid Build Coastguard Worker
visitInsertElementInst(InsertElementInst & I)1780*9880d681SAndroid Build Coastguard Worker void Interpreter::visitInsertElementInst(InsertElementInst &I) {
1781*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1782*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1783*9880d681SAndroid Build Coastguard Worker
1784*9880d681SAndroid Build Coastguard Worker if(!(Ty->isVectorTy()) )
1785*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for insertelement instruction");
1786*9880d681SAndroid Build Coastguard Worker
1787*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1788*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1789*9880d681SAndroid Build Coastguard Worker GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
1790*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1791*9880d681SAndroid Build Coastguard Worker
1792*9880d681SAndroid Build Coastguard Worker Type *TyContained = Ty->getContainedType(0);
1793*9880d681SAndroid Build Coastguard Worker
1794*9880d681SAndroid Build Coastguard Worker const unsigned indx = unsigned(Src3.IntVal.getZExtValue());
1795*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal = Src1.AggregateVal;
1796*9880d681SAndroid Build Coastguard Worker
1797*9880d681SAndroid Build Coastguard Worker if(Src1.AggregateVal.size() <= indx)
1798*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid index in insertelement instruction");
1799*9880d681SAndroid Build Coastguard Worker switch (TyContained->getTypeID()) {
1800*9880d681SAndroid Build Coastguard Worker default:
1801*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for insertelement instruction");
1802*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1803*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[indx].IntVal = Src2.IntVal;
1804*9880d681SAndroid Build Coastguard Worker break;
1805*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
1806*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[indx].FloatVal = Src2.FloatVal;
1807*9880d681SAndroid Build Coastguard Worker break;
1808*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
1809*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[indx].DoubleVal = Src2.DoubleVal;
1810*9880d681SAndroid Build Coastguard Worker break;
1811*9880d681SAndroid Build Coastguard Worker }
1812*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1813*9880d681SAndroid Build Coastguard Worker }
1814*9880d681SAndroid Build Coastguard Worker
visitShuffleVectorInst(ShuffleVectorInst & I)1815*9880d681SAndroid Build Coastguard Worker void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){
1816*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1817*9880d681SAndroid Build Coastguard Worker
1818*9880d681SAndroid Build Coastguard Worker Type *Ty = I.getType();
1819*9880d681SAndroid Build Coastguard Worker if(!(Ty->isVectorTy()))
1820*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for shufflevector instruction");
1821*9880d681SAndroid Build Coastguard Worker
1822*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
1823*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1824*9880d681SAndroid Build Coastguard Worker GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
1825*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1826*9880d681SAndroid Build Coastguard Worker
1827*9880d681SAndroid Build Coastguard Worker // There is no need to check types of src1 and src2, because the compiled
1828*9880d681SAndroid Build Coastguard Worker // bytecode can't contain different types for src1 and src2 for a
1829*9880d681SAndroid Build Coastguard Worker // shufflevector instruction.
1830*9880d681SAndroid Build Coastguard Worker
1831*9880d681SAndroid Build Coastguard Worker Type *TyContained = Ty->getContainedType(0);
1832*9880d681SAndroid Build Coastguard Worker unsigned src1Size = (unsigned)Src1.AggregateVal.size();
1833*9880d681SAndroid Build Coastguard Worker unsigned src2Size = (unsigned)Src2.AggregateVal.size();
1834*9880d681SAndroid Build Coastguard Worker unsigned src3Size = (unsigned)Src3.AggregateVal.size();
1835*9880d681SAndroid Build Coastguard Worker
1836*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal.resize(src3Size);
1837*9880d681SAndroid Build Coastguard Worker
1838*9880d681SAndroid Build Coastguard Worker switch (TyContained->getTypeID()) {
1839*9880d681SAndroid Build Coastguard Worker default:
1840*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for insertelement instruction");
1841*9880d681SAndroid Build Coastguard Worker break;
1842*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1843*9880d681SAndroid Build Coastguard Worker for( unsigned i=0; i<src3Size; i++) {
1844*9880d681SAndroid Build Coastguard Worker unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
1845*9880d681SAndroid Build Coastguard Worker if(j < src1Size)
1846*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = Src1.AggregateVal[j].IntVal;
1847*9880d681SAndroid Build Coastguard Worker else if(j < src1Size + src2Size)
1848*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].IntVal = Src2.AggregateVal[j-src1Size].IntVal;
1849*9880d681SAndroid Build Coastguard Worker else
1850*9880d681SAndroid Build Coastguard Worker // The selector may not be greater than sum of lengths of first and
1851*9880d681SAndroid Build Coastguard Worker // second operands and llasm should not allow situation like
1852*9880d681SAndroid Build Coastguard Worker // %tmp = shufflevector <2 x i32> <i32 3, i32 4>, <2 x i32> undef,
1853*9880d681SAndroid Build Coastguard Worker // <2 x i32> < i32 0, i32 5 >,
1854*9880d681SAndroid Build Coastguard Worker // where i32 5 is invalid, but let it be additional check here:
1855*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid mask in shufflevector instruction");
1856*9880d681SAndroid Build Coastguard Worker }
1857*9880d681SAndroid Build Coastguard Worker break;
1858*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
1859*9880d681SAndroid Build Coastguard Worker for( unsigned i=0; i<src3Size; i++) {
1860*9880d681SAndroid Build Coastguard Worker unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
1861*9880d681SAndroid Build Coastguard Worker if(j < src1Size)
1862*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal = Src1.AggregateVal[j].FloatVal;
1863*9880d681SAndroid Build Coastguard Worker else if(j < src1Size + src2Size)
1864*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].FloatVal = Src2.AggregateVal[j-src1Size].FloatVal;
1865*9880d681SAndroid Build Coastguard Worker else
1866*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid mask in shufflevector instruction");
1867*9880d681SAndroid Build Coastguard Worker }
1868*9880d681SAndroid Build Coastguard Worker break;
1869*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
1870*9880d681SAndroid Build Coastguard Worker for( unsigned i=0; i<src3Size; i++) {
1871*9880d681SAndroid Build Coastguard Worker unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
1872*9880d681SAndroid Build Coastguard Worker if(j < src1Size)
1873*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal = Src1.AggregateVal[j].DoubleVal;
1874*9880d681SAndroid Build Coastguard Worker else if(j < src1Size + src2Size)
1875*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal[i].DoubleVal =
1876*9880d681SAndroid Build Coastguard Worker Src2.AggregateVal[j-src1Size].DoubleVal;
1877*9880d681SAndroid Build Coastguard Worker else
1878*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid mask in shufflevector instruction");
1879*9880d681SAndroid Build Coastguard Worker }
1880*9880d681SAndroid Build Coastguard Worker break;
1881*9880d681SAndroid Build Coastguard Worker }
1882*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1883*9880d681SAndroid Build Coastguard Worker }
1884*9880d681SAndroid Build Coastguard Worker
visitExtractValueInst(ExtractValueInst & I)1885*9880d681SAndroid Build Coastguard Worker void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
1886*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1887*9880d681SAndroid Build Coastguard Worker Value *Agg = I.getAggregateOperand();
1888*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
1889*9880d681SAndroid Build Coastguard Worker GenericValue Src = getOperandValue(Agg, SF);
1890*9880d681SAndroid Build Coastguard Worker
1891*9880d681SAndroid Build Coastguard Worker ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
1892*9880d681SAndroid Build Coastguard Worker unsigned Num = I.getNumIndices();
1893*9880d681SAndroid Build Coastguard Worker GenericValue *pSrc = &Src;
1894*9880d681SAndroid Build Coastguard Worker
1895*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0 ; i < Num; ++i) {
1896*9880d681SAndroid Build Coastguard Worker pSrc = &pSrc->AggregateVal[*IdxBegin];
1897*9880d681SAndroid Build Coastguard Worker ++IdxBegin;
1898*9880d681SAndroid Build Coastguard Worker }
1899*9880d681SAndroid Build Coastguard Worker
1900*9880d681SAndroid Build Coastguard Worker Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
1901*9880d681SAndroid Build Coastguard Worker switch (IndexedType->getTypeID()) {
1902*9880d681SAndroid Build Coastguard Worker default:
1903*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for extractelement instruction");
1904*9880d681SAndroid Build Coastguard Worker break;
1905*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1906*9880d681SAndroid Build Coastguard Worker Dest.IntVal = pSrc->IntVal;
1907*9880d681SAndroid Build Coastguard Worker break;
1908*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
1909*9880d681SAndroid Build Coastguard Worker Dest.FloatVal = pSrc->FloatVal;
1910*9880d681SAndroid Build Coastguard Worker break;
1911*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
1912*9880d681SAndroid Build Coastguard Worker Dest.DoubleVal = pSrc->DoubleVal;
1913*9880d681SAndroid Build Coastguard Worker break;
1914*9880d681SAndroid Build Coastguard Worker case Type::ArrayTyID:
1915*9880d681SAndroid Build Coastguard Worker case Type::StructTyID:
1916*9880d681SAndroid Build Coastguard Worker case Type::VectorTyID:
1917*9880d681SAndroid Build Coastguard Worker Dest.AggregateVal = pSrc->AggregateVal;
1918*9880d681SAndroid Build Coastguard Worker break;
1919*9880d681SAndroid Build Coastguard Worker case Type::PointerTyID:
1920*9880d681SAndroid Build Coastguard Worker Dest.PointerVal = pSrc->PointerVal;
1921*9880d681SAndroid Build Coastguard Worker break;
1922*9880d681SAndroid Build Coastguard Worker }
1923*9880d681SAndroid Build Coastguard Worker
1924*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1925*9880d681SAndroid Build Coastguard Worker }
1926*9880d681SAndroid Build Coastguard Worker
visitInsertValueInst(InsertValueInst & I)1927*9880d681SAndroid Build Coastguard Worker void Interpreter::visitInsertValueInst(InsertValueInst &I) {
1928*9880d681SAndroid Build Coastguard Worker
1929*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back();
1930*9880d681SAndroid Build Coastguard Worker Value *Agg = I.getAggregateOperand();
1931*9880d681SAndroid Build Coastguard Worker
1932*9880d681SAndroid Build Coastguard Worker GenericValue Src1 = getOperandValue(Agg, SF);
1933*9880d681SAndroid Build Coastguard Worker GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
1934*9880d681SAndroid Build Coastguard Worker GenericValue Dest = Src1; // Dest is a slightly changed Src1
1935*9880d681SAndroid Build Coastguard Worker
1936*9880d681SAndroid Build Coastguard Worker ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
1937*9880d681SAndroid Build Coastguard Worker unsigned Num = I.getNumIndices();
1938*9880d681SAndroid Build Coastguard Worker
1939*9880d681SAndroid Build Coastguard Worker GenericValue *pDest = &Dest;
1940*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0 ; i < Num; ++i) {
1941*9880d681SAndroid Build Coastguard Worker pDest = &pDest->AggregateVal[*IdxBegin];
1942*9880d681SAndroid Build Coastguard Worker ++IdxBegin;
1943*9880d681SAndroid Build Coastguard Worker }
1944*9880d681SAndroid Build Coastguard Worker // pDest points to the target value in the Dest now
1945*9880d681SAndroid Build Coastguard Worker
1946*9880d681SAndroid Build Coastguard Worker Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
1947*9880d681SAndroid Build Coastguard Worker
1948*9880d681SAndroid Build Coastguard Worker switch (IndexedType->getTypeID()) {
1949*9880d681SAndroid Build Coastguard Worker default:
1950*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled dest type for insertelement instruction");
1951*9880d681SAndroid Build Coastguard Worker break;
1952*9880d681SAndroid Build Coastguard Worker case Type::IntegerTyID:
1953*9880d681SAndroid Build Coastguard Worker pDest->IntVal = Src2.IntVal;
1954*9880d681SAndroid Build Coastguard Worker break;
1955*9880d681SAndroid Build Coastguard Worker case Type::FloatTyID:
1956*9880d681SAndroid Build Coastguard Worker pDest->FloatVal = Src2.FloatVal;
1957*9880d681SAndroid Build Coastguard Worker break;
1958*9880d681SAndroid Build Coastguard Worker case Type::DoubleTyID:
1959*9880d681SAndroid Build Coastguard Worker pDest->DoubleVal = Src2.DoubleVal;
1960*9880d681SAndroid Build Coastguard Worker break;
1961*9880d681SAndroid Build Coastguard Worker case Type::ArrayTyID:
1962*9880d681SAndroid Build Coastguard Worker case Type::StructTyID:
1963*9880d681SAndroid Build Coastguard Worker case Type::VectorTyID:
1964*9880d681SAndroid Build Coastguard Worker pDest->AggregateVal = Src2.AggregateVal;
1965*9880d681SAndroid Build Coastguard Worker break;
1966*9880d681SAndroid Build Coastguard Worker case Type::PointerTyID:
1967*9880d681SAndroid Build Coastguard Worker pDest->PointerVal = Src2.PointerVal;
1968*9880d681SAndroid Build Coastguard Worker break;
1969*9880d681SAndroid Build Coastguard Worker }
1970*9880d681SAndroid Build Coastguard Worker
1971*9880d681SAndroid Build Coastguard Worker SetValue(&I, Dest, SF);
1972*9880d681SAndroid Build Coastguard Worker }
1973*9880d681SAndroid Build Coastguard Worker
getConstantExprValue(ConstantExpr * CE,ExecutionContext & SF)1974*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
1975*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF) {
1976*9880d681SAndroid Build Coastguard Worker switch (CE->getOpcode()) {
1977*9880d681SAndroid Build Coastguard Worker case Instruction::Trunc:
1978*9880d681SAndroid Build Coastguard Worker return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
1979*9880d681SAndroid Build Coastguard Worker case Instruction::ZExt:
1980*9880d681SAndroid Build Coastguard Worker return executeZExtInst(CE->getOperand(0), CE->getType(), SF);
1981*9880d681SAndroid Build Coastguard Worker case Instruction::SExt:
1982*9880d681SAndroid Build Coastguard Worker return executeSExtInst(CE->getOperand(0), CE->getType(), SF);
1983*9880d681SAndroid Build Coastguard Worker case Instruction::FPTrunc:
1984*9880d681SAndroid Build Coastguard Worker return executeFPTruncInst(CE->getOperand(0), CE->getType(), SF);
1985*9880d681SAndroid Build Coastguard Worker case Instruction::FPExt:
1986*9880d681SAndroid Build Coastguard Worker return executeFPExtInst(CE->getOperand(0), CE->getType(), SF);
1987*9880d681SAndroid Build Coastguard Worker case Instruction::UIToFP:
1988*9880d681SAndroid Build Coastguard Worker return executeUIToFPInst(CE->getOperand(0), CE->getType(), SF);
1989*9880d681SAndroid Build Coastguard Worker case Instruction::SIToFP:
1990*9880d681SAndroid Build Coastguard Worker return executeSIToFPInst(CE->getOperand(0), CE->getType(), SF);
1991*9880d681SAndroid Build Coastguard Worker case Instruction::FPToUI:
1992*9880d681SAndroid Build Coastguard Worker return executeFPToUIInst(CE->getOperand(0), CE->getType(), SF);
1993*9880d681SAndroid Build Coastguard Worker case Instruction::FPToSI:
1994*9880d681SAndroid Build Coastguard Worker return executeFPToSIInst(CE->getOperand(0), CE->getType(), SF);
1995*9880d681SAndroid Build Coastguard Worker case Instruction::PtrToInt:
1996*9880d681SAndroid Build Coastguard Worker return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
1997*9880d681SAndroid Build Coastguard Worker case Instruction::IntToPtr:
1998*9880d681SAndroid Build Coastguard Worker return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
1999*9880d681SAndroid Build Coastguard Worker case Instruction::BitCast:
2000*9880d681SAndroid Build Coastguard Worker return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
2001*9880d681SAndroid Build Coastguard Worker case Instruction::GetElementPtr:
2002*9880d681SAndroid Build Coastguard Worker return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
2003*9880d681SAndroid Build Coastguard Worker gep_type_end(CE), SF);
2004*9880d681SAndroid Build Coastguard Worker case Instruction::FCmp:
2005*9880d681SAndroid Build Coastguard Worker case Instruction::ICmp:
2006*9880d681SAndroid Build Coastguard Worker return executeCmpInst(CE->getPredicate(),
2007*9880d681SAndroid Build Coastguard Worker getOperandValue(CE->getOperand(0), SF),
2008*9880d681SAndroid Build Coastguard Worker getOperandValue(CE->getOperand(1), SF),
2009*9880d681SAndroid Build Coastguard Worker CE->getOperand(0)->getType());
2010*9880d681SAndroid Build Coastguard Worker case Instruction::Select:
2011*9880d681SAndroid Build Coastguard Worker return executeSelectInst(getOperandValue(CE->getOperand(0), SF),
2012*9880d681SAndroid Build Coastguard Worker getOperandValue(CE->getOperand(1), SF),
2013*9880d681SAndroid Build Coastguard Worker getOperandValue(CE->getOperand(2), SF),
2014*9880d681SAndroid Build Coastguard Worker CE->getOperand(0)->getType());
2015*9880d681SAndroid Build Coastguard Worker default :
2016*9880d681SAndroid Build Coastguard Worker break;
2017*9880d681SAndroid Build Coastguard Worker }
2018*9880d681SAndroid Build Coastguard Worker
2019*9880d681SAndroid Build Coastguard Worker // The cases below here require a GenericValue parameter for the result
2020*9880d681SAndroid Build Coastguard Worker // so we initialize one, compute it and then return it.
2021*9880d681SAndroid Build Coastguard Worker GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
2022*9880d681SAndroid Build Coastguard Worker GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
2023*9880d681SAndroid Build Coastguard Worker GenericValue Dest;
2024*9880d681SAndroid Build Coastguard Worker Type * Ty = CE->getOperand(0)->getType();
2025*9880d681SAndroid Build Coastguard Worker switch (CE->getOpcode()) {
2026*9880d681SAndroid Build Coastguard Worker case Instruction::Add: Dest.IntVal = Op0.IntVal + Op1.IntVal; break;
2027*9880d681SAndroid Build Coastguard Worker case Instruction::Sub: Dest.IntVal = Op0.IntVal - Op1.IntVal; break;
2028*9880d681SAndroid Build Coastguard Worker case Instruction::Mul: Dest.IntVal = Op0.IntVal * Op1.IntVal; break;
2029*9880d681SAndroid Build Coastguard Worker case Instruction::FAdd: executeFAddInst(Dest, Op0, Op1, Ty); break;
2030*9880d681SAndroid Build Coastguard Worker case Instruction::FSub: executeFSubInst(Dest, Op0, Op1, Ty); break;
2031*9880d681SAndroid Build Coastguard Worker case Instruction::FMul: executeFMulInst(Dest, Op0, Op1, Ty); break;
2032*9880d681SAndroid Build Coastguard Worker case Instruction::FDiv: executeFDivInst(Dest, Op0, Op1, Ty); break;
2033*9880d681SAndroid Build Coastguard Worker case Instruction::FRem: executeFRemInst(Dest, Op0, Op1, Ty); break;
2034*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv: Dest.IntVal = Op0.IntVal.sdiv(Op1.IntVal); break;
2035*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv: Dest.IntVal = Op0.IntVal.udiv(Op1.IntVal); break;
2036*9880d681SAndroid Build Coastguard Worker case Instruction::URem: Dest.IntVal = Op0.IntVal.urem(Op1.IntVal); break;
2037*9880d681SAndroid Build Coastguard Worker case Instruction::SRem: Dest.IntVal = Op0.IntVal.srem(Op1.IntVal); break;
2038*9880d681SAndroid Build Coastguard Worker case Instruction::And: Dest.IntVal = Op0.IntVal & Op1.IntVal; break;
2039*9880d681SAndroid Build Coastguard Worker case Instruction::Or: Dest.IntVal = Op0.IntVal | Op1.IntVal; break;
2040*9880d681SAndroid Build Coastguard Worker case Instruction::Xor: Dest.IntVal = Op0.IntVal ^ Op1.IntVal; break;
2041*9880d681SAndroid Build Coastguard Worker case Instruction::Shl:
2042*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Op0.IntVal.shl(Op1.IntVal.getZExtValue());
2043*9880d681SAndroid Build Coastguard Worker break;
2044*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
2045*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Op0.IntVal.lshr(Op1.IntVal.getZExtValue());
2046*9880d681SAndroid Build Coastguard Worker break;
2047*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
2048*9880d681SAndroid Build Coastguard Worker Dest.IntVal = Op0.IntVal.ashr(Op1.IntVal.getZExtValue());
2049*9880d681SAndroid Build Coastguard Worker break;
2050*9880d681SAndroid Build Coastguard Worker default:
2051*9880d681SAndroid Build Coastguard Worker dbgs() << "Unhandled ConstantExpr: " << *CE << "\n";
2052*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled ConstantExpr");
2053*9880d681SAndroid Build Coastguard Worker }
2054*9880d681SAndroid Build Coastguard Worker return Dest;
2055*9880d681SAndroid Build Coastguard Worker }
2056*9880d681SAndroid Build Coastguard Worker
getOperandValue(Value * V,ExecutionContext & SF)2057*9880d681SAndroid Build Coastguard Worker GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
2058*9880d681SAndroid Build Coastguard Worker if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
2059*9880d681SAndroid Build Coastguard Worker return getConstantExprValue(CE, SF);
2060*9880d681SAndroid Build Coastguard Worker } else if (Constant *CPV = dyn_cast<Constant>(V)) {
2061*9880d681SAndroid Build Coastguard Worker return getConstantValue(CPV);
2062*9880d681SAndroid Build Coastguard Worker } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
2063*9880d681SAndroid Build Coastguard Worker return PTOGV(getPointerToGlobal(GV));
2064*9880d681SAndroid Build Coastguard Worker } else {
2065*9880d681SAndroid Build Coastguard Worker return SF.Values[V];
2066*9880d681SAndroid Build Coastguard Worker }
2067*9880d681SAndroid Build Coastguard Worker }
2068*9880d681SAndroid Build Coastguard Worker
2069*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2070*9880d681SAndroid Build Coastguard Worker // Dispatch and Execution Code
2071*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2072*9880d681SAndroid Build Coastguard Worker
2073*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2074*9880d681SAndroid Build Coastguard Worker // callFunction - Execute the specified function...
2075*9880d681SAndroid Build Coastguard Worker //
callFunction(Function * F,ArrayRef<GenericValue> ArgVals)2076*9880d681SAndroid Build Coastguard Worker void Interpreter::callFunction(Function *F, ArrayRef<GenericValue> ArgVals) {
2077*9880d681SAndroid Build Coastguard Worker assert((ECStack.empty() || !ECStack.back().Caller.getInstruction() ||
2078*9880d681SAndroid Build Coastguard Worker ECStack.back().Caller.arg_size() == ArgVals.size()) &&
2079*9880d681SAndroid Build Coastguard Worker "Incorrect number of arguments passed into function call!");
2080*9880d681SAndroid Build Coastguard Worker // Make a new stack frame... and fill it in.
2081*9880d681SAndroid Build Coastguard Worker ECStack.emplace_back();
2082*9880d681SAndroid Build Coastguard Worker ExecutionContext &StackFrame = ECStack.back();
2083*9880d681SAndroid Build Coastguard Worker StackFrame.CurFunction = F;
2084*9880d681SAndroid Build Coastguard Worker
2085*9880d681SAndroid Build Coastguard Worker // Special handling for external functions.
2086*9880d681SAndroid Build Coastguard Worker if (F->isDeclaration()) {
2087*9880d681SAndroid Build Coastguard Worker GenericValue Result = callExternalFunction (F, ArgVals);
2088*9880d681SAndroid Build Coastguard Worker // Simulate a 'ret' instruction of the appropriate type.
2089*9880d681SAndroid Build Coastguard Worker popStackAndReturnValueToCaller (F->getReturnType (), Result);
2090*9880d681SAndroid Build Coastguard Worker return;
2091*9880d681SAndroid Build Coastguard Worker }
2092*9880d681SAndroid Build Coastguard Worker
2093*9880d681SAndroid Build Coastguard Worker // Get pointers to first LLVM BB & Instruction in function.
2094*9880d681SAndroid Build Coastguard Worker StackFrame.CurBB = &F->front();
2095*9880d681SAndroid Build Coastguard Worker StackFrame.CurInst = StackFrame.CurBB->begin();
2096*9880d681SAndroid Build Coastguard Worker
2097*9880d681SAndroid Build Coastguard Worker // Run through the function arguments and initialize their values...
2098*9880d681SAndroid Build Coastguard Worker assert((ArgVals.size() == F->arg_size() ||
2099*9880d681SAndroid Build Coastguard Worker (ArgVals.size() > F->arg_size() && F->getFunctionType()->isVarArg()))&&
2100*9880d681SAndroid Build Coastguard Worker "Invalid number of values passed to function invocation!");
2101*9880d681SAndroid Build Coastguard Worker
2102*9880d681SAndroid Build Coastguard Worker // Handle non-varargs arguments...
2103*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
2104*9880d681SAndroid Build Coastguard Worker for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
2105*9880d681SAndroid Build Coastguard Worker AI != E; ++AI, ++i)
2106*9880d681SAndroid Build Coastguard Worker SetValue(&*AI, ArgVals[i], StackFrame);
2107*9880d681SAndroid Build Coastguard Worker
2108*9880d681SAndroid Build Coastguard Worker // Handle varargs arguments...
2109*9880d681SAndroid Build Coastguard Worker StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end());
2110*9880d681SAndroid Build Coastguard Worker }
2111*9880d681SAndroid Build Coastguard Worker
2112*9880d681SAndroid Build Coastguard Worker
run()2113*9880d681SAndroid Build Coastguard Worker void Interpreter::run() {
2114*9880d681SAndroid Build Coastguard Worker while (!ECStack.empty()) {
2115*9880d681SAndroid Build Coastguard Worker // Interpret a single instruction & increment the "PC".
2116*9880d681SAndroid Build Coastguard Worker ExecutionContext &SF = ECStack.back(); // Current stack frame
2117*9880d681SAndroid Build Coastguard Worker Instruction &I = *SF.CurInst++; // Increment before execute
2118*9880d681SAndroid Build Coastguard Worker
2119*9880d681SAndroid Build Coastguard Worker // Track the number of dynamic instructions executed.
2120*9880d681SAndroid Build Coastguard Worker ++NumDynamicInsts;
2121*9880d681SAndroid Build Coastguard Worker
2122*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "About to interpret: " << I);
2123*9880d681SAndroid Build Coastguard Worker visit(I); // Dispatch to one of the visit* methods...
2124*9880d681SAndroid Build Coastguard Worker }
2125*9880d681SAndroid Build Coastguard Worker }
2126