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