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