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