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