1
2 /*---------------------------------------------------------------*/
3 /*--- begin ir_defs.c ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2004-2012 OpenWorks LLP
11 info@open-works.net
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
34 */
35
36 #include "libvex_basictypes.h"
37 #include "libvex_ir.h"
38 #include "libvex.h"
39
40 #include "main_util.h"
41
42
43 /*---------------------------------------------------------------*/
44 /*--- Printing the IR ---*/
45 /*---------------------------------------------------------------*/
46
ppIRType(IRType ty)47 void ppIRType ( IRType ty )
48 {
49 switch (ty) {
50 case Ity_INVALID: vex_printf("Ity_INVALID"); break;
51 case Ity_I1: vex_printf( "I1"); break;
52 case Ity_I8: vex_printf( "I8"); break;
53 case Ity_I16: vex_printf( "I16"); break;
54 case Ity_I32: vex_printf( "I32"); break;
55 case Ity_I64: vex_printf( "I64"); break;
56 case Ity_I128: vex_printf( "I128"); break;
57 case Ity_F32: vex_printf( "F32"); break;
58 case Ity_F64: vex_printf( "F64"); break;
59 case Ity_F128: vex_printf( "F128"); break;
60 case Ity_D32: vex_printf( "D32"); break;
61 case Ity_D64: vex_printf( "D64"); break;
62 case Ity_D128: vex_printf( "D128"); break;
63 case Ity_V128: vex_printf( "V128"); break;
64 case Ity_V256: vex_printf( "V256"); break;
65 default: vex_printf("ty = 0x%x\n", (Int)ty);
66 vpanic("ppIRType");
67 }
68 }
69
ppIRConst(IRConst * con)70 void ppIRConst ( IRConst* con )
71 {
72 union { ULong i64; Double f64; UInt i32; Float f32; } u;
73 vassert(sizeof(ULong) == sizeof(Double));
74 switch (con->tag) {
75 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break;
76 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break;
77 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break;
78 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break;
79 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break;
80 case Ico_F32: u.f32 = con->Ico.F32;
81 vex_printf( "F32{0x%x}", u.i32);
82 break;
83 case Ico_F32i: vex_printf( "F32i{0x%x}", con->Ico.F32i); break;
84 case Ico_F64: u.f64 = con->Ico.F64;
85 vex_printf( "F64{0x%llx}", u.i64);
86 break;
87 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
88 case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break;
89 case Ico_V256: vex_printf( "V256{0x%08x}", con->Ico.V256); break;
90 default: vpanic("ppIRConst");
91 }
92 }
93
ppIRCallee(IRCallee * ce)94 void ppIRCallee ( IRCallee* ce )
95 {
96 vex_printf("%s", ce->name);
97 if (ce->regparms > 0)
98 vex_printf("[rp=%d]", ce->regparms);
99 if (ce->mcx_mask > 0)
100 vex_printf("[mcx=0x%x]", ce->mcx_mask);
101 vex_printf("{%p}", (void*)ce->addr);
102 }
103
ppIRRegArray(IRRegArray * arr)104 void ppIRRegArray ( IRRegArray* arr )
105 {
106 vex_printf("(%d:%dx", arr->base, arr->nElems);
107 ppIRType(arr->elemTy);
108 vex_printf(")");
109 }
110
ppIRTemp(IRTemp tmp)111 void ppIRTemp ( IRTemp tmp )
112 {
113 if (tmp == IRTemp_INVALID)
114 vex_printf("IRTemp_INVALID");
115 else
116 vex_printf( "t%d", (Int)tmp);
117 }
118
ppIROp(IROp op)119 void ppIROp ( IROp op )
120 {
121 HChar* str = NULL;
122 IROp base;
123 switch (op) {
124 case Iop_Add8 ... Iop_Add64:
125 str = "Add"; base = Iop_Add8; break;
126 case Iop_Sub8 ... Iop_Sub64:
127 str = "Sub"; base = Iop_Sub8; break;
128 case Iop_Mul8 ... Iop_Mul64:
129 str = "Mul"; base = Iop_Mul8; break;
130 case Iop_Or8 ... Iop_Or64:
131 str = "Or"; base = Iop_Or8; break;
132 case Iop_And8 ... Iop_And64:
133 str = "And"; base = Iop_And8; break;
134 case Iop_Xor8 ... Iop_Xor64:
135 str = "Xor"; base = Iop_Xor8; break;
136 case Iop_Shl8 ... Iop_Shl64:
137 str = "Shl"; base = Iop_Shl8; break;
138 case Iop_Shr8 ... Iop_Shr64:
139 str = "Shr"; base = Iop_Shr8; break;
140 case Iop_Sar8 ... Iop_Sar64:
141 str = "Sar"; base = Iop_Sar8; break;
142 case Iop_CmpEQ8 ... Iop_CmpEQ64:
143 str = "CmpEQ"; base = Iop_CmpEQ8; break;
144 case Iop_CmpNE8 ... Iop_CmpNE64:
145 str = "CmpNE"; base = Iop_CmpNE8; break;
146 case Iop_CasCmpEQ8 ... Iop_CasCmpEQ64:
147 str = "CasCmpEQ"; base = Iop_CasCmpEQ8; break;
148 case Iop_CasCmpNE8 ... Iop_CasCmpNE64:
149 str = "CasCmpNE"; base = Iop_CasCmpNE8; break;
150 case Iop_Not8 ... Iop_Not64:
151 str = "Not"; base = Iop_Not8; break;
152 /* other cases must explicitly "return;" */
153 case Iop_8Uto16: vex_printf("8Uto16"); return;
154 case Iop_8Uto32: vex_printf("8Uto32"); return;
155 case Iop_16Uto32: vex_printf("16Uto32"); return;
156 case Iop_8Sto16: vex_printf("8Sto16"); return;
157 case Iop_8Sto32: vex_printf("8Sto32"); return;
158 case Iop_16Sto32: vex_printf("16Sto32"); return;
159 case Iop_32Sto64: vex_printf("32Sto64"); return;
160 case Iop_32Uto64: vex_printf("32Uto64"); return;
161 case Iop_32to8: vex_printf("32to8"); return;
162 case Iop_16Uto64: vex_printf("16Uto64"); return;
163 case Iop_16Sto64: vex_printf("16Sto64"); return;
164 case Iop_8Uto64: vex_printf("8Uto64"); return;
165 case Iop_8Sto64: vex_printf("8Sto64"); return;
166 case Iop_64to16: vex_printf("64to16"); return;
167 case Iop_64to8: vex_printf("64to8"); return;
168
169 case Iop_Not1: vex_printf("Not1"); return;
170 case Iop_32to1: vex_printf("32to1"); return;
171 case Iop_64to1: vex_printf("64to1"); return;
172 case Iop_1Uto8: vex_printf("1Uto8"); return;
173 case Iop_1Uto32: vex_printf("1Uto32"); return;
174 case Iop_1Uto64: vex_printf("1Uto64"); return;
175 case Iop_1Sto8: vex_printf("1Sto8"); return;
176 case Iop_1Sto16: vex_printf("1Sto16"); return;
177 case Iop_1Sto32: vex_printf("1Sto32"); return;
178 case Iop_1Sto64: vex_printf("1Sto64"); return;
179
180 case Iop_MullS8: vex_printf("MullS8"); return;
181 case Iop_MullS16: vex_printf("MullS16"); return;
182 case Iop_MullS32: vex_printf("MullS32"); return;
183 case Iop_MullS64: vex_printf("MullS64"); return;
184 case Iop_MullU8: vex_printf("MullU8"); return;
185 case Iop_MullU16: vex_printf("MullU16"); return;
186 case Iop_MullU32: vex_printf("MullU32"); return;
187 case Iop_MullU64: vex_printf("MullU64"); return;
188
189 case Iop_Clz64: vex_printf("Clz64"); return;
190 case Iop_Clz32: vex_printf("Clz32"); return;
191 case Iop_Ctz64: vex_printf("Ctz64"); return;
192 case Iop_Ctz32: vex_printf("Ctz32"); return;
193
194 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
195 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
196 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
197 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
198
199 case Iop_CmpLT64S: vex_printf("CmpLT64S"); return;
200 case Iop_CmpLE64S: vex_printf("CmpLE64S"); return;
201 case Iop_CmpLT64U: vex_printf("CmpLT64U"); return;
202 case Iop_CmpLE64U: vex_printf("CmpLE64U"); return;
203
204 case Iop_CmpNEZ8: vex_printf("CmpNEZ8"); return;
205 case Iop_CmpNEZ16: vex_printf("CmpNEZ16"); return;
206 case Iop_CmpNEZ32: vex_printf("CmpNEZ32"); return;
207 case Iop_CmpNEZ64: vex_printf("CmpNEZ64"); return;
208
209 case Iop_CmpwNEZ32: vex_printf("CmpwNEZ32"); return;
210 case Iop_CmpwNEZ64: vex_printf("CmpwNEZ64"); return;
211
212 case Iop_Left8: vex_printf("Left8"); return;
213 case Iop_Left16: vex_printf("Left16"); return;
214 case Iop_Left32: vex_printf("Left32"); return;
215 case Iop_Left64: vex_printf("Left64"); return;
216 case Iop_Max32U: vex_printf("Max32U"); return;
217
218 case Iop_CmpORD32U: vex_printf("CmpORD32U"); return;
219 case Iop_CmpORD32S: vex_printf("CmpORD32S"); return;
220
221 case Iop_CmpORD64U: vex_printf("CmpORD64U"); return;
222 case Iop_CmpORD64S: vex_printf("CmpORD64S"); return;
223
224 case Iop_DivU32: vex_printf("DivU32"); return;
225 case Iop_DivS32: vex_printf("DivS32"); return;
226 case Iop_DivU64: vex_printf("DivU64"); return;
227 case Iop_DivS64: vex_printf("DivS64"); return;
228 case Iop_DivU64E: vex_printf("DivU64E"); return;
229 case Iop_DivS64E: vex_printf("DivS64E"); return;
230 case Iop_DivU32E: vex_printf("DivU32E"); return;
231 case Iop_DivS32E: vex_printf("DivS32E"); return;
232
233 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
234 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
235
236 case Iop_DivModU128to64: vex_printf("DivModU128to64"); return;
237 case Iop_DivModS128to64: vex_printf("DivModS128to64"); return;
238
239 case Iop_DivModS64to64: vex_printf("DivModS64to64"); return;
240
241 case Iop_16HIto8: vex_printf("16HIto8"); return;
242 case Iop_16to8: vex_printf("16to8"); return;
243 case Iop_8HLto16: vex_printf("8HLto16"); return;
244
245 case Iop_32HIto16: vex_printf("32HIto16"); return;
246 case Iop_32to16: vex_printf("32to16"); return;
247 case Iop_16HLto32: vex_printf("16HLto32"); return;
248
249 case Iop_64HIto32: vex_printf("64HIto32"); return;
250 case Iop_64to32: vex_printf("64to32"); return;
251 case Iop_32HLto64: vex_printf("32HLto64"); return;
252
253 case Iop_128HIto64: vex_printf("128HIto64"); return;
254 case Iop_128to64: vex_printf("128to64"); return;
255 case Iop_64HLto128: vex_printf("64HLto128"); return;
256
257 case Iop_CmpF32: vex_printf("CmpF32"); return;
258 case Iop_F32toI16S: vex_printf("F32toI16S"); return;
259 case Iop_F32toI32S: vex_printf("F32toI32S"); return;
260 case Iop_F32toI64S: vex_printf("F32toI64S"); return;
261 case Iop_I16StoF32: vex_printf("I16StoF32"); return;
262 case Iop_I32StoF32: vex_printf("I32StoF32"); return;
263 case Iop_I64StoF32: vex_printf("I64StoF32"); return;
264
265 case Iop_AddF64: vex_printf("AddF64"); return;
266 case Iop_SubF64: vex_printf("SubF64"); return;
267 case Iop_MulF64: vex_printf("MulF64"); return;
268 case Iop_DivF64: vex_printf("DivF64"); return;
269 case Iop_AddF64r32: vex_printf("AddF64r32"); return;
270 case Iop_SubF64r32: vex_printf("SubF64r32"); return;
271 case Iop_MulF64r32: vex_printf("MulF64r32"); return;
272 case Iop_DivF64r32: vex_printf("DivF64r32"); return;
273 case Iop_AddF32: vex_printf("AddF32"); return;
274 case Iop_SubF32: vex_printf("SubF32"); return;
275 case Iop_MulF32: vex_printf("MulF32"); return;
276 case Iop_DivF32: vex_printf("DivF32"); return;
277
278 /* 128 bit floating point */
279 case Iop_AddF128: vex_printf("AddF128"); return;
280 case Iop_SubF128: vex_printf("SubF128"); return;
281 case Iop_MulF128: vex_printf("MulF128"); return;
282 case Iop_DivF128: vex_printf("DivF128"); return;
283 case Iop_AbsF128: vex_printf("AbsF128"); return;
284 case Iop_NegF128: vex_printf("NegF128"); return;
285 case Iop_SqrtF128: vex_printf("SqrtF128"); return;
286 case Iop_CmpF128: vex_printf("CmpF128"); return;
287
288 case Iop_F64HLtoF128: vex_printf("F64HLtoF128"); return;
289 case Iop_F128HItoF64: vex_printf("F128HItoF64"); return;
290 case Iop_F128LOtoF64: vex_printf("F128LOtoF64"); return;
291 case Iop_I32StoF128: vex_printf("I32StoF128"); return;
292 case Iop_I64StoF128: vex_printf("I64StoF128"); return;
293 case Iop_F128toI32S: vex_printf("F128toI32S"); return;
294 case Iop_F128toI64S: vex_printf("F128toI64S"); return;
295 case Iop_F32toF128: vex_printf("F32toF128"); return;
296 case Iop_F64toF128: vex_printf("F64toF128"); return;
297 case Iop_F128toF64: vex_printf("F128toF64"); return;
298 case Iop_F128toF32: vex_printf("F128toF32"); return;
299
300 /* s390 specific */
301 case Iop_MAddF32: vex_printf("s390_MAddF32"); return;
302 case Iop_MSubF32: vex_printf("s390_MSubF32"); return;
303
304 case Iop_ScaleF64: vex_printf("ScaleF64"); return;
305 case Iop_AtanF64: vex_printf("AtanF64"); return;
306 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return;
307 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return;
308 case Iop_PRemF64: vex_printf("PRemF64"); return;
309 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return;
310 case Iop_PRem1F64: vex_printf("PRem1F64"); return;
311 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
312 case Iop_NegF64: vex_printf("NegF64"); return;
313 case Iop_AbsF64: vex_printf("AbsF64"); return;
314 case Iop_NegF32: vex_printf("NegF32"); return;
315 case Iop_AbsF32: vex_printf("AbsF32"); return;
316 case Iop_SqrtF64: vex_printf("SqrtF64"); return;
317 case Iop_SqrtF32: vex_printf("SqrtF32"); return;
318 case Iop_SinF64: vex_printf("SinF64"); return;
319 case Iop_CosF64: vex_printf("CosF64"); return;
320 case Iop_TanF64: vex_printf("TanF64"); return;
321 case Iop_2xm1F64: vex_printf("2xm1F64"); return;
322
323 case Iop_MAddF64: vex_printf("MAddF64"); return;
324 case Iop_MSubF64: vex_printf("MSubF64"); return;
325 case Iop_MAddF64r32: vex_printf("MAddF64r32"); return;
326 case Iop_MSubF64r32: vex_printf("MSubF64r32"); return;
327
328 case Iop_Est5FRSqrt: vex_printf("Est5FRSqrt"); return;
329 case Iop_RoundF64toF64_NEAREST: vex_printf("RoundF64toF64_NEAREST"); return;
330 case Iop_RoundF64toF64_NegINF: vex_printf("RoundF64toF64_NegINF"); return;
331 case Iop_RoundF64toF64_PosINF: vex_printf("RoundF64toF64_PosINF"); return;
332 case Iop_RoundF64toF64_ZERO: vex_printf("RoundF64toF64_ZERO"); return;
333
334 case Iop_TruncF64asF32: vex_printf("TruncF64asF32"); return;
335 case Iop_CalcFPRF: vex_printf("CalcFPRF"); return;
336
337 case Iop_QAdd32S: vex_printf("QAdd32S"); return;
338 case Iop_QSub32S: vex_printf("QSub32S"); return;
339 case Iop_Add16x2: vex_printf("Add16x2"); return;
340 case Iop_Sub16x2: vex_printf("Sub16x2"); return;
341 case Iop_QAdd16Sx2: vex_printf("QAdd16Sx2"); return;
342 case Iop_QAdd16Ux2: vex_printf("QAdd16Ux2"); return;
343 case Iop_QSub16Sx2: vex_printf("QSub16Sx2"); return;
344 case Iop_QSub16Ux2: vex_printf("QSub16Ux2"); return;
345 case Iop_HAdd16Ux2: vex_printf("HAdd16Ux2"); return;
346 case Iop_HAdd16Sx2: vex_printf("HAdd16Sx2"); return;
347 case Iop_HSub16Ux2: vex_printf("HSub16Ux2"); return;
348 case Iop_HSub16Sx2: vex_printf("HSub16Sx2"); return;
349
350 case Iop_Add8x4: vex_printf("Add8x4"); return;
351 case Iop_Sub8x4: vex_printf("Sub8x4"); return;
352 case Iop_QAdd8Sx4: vex_printf("QAdd8Sx4"); return;
353 case Iop_QAdd8Ux4: vex_printf("QAdd8Ux4"); return;
354 case Iop_QSub8Sx4: vex_printf("QSub8Sx4"); return;
355 case Iop_QSub8Ux4: vex_printf("QSub8Ux4"); return;
356 case Iop_HAdd8Ux4: vex_printf("HAdd8Ux4"); return;
357 case Iop_HAdd8Sx4: vex_printf("HAdd8Sx4"); return;
358 case Iop_HSub8Ux4: vex_printf("HSub8Ux4"); return;
359 case Iop_HSub8Sx4: vex_printf("HSub8Sx4"); return;
360 case Iop_Sad8Ux4: vex_printf("Sad8Ux4"); return;
361
362 case Iop_CmpNEZ16x2: vex_printf("CmpNEZ16x2"); return;
363 case Iop_CmpNEZ8x4: vex_printf("CmpNEZ8x4"); return;
364
365 case Iop_CmpF64: vex_printf("CmpF64"); return;
366
367 case Iop_F64toI16S: vex_printf("F64toI16S"); return;
368 case Iop_F64toI32S: vex_printf("F64toI32S"); return;
369 case Iop_F64toI64S: vex_printf("F64toI64S"); return;
370 case Iop_F64toI64U: vex_printf("F64toI64U"); return;
371
372 case Iop_F64toI32U: vex_printf("F64toI32U"); return;
373
374 case Iop_I16StoF64: vex_printf("I16StoF64"); return;
375 case Iop_I32StoF64: vex_printf("I32StoF64"); return;
376 case Iop_I64StoF64: vex_printf("I64StoF64"); return;
377 case Iop_I64UtoF64: vex_printf("I64UtoF64"); return;
378 case Iop_I64UtoF32: vex_printf("I64UtoF32"); return;
379
380 case Iop_I32UtoF64: vex_printf("I32UtoF64"); return;
381
382 case Iop_F32toF64: vex_printf("F32toF64"); return;
383 case Iop_F64toF32: vex_printf("F64toF32"); return;
384
385 case Iop_RoundF64toInt: vex_printf("RoundF64toInt"); return;
386 case Iop_RoundF32toInt: vex_printf("RoundF32toInt"); return;
387 case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return;
388
389 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
390 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
391 case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return;
392 case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
393
394 case Iop_I32UtoFx4: vex_printf("I32UtoFx4"); return;
395 case Iop_I32StoFx4: vex_printf("I32StoFx4"); return;
396
397 case Iop_F32toF16x4: vex_printf("F32toF16x4"); return;
398 case Iop_F16toF32x4: vex_printf("F16toF32x4"); return;
399
400 case Iop_Rsqrte32Fx4: vex_printf("VRsqrte32Fx4"); return;
401 case Iop_Rsqrte32x4: vex_printf("VRsqrte32x4"); return;
402 case Iop_Rsqrte32Fx2: vex_printf("VRsqrte32Fx2"); return;
403 case Iop_Rsqrte32x2: vex_printf("VRsqrte32x2"); return;
404
405 case Iop_QFtoI32Ux4_RZ: vex_printf("QFtoI32Ux4_RZ"); return;
406 case Iop_QFtoI32Sx4_RZ: vex_printf("QFtoI32Sx4_RZ"); return;
407
408 case Iop_FtoI32Ux4_RZ: vex_printf("FtoI32Ux4_RZ"); return;
409 case Iop_FtoI32Sx4_RZ: vex_printf("FtoI32Sx4_RZ"); return;
410
411 case Iop_I32UtoFx2: vex_printf("I32UtoFx2"); return;
412 case Iop_I32StoFx2: vex_printf("I32StoFx2"); return;
413
414 case Iop_FtoI32Ux2_RZ: vex_printf("FtoI32Ux2_RZ"); return;
415 case Iop_FtoI32Sx2_RZ: vex_printf("FtoI32Sx2_RZ"); return;
416
417 case Iop_RoundF32x4_RM: vex_printf("RoundF32x4_RM"); return;
418 case Iop_RoundF32x4_RP: vex_printf("RoundF32x4_RP"); return;
419 case Iop_RoundF32x4_RN: vex_printf("RoundF32x4_RN"); return;
420 case Iop_RoundF32x4_RZ: vex_printf("RoundF32x4_RZ"); return;
421
422 case Iop_Abs8x8: vex_printf("Abs8x8"); return;
423 case Iop_Abs16x4: vex_printf("Abs16x4"); return;
424 case Iop_Abs32x2: vex_printf("Abs32x2"); return;
425 case Iop_Add8x8: vex_printf("Add8x8"); return;
426 case Iop_Add16x4: vex_printf("Add16x4"); return;
427 case Iop_Add32x2: vex_printf("Add32x2"); return;
428 case Iop_QAdd8Ux8: vex_printf("QAdd8Ux8"); return;
429 case Iop_QAdd16Ux4: vex_printf("QAdd16Ux4"); return;
430 case Iop_QAdd32Ux2: vex_printf("QAdd32Ux2"); return;
431 case Iop_QAdd64Ux1: vex_printf("QAdd64Ux1"); return;
432 case Iop_QAdd8Sx8: vex_printf("QAdd8Sx8"); return;
433 case Iop_QAdd16Sx4: vex_printf("QAdd16Sx4"); return;
434 case Iop_QAdd32Sx2: vex_printf("QAdd32Sx2"); return;
435 case Iop_QAdd64Sx1: vex_printf("QAdd64Sx1"); return;
436 case Iop_PwAdd8x8: vex_printf("PwAdd8x8"); return;
437 case Iop_PwAdd16x4: vex_printf("PwAdd16x4"); return;
438 case Iop_PwAdd32x2: vex_printf("PwAdd32x2"); return;
439 case Iop_PwAdd32Fx2: vex_printf("PwAdd32Fx2"); return;
440 case Iop_PwAddL8Ux8: vex_printf("PwAddL8Ux8"); return;
441 case Iop_PwAddL16Ux4: vex_printf("PwAddL16Ux4"); return;
442 case Iop_PwAddL32Ux2: vex_printf("PwAddL32Ux2"); return;
443 case Iop_PwAddL8Sx8: vex_printf("PwAddL8Sx8"); return;
444 case Iop_PwAddL16Sx4: vex_printf("PwAddL16Sx4"); return;
445 case Iop_PwAddL32Sx2: vex_printf("PwAddL32Sx2"); return;
446 case Iop_Sub8x8: vex_printf("Sub8x8"); return;
447 case Iop_Sub16x4: vex_printf("Sub16x4"); return;
448 case Iop_Sub32x2: vex_printf("Sub32x2"); return;
449 case Iop_QSub8Ux8: vex_printf("QSub8Ux8"); return;
450 case Iop_QSub16Ux4: vex_printf("QSub16Ux4"); return;
451 case Iop_QSub32Ux2: vex_printf("QSub32Ux2"); return;
452 case Iop_QSub64Ux1: vex_printf("QSub64Ux1"); return;
453 case Iop_QSub8Sx8: vex_printf("QSub8Sx8"); return;
454 case Iop_QSub16Sx4: vex_printf("QSub16Sx4"); return;
455 case Iop_QSub32Sx2: vex_printf("QSub32Sx2"); return;
456 case Iop_QSub64Sx1: vex_printf("QSub64Sx1"); return;
457 case Iop_Mul8x8: vex_printf("Mul8x8"); return;
458 case Iop_Mul16x4: vex_printf("Mul16x4"); return;
459 case Iop_Mul32x2: vex_printf("Mul32x2"); return;
460 case Iop_Mul32Fx2: vex_printf("Mul32Fx2"); return;
461 case Iop_PolynomialMul8x8: vex_printf("PolynomialMul8x8"); return;
462 case Iop_MulHi16Ux4: vex_printf("MulHi16Ux4"); return;
463 case Iop_MulHi16Sx4: vex_printf("MulHi16Sx4"); return;
464 case Iop_QDMulHi16Sx4: vex_printf("QDMulHi16Sx4"); return;
465 case Iop_QDMulHi32Sx2: vex_printf("QDMulHi32Sx2"); return;
466 case Iop_QRDMulHi16Sx4: vex_printf("QRDMulHi16Sx4"); return;
467 case Iop_QRDMulHi32Sx2: vex_printf("QRDMulHi32Sx2"); return;
468 case Iop_QDMulLong16Sx4: vex_printf("QDMulLong16Sx4"); return;
469 case Iop_QDMulLong32Sx2: vex_printf("QDMulLong32Sx2"); return;
470 case Iop_Avg8Ux8: vex_printf("Avg8Ux8"); return;
471 case Iop_Avg16Ux4: vex_printf("Avg16Ux4"); return;
472 case Iop_Max8Sx8: vex_printf("Max8Sx8"); return;
473 case Iop_Max16Sx4: vex_printf("Max16Sx4"); return;
474 case Iop_Max32Sx2: vex_printf("Max32Sx2"); return;
475 case Iop_Max8Ux8: vex_printf("Max8Ux8"); return;
476 case Iop_Max16Ux4: vex_printf("Max16Ux4"); return;
477 case Iop_Max32Ux2: vex_printf("Max32Ux2"); return;
478 case Iop_Min8Sx8: vex_printf("Min8Sx8"); return;
479 case Iop_Min16Sx4: vex_printf("Min16Sx4"); return;
480 case Iop_Min32Sx2: vex_printf("Min32Sx2"); return;
481 case Iop_Min8Ux8: vex_printf("Min8Ux8"); return;
482 case Iop_Min16Ux4: vex_printf("Min16Ux4"); return;
483 case Iop_Min32Ux2: vex_printf("Min32Ux2"); return;
484 case Iop_PwMax8Sx8: vex_printf("PwMax8Sx8"); return;
485 case Iop_PwMax16Sx4: vex_printf("PwMax16Sx4"); return;
486 case Iop_PwMax32Sx2: vex_printf("PwMax32Sx2"); return;
487 case Iop_PwMax8Ux8: vex_printf("PwMax8Ux8"); return;
488 case Iop_PwMax16Ux4: vex_printf("PwMax16Ux4"); return;
489 case Iop_PwMax32Ux2: vex_printf("PwMax32Ux2"); return;
490 case Iop_PwMin8Sx8: vex_printf("PwMin8Sx8"); return;
491 case Iop_PwMin16Sx4: vex_printf("PwMin16Sx4"); return;
492 case Iop_PwMin32Sx2: vex_printf("PwMin32Sx2"); return;
493 case Iop_PwMin8Ux8: vex_printf("PwMin8Ux8"); return;
494 case Iop_PwMin16Ux4: vex_printf("PwMin16Ux4"); return;
495 case Iop_PwMin32Ux2: vex_printf("PwMin32Ux2"); return;
496 case Iop_CmpEQ8x8: vex_printf("CmpEQ8x8"); return;
497 case Iop_CmpEQ16x4: vex_printf("CmpEQ16x4"); return;
498 case Iop_CmpEQ32x2: vex_printf("CmpEQ32x2"); return;
499 case Iop_CmpGT8Ux8: vex_printf("CmpGT8Ux8"); return;
500 case Iop_CmpGT16Ux4: vex_printf("CmpGT16Ux4"); return;
501 case Iop_CmpGT32Ux2: vex_printf("CmpGT32Ux2"); return;
502 case Iop_CmpGT8Sx8: vex_printf("CmpGT8Sx8"); return;
503 case Iop_CmpGT16Sx4: vex_printf("CmpGT16Sx4"); return;
504 case Iop_CmpGT32Sx2: vex_printf("CmpGT32Sx2"); return;
505 case Iop_Cnt8x8: vex_printf("Cnt8x8"); return;
506 case Iop_Clz8Sx8: vex_printf("Clz8Sx8"); return;
507 case Iop_Clz16Sx4: vex_printf("Clz16Sx4"); return;
508 case Iop_Clz32Sx2: vex_printf("Clz32Sx2"); return;
509 case Iop_Cls8Sx8: vex_printf("Cls8Sx8"); return;
510 case Iop_Cls16Sx4: vex_printf("Cls16Sx4"); return;
511 case Iop_Cls32Sx2: vex_printf("Cls32Sx2"); return;
512 case Iop_ShlN8x8: vex_printf("ShlN8x8"); return;
513 case Iop_ShlN16x4: vex_printf("ShlN16x4"); return;
514 case Iop_ShlN32x2: vex_printf("ShlN32x2"); return;
515 case Iop_ShrN8x8: vex_printf("ShrN8x8"); return;
516 case Iop_ShrN16x4: vex_printf("ShrN16x4"); return;
517 case Iop_ShrN32x2: vex_printf("ShrN32x2"); return;
518 case Iop_SarN8x8: vex_printf("SarN8x8"); return;
519 case Iop_SarN16x4: vex_printf("SarN16x4"); return;
520 case Iop_SarN32x2: vex_printf("SarN32x2"); return;
521 case Iop_QNarrowBin16Sto8Ux8: vex_printf("QNarrowBin16Sto8Ux8"); return;
522 case Iop_QNarrowBin16Sto8Sx8: vex_printf("QNarrowBin16Sto8Sx8"); return;
523 case Iop_QNarrowBin32Sto16Sx4: vex_printf("QNarrowBin32Sto16Sx4"); return;
524 case Iop_NarrowBin16to8x8: vex_printf("NarrowBin16to8x8"); return;
525 case Iop_NarrowBin32to16x4: vex_printf("NarrowBin32to16x4"); return;
526 case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return;
527 case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return;
528 case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return;
529 case Iop_InterleaveLO8x8: vex_printf("InterleaveLO8x8"); return;
530 case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return;
531 case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return;
532 case Iop_CatOddLanes8x8: vex_printf("CatOddLanes8x8"); return;
533 case Iop_CatOddLanes16x4: vex_printf("CatOddLanes16x4"); return;
534 case Iop_CatEvenLanes8x8: vex_printf("CatEvenLanes8x8"); return;
535 case Iop_CatEvenLanes16x4: vex_printf("CatEvenLanes16x4"); return;
536 case Iop_InterleaveOddLanes8x8: vex_printf("InterleaveOddLanes8x8"); return;
537 case Iop_InterleaveOddLanes16x4: vex_printf("InterleaveOddLanes16x4"); return;
538 case Iop_InterleaveEvenLanes8x8: vex_printf("InterleaveEvenLanes8x8"); return;
539 case Iop_InterleaveEvenLanes16x4: vex_printf("InterleaveEvenLanes16x4"); return;
540 case Iop_Shl8x8: vex_printf("Shl8x8"); return;
541 case Iop_Shl16x4: vex_printf("Shl16x4"); return;
542 case Iop_Shl32x2: vex_printf("Shl32x2"); return;
543 case Iop_Shr8x8: vex_printf("Shr8x8"); return;
544 case Iop_Shr16x4: vex_printf("Shr16x4"); return;
545 case Iop_Shr32x2: vex_printf("Shr32x2"); return;
546 case Iop_QShl8x8: vex_printf("QShl8x8"); return;
547 case Iop_QShl16x4: vex_printf("QShl16x4"); return;
548 case Iop_QShl32x2: vex_printf("QShl32x2"); return;
549 case Iop_QShl64x1: vex_printf("QShl64x1"); return;
550 case Iop_QSal8x8: vex_printf("QSal8x8"); return;
551 case Iop_QSal16x4: vex_printf("QSal16x4"); return;
552 case Iop_QSal32x2: vex_printf("QSal32x2"); return;
553 case Iop_QSal64x1: vex_printf("QSal64x1"); return;
554 case Iop_QShlN8x8: vex_printf("QShlN8x8"); return;
555 case Iop_QShlN16x4: vex_printf("QShlN16x4"); return;
556 case Iop_QShlN32x2: vex_printf("QShlN32x2"); return;
557 case Iop_QShlN64x1: vex_printf("QShlN64x1"); return;
558 case Iop_QShlN8Sx8: vex_printf("QShlN8Sx8"); return;
559 case Iop_QShlN16Sx4: vex_printf("QShlN16Sx4"); return;
560 case Iop_QShlN32Sx2: vex_printf("QShlN32Sx2"); return;
561 case Iop_QShlN64Sx1: vex_printf("QShlN64Sx1"); return;
562 case Iop_QSalN8x8: vex_printf("QSalN8x8"); return;
563 case Iop_QSalN16x4: vex_printf("QSalN16x4"); return;
564 case Iop_QSalN32x2: vex_printf("QSalN32x2"); return;
565 case Iop_QSalN64x1: vex_printf("QSalN64x1"); return;
566 case Iop_Sar8x8: vex_printf("Sar8x8"); return;
567 case Iop_Sar16x4: vex_printf("Sar16x4"); return;
568 case Iop_Sar32x2: vex_printf("Sar32x2"); return;
569 case Iop_Sal8x8: vex_printf("Sal8x8"); return;
570 case Iop_Sal16x4: vex_printf("Sal16x4"); return;
571 case Iop_Sal32x2: vex_printf("Sal32x2"); return;
572 case Iop_Sal64x1: vex_printf("Sal64x1"); return;
573 case Iop_Perm8x8: vex_printf("Perm8x8"); return;
574 case Iop_Reverse16_8x8: vex_printf("Reverse16_8x8"); return;
575 case Iop_Reverse32_8x8: vex_printf("Reverse32_8x8"); return;
576 case Iop_Reverse32_16x4: vex_printf("Reverse32_16x4"); return;
577 case Iop_Reverse64_8x8: vex_printf("Reverse64_8x8"); return;
578 case Iop_Reverse64_16x4: vex_printf("Reverse64_16x4"); return;
579 case Iop_Reverse64_32x2: vex_printf("Reverse64_32x2"); return;
580 case Iop_Abs32Fx2: vex_printf("Abs32Fx2"); return;
581
582 case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return;
583 case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return;
584 case Iop_CmpNEZ8x8: vex_printf("CmpNEZ8x8"); return;
585
586 case Iop_Add32Fx4: vex_printf("Add32Fx4"); return;
587 case Iop_Add32Fx2: vex_printf("Add32Fx2"); return;
588 case Iop_Add32F0x4: vex_printf("Add32F0x4"); return;
589 case Iop_Add64Fx2: vex_printf("Add64Fx2"); return;
590 case Iop_Add64F0x2: vex_printf("Add64F0x2"); return;
591
592 case Iop_Div32Fx4: vex_printf("Div32Fx4"); return;
593 case Iop_Div32F0x4: vex_printf("Div32F0x4"); return;
594 case Iop_Div64Fx2: vex_printf("Div64Fx2"); return;
595 case Iop_Div64F0x2: vex_printf("Div64F0x2"); return;
596
597 case Iop_Max32Fx8: vex_printf("Max32Fx8"); return;
598 case Iop_Max32Fx4: vex_printf("Max32Fx4"); return;
599 case Iop_Max32Fx2: vex_printf("Max32Fx2"); return;
600 case Iop_PwMax32Fx4: vex_printf("PwMax32Fx4"); return;
601 case Iop_PwMax32Fx2: vex_printf("PwMax32Fx2"); return;
602 case Iop_Max32F0x4: vex_printf("Max32F0x4"); return;
603 case Iop_Max64Fx4: vex_printf("Max64Fx4"); return;
604 case Iop_Max64Fx2: vex_printf("Max64Fx2"); return;
605 case Iop_Max64F0x2: vex_printf("Max64F0x2"); return;
606
607 case Iop_Min32Fx8: vex_printf("Min32Fx8"); return;
608 case Iop_Min32Fx4: vex_printf("Min32Fx4"); return;
609 case Iop_Min32Fx2: vex_printf("Min32Fx2"); return;
610 case Iop_PwMin32Fx4: vex_printf("PwMin32Fx4"); return;
611 case Iop_PwMin32Fx2: vex_printf("PwMin32Fx2"); return;
612 case Iop_Min32F0x4: vex_printf("Min32F0x4"); return;
613 case Iop_Min64Fx4: vex_printf("Min64Fx4"); return;
614 case Iop_Min64Fx2: vex_printf("Min64Fx2"); return;
615 case Iop_Min64F0x2: vex_printf("Min64F0x2"); return;
616
617 case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return;
618 case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return;
619 case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return;
620 case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return;
621
622 case Iop_Recip32x2: vex_printf("Recip32x2"); return;
623 case Iop_Recip32Fx2: vex_printf("Recip32Fx2"); return;
624 case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return;
625 case Iop_Recip32Fx8: vex_printf("Recip32Fx8"); return;
626 case Iop_Recip32x4: vex_printf("Recip32x4"); return;
627 case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return;
628 case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return;
629 case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return;
630 case Iop_Recps32Fx2: vex_printf("VRecps32Fx2"); return;
631 case Iop_Recps32Fx4: vex_printf("VRecps32Fx4"); return;
632 case Iop_Abs32Fx4: vex_printf("Abs32Fx4"); return;
633 case Iop_Rsqrts32Fx4: vex_printf("VRsqrts32Fx4"); return;
634 case Iop_Rsqrts32Fx2: vex_printf("VRsqrts32Fx2"); return;
635
636 case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return;
637 case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return;
638 case Iop_RSqrt32Fx8: vex_printf("RSqrt32Fx8"); return;
639 case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return;
640 case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return;
641
642 case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return;
643 case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return;
644 case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return;
645 case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return;
646 case Iop_Sqrt32Fx8: vex_printf("Sqrt32Fx8"); return;
647 case Iop_Sqrt64Fx4: vex_printf("Sqrt64Fx4"); return;
648
649 case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return;
650 case Iop_Sub32Fx2: vex_printf("Sub32Fx2"); return;
651 case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return;
652 case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return;
653 case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return;
654
655 case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return;
656 case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return;
657 case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return;
658 case Iop_CmpGT32Fx4: vex_printf("CmpGT32Fx4"); return;
659 case Iop_CmpGE32Fx4: vex_printf("CmpGE32Fx4"); return;
660 case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return;
661 case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return;
662 case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return;
663 case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return;
664 case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return;
665 case Iop_CmpGT32Fx2: vex_printf("CmpGT32Fx2"); return;
666 case Iop_CmpEQ32Fx2: vex_printf("CmpEQ32Fx2"); return;
667 case Iop_CmpGE32Fx2: vex_printf("CmpGE32Fx2"); return;
668
669 case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return;
670 case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return;
671 case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return;
672 case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return;
673 case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return;
674 case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return;
675 case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return;
676 case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return;
677
678 case Iop_Neg32Fx4: vex_printf("Neg32Fx4"); return;
679 case Iop_Neg32Fx2: vex_printf("Neg32Fx2"); return;
680
681 case Iop_V128to64: vex_printf("V128to64"); return;
682 case Iop_V128HIto64: vex_printf("V128HIto64"); return;
683 case Iop_64HLtoV128: vex_printf("64HLtoV128"); return;
684
685 case Iop_64UtoV128: vex_printf("64UtoV128"); return;
686 case Iop_SetV128lo64: vex_printf("SetV128lo64"); return;
687
688 case Iop_32UtoV128: vex_printf("32UtoV128"); return;
689 case Iop_V128to32: vex_printf("V128to32"); return;
690 case Iop_SetV128lo32: vex_printf("SetV128lo32"); return;
691
692 case Iop_Dup8x16: vex_printf("Dup8x16"); return;
693 case Iop_Dup16x8: vex_printf("Dup16x8"); return;
694 case Iop_Dup32x4: vex_printf("Dup32x4"); return;
695 case Iop_Dup8x8: vex_printf("Dup8x8"); return;
696 case Iop_Dup16x4: vex_printf("Dup16x4"); return;
697 case Iop_Dup32x2: vex_printf("Dup32x2"); return;
698
699 case Iop_NotV128: vex_printf("NotV128"); return;
700 case Iop_AndV128: vex_printf("AndV128"); return;
701 case Iop_OrV128: vex_printf("OrV128"); return;
702 case Iop_XorV128: vex_printf("XorV128"); return;
703
704 case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return;
705 case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return;
706 case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
707 case Iop_CmpNEZ64x2: vex_printf("CmpNEZ64x2"); return;
708
709 case Iop_Abs8x16: vex_printf("Abs8x16"); return;
710 case Iop_Abs16x8: vex_printf("Abs16x8"); return;
711 case Iop_Abs32x4: vex_printf("Abs32x4"); return;
712
713 case Iop_Add8x16: vex_printf("Add8x16"); return;
714 case Iop_Add16x8: vex_printf("Add16x8"); return;
715 case Iop_Add32x4: vex_printf("Add32x4"); return;
716 case Iop_Add64x2: vex_printf("Add64x2"); return;
717 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
718 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
719 case Iop_QAdd32Ux4: vex_printf("QAdd32Ux4"); return;
720 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
721 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
722 case Iop_QAdd32Sx4: vex_printf("QAdd32Sx4"); return;
723 case Iop_QAdd64Ux2: vex_printf("QAdd64Ux2"); return;
724 case Iop_QAdd64Sx2: vex_printf("QAdd64Sx2"); return;
725 case Iop_PwAdd8x16: vex_printf("PwAdd8x16"); return;
726 case Iop_PwAdd16x8: vex_printf("PwAdd16x8"); return;
727 case Iop_PwAdd32x4: vex_printf("PwAdd32x4"); return;
728 case Iop_PwAddL8Ux16: vex_printf("PwAddL8Ux16"); return;
729 case Iop_PwAddL16Ux8: vex_printf("PwAddL16Ux8"); return;
730 case Iop_PwAddL32Ux4: vex_printf("PwAddL32Ux4"); return;
731 case Iop_PwAddL8Sx16: vex_printf("PwAddL8Sx16"); return;
732 case Iop_PwAddL16Sx8: vex_printf("PwAddL16Sx8"); return;
733 case Iop_PwAddL32Sx4: vex_printf("PwAddL32Sx4"); return;
734
735 case Iop_Sub8x16: vex_printf("Sub8x16"); return;
736 case Iop_Sub16x8: vex_printf("Sub16x8"); return;
737 case Iop_Sub32x4: vex_printf("Sub32x4"); return;
738 case Iop_Sub64x2: vex_printf("Sub64x2"); return;
739 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
740 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
741 case Iop_QSub32Ux4: vex_printf("QSub32Ux4"); return;
742 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
743 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
744 case Iop_QSub32Sx4: vex_printf("QSub32Sx4"); return;
745 case Iop_QSub64Ux2: vex_printf("QSub64Ux2"); return;
746 case Iop_QSub64Sx2: vex_printf("QSub64Sx2"); return;
747
748 case Iop_Mul8x16: vex_printf("Mul8x16"); return;
749 case Iop_Mul16x8: vex_printf("Mul16x8"); return;
750 case Iop_Mul32x4: vex_printf("Mul32x4"); return;
751 case Iop_Mull8Ux8: vex_printf("Mull8Ux8"); return;
752 case Iop_Mull8Sx8: vex_printf("Mull8Sx8"); return;
753 case Iop_Mull16Ux4: vex_printf("Mull16Ux4"); return;
754 case Iop_Mull16Sx4: vex_printf("Mull16Sx4"); return;
755 case Iop_Mull32Ux2: vex_printf("Mull32Ux2"); return;
756 case Iop_Mull32Sx2: vex_printf("Mull32Sx2"); return;
757 case Iop_PolynomialMul8x16: vex_printf("PolynomialMul8x16"); return;
758 case Iop_PolynomialMull8x8: vex_printf("PolynomialMull8x8"); return;
759 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
760 case Iop_MulHi32Ux4: vex_printf("MulHi32Ux4"); return;
761 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
762 case Iop_MulHi32Sx4: vex_printf("MulHi32Sx4"); return;
763 case Iop_QDMulHi16Sx8: vex_printf("QDMulHi16Sx8"); return;
764 case Iop_QDMulHi32Sx4: vex_printf("QDMulHi32Sx4"); return;
765 case Iop_QRDMulHi16Sx8: vex_printf("QRDMulHi16Sx8"); return;
766 case Iop_QRDMulHi32Sx4: vex_printf("QRDMulHi32Sx4"); return;
767
768 case Iop_MullEven8Ux16: vex_printf("MullEven8Ux16"); return;
769 case Iop_MullEven16Ux8: vex_printf("MullEven16Ux8"); return;
770 case Iop_MullEven8Sx16: vex_printf("MullEven8Sx16"); return;
771 case Iop_MullEven16Sx8: vex_printf("MullEven16Sx8"); return;
772
773 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
774 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
775 case Iop_Avg32Ux4: vex_printf("Avg32Ux4"); return;
776 case Iop_Avg8Sx16: vex_printf("Avg8Sx16"); return;
777 case Iop_Avg16Sx8: vex_printf("Avg16Sx8"); return;
778 case Iop_Avg32Sx4: vex_printf("Avg32Sx4"); return;
779
780 case Iop_Max8Sx16: vex_printf("Max8Sx16"); return;
781 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
782 case Iop_Max32Sx4: vex_printf("Max32Sx4"); return;
783 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
784 case Iop_Max16Ux8: vex_printf("Max16Ux8"); return;
785 case Iop_Max32Ux4: vex_printf("Max32Ux4"); return;
786
787 case Iop_Min8Sx16: vex_printf("Min8Sx16"); return;
788 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
789 case Iop_Min32Sx4: vex_printf("Min32Sx4"); return;
790 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
791 case Iop_Min16Ux8: vex_printf("Min16Ux8"); return;
792 case Iop_Min32Ux4: vex_printf("Min32Ux4"); return;
793
794 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return;
795 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return;
796 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return;
797 case Iop_CmpEQ64x2: vex_printf("CmpEQ64x2"); return;
798 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
799 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
800 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
801 case Iop_CmpGT64Sx2: vex_printf("CmpGT64Sx2"); return;
802 case Iop_CmpGT8Ux16: vex_printf("CmpGT8Ux16"); return;
803 case Iop_CmpGT16Ux8: vex_printf("CmpGT16Ux8"); return;
804 case Iop_CmpGT32Ux4: vex_printf("CmpGT32Ux4"); return;
805
806 case Iop_Cnt8x16: vex_printf("Cnt8x16"); return;
807 case Iop_Clz8Sx16: vex_printf("Clz8Sx16"); return;
808 case Iop_Clz16Sx8: vex_printf("Clz16Sx8"); return;
809 case Iop_Clz32Sx4: vex_printf("Clz32Sx4"); return;
810 case Iop_Cls8Sx16: vex_printf("Cls8Sx16"); return;
811 case Iop_Cls16Sx8: vex_printf("Cls16Sx8"); return;
812 case Iop_Cls32Sx4: vex_printf("Cls32Sx4"); return;
813
814 case Iop_ShlV128: vex_printf("ShlV128"); return;
815 case Iop_ShrV128: vex_printf("ShrV128"); return;
816
817 case Iop_ShlN8x16: vex_printf("ShlN8x16"); return;
818 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
819 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
820 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
821 case Iop_ShrN8x16: vex_printf("ShrN8x16"); return;
822 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
823 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
824 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
825 case Iop_SarN8x16: vex_printf("SarN8x16"); return;
826 case Iop_SarN16x8: vex_printf("SarN16x8"); return;
827 case Iop_SarN32x4: vex_printf("SarN32x4"); return;
828 case Iop_SarN64x2: vex_printf("SarN64x2"); return;
829
830 case Iop_Shl8x16: vex_printf("Shl8x16"); return;
831 case Iop_Shl16x8: vex_printf("Shl16x8"); return;
832 case Iop_Shl32x4: vex_printf("Shl32x4"); return;
833 case Iop_Shl64x2: vex_printf("Shl64x2"); return;
834 case Iop_QSal8x16: vex_printf("QSal8x16"); return;
835 case Iop_QSal16x8: vex_printf("QSal16x8"); return;
836 case Iop_QSal32x4: vex_printf("QSal32x4"); return;
837 case Iop_QSal64x2: vex_printf("QSal64x2"); return;
838 case Iop_QShl8x16: vex_printf("QShl8x16"); return;
839 case Iop_QShl16x8: vex_printf("QShl16x8"); return;
840 case Iop_QShl32x4: vex_printf("QShl32x4"); return;
841 case Iop_QShl64x2: vex_printf("QShl64x2"); return;
842 case Iop_QSalN8x16: vex_printf("QSalN8x16"); return;
843 case Iop_QSalN16x8: vex_printf("QSalN16x8"); return;
844 case Iop_QSalN32x4: vex_printf("QSalN32x4"); return;
845 case Iop_QSalN64x2: vex_printf("QSalN64x2"); return;
846 case Iop_QShlN8x16: vex_printf("QShlN8x16"); return;
847 case Iop_QShlN16x8: vex_printf("QShlN16x8"); return;
848 case Iop_QShlN32x4: vex_printf("QShlN32x4"); return;
849 case Iop_QShlN64x2: vex_printf("QShlN64x2"); return;
850 case Iop_QShlN8Sx16: vex_printf("QShlN8Sx16"); return;
851 case Iop_QShlN16Sx8: vex_printf("QShlN16Sx8"); return;
852 case Iop_QShlN32Sx4: vex_printf("QShlN32Sx4"); return;
853 case Iop_QShlN64Sx2: vex_printf("QShlN64Sx2"); return;
854 case Iop_Shr8x16: vex_printf("Shr8x16"); return;
855 case Iop_Shr16x8: vex_printf("Shr16x8"); return;
856 case Iop_Shr32x4: vex_printf("Shr32x4"); return;
857 case Iop_Shr64x2: vex_printf("Shr64x2"); return;
858 case Iop_Sar8x16: vex_printf("Sar8x16"); return;
859 case Iop_Sar16x8: vex_printf("Sar16x8"); return;
860 case Iop_Sar32x4: vex_printf("Sar32x4"); return;
861 case Iop_Sar64x2: vex_printf("Sar64x2"); return;
862 case Iop_Sal8x16: vex_printf("Sal8x16"); return;
863 case Iop_Sal16x8: vex_printf("Sal16x8"); return;
864 case Iop_Sal32x4: vex_printf("Sal32x4"); return;
865 case Iop_Sal64x2: vex_printf("Sal64x2"); return;
866 case Iop_Rol8x16: vex_printf("Rol8x16"); return;
867 case Iop_Rol16x8: vex_printf("Rol16x8"); return;
868 case Iop_Rol32x4: vex_printf("Rol32x4"); return;
869
870 case Iop_NarrowBin16to8x16: vex_printf("NarrowBin16to8x16"); return;
871 case Iop_NarrowBin32to16x8: vex_printf("NarrowBin32to16x8"); return;
872 case Iop_QNarrowBin16Uto8Ux16: vex_printf("QNarrowBin16Uto8Ux16"); return;
873 case Iop_QNarrowBin32Sto16Ux8: vex_printf("QNarrowBin32Sto16Ux8"); return;
874 case Iop_QNarrowBin16Sto8Ux16: vex_printf("QNarrowBin16Sto8Ux16"); return;
875 case Iop_QNarrowBin32Uto16Ux8: vex_printf("QNarrowBin32Uto16Ux8"); return;
876 case Iop_QNarrowBin16Sto8Sx16: vex_printf("QNarrowBin16Sto8Sx16"); return;
877 case Iop_QNarrowBin32Sto16Sx8: vex_printf("QNarrowBin32Sto16Sx8"); return;
878 case Iop_NarrowUn16to8x8: vex_printf("NarrowUn16to8x8"); return;
879 case Iop_NarrowUn32to16x4: vex_printf("NarrowUn32to16x4"); return;
880 case Iop_NarrowUn64to32x2: vex_printf("NarrowUn64to32x2"); return;
881 case Iop_QNarrowUn16Uto8Ux8: vex_printf("QNarrowUn16Uto8Ux8"); return;
882 case Iop_QNarrowUn32Uto16Ux4: vex_printf("QNarrowUn32Uto16Ux4"); return;
883 case Iop_QNarrowUn64Uto32Ux2: vex_printf("QNarrowUn64Uto32Ux2"); return;
884 case Iop_QNarrowUn16Sto8Sx8: vex_printf("QNarrowUn16Sto8Sx8"); return;
885 case Iop_QNarrowUn32Sto16Sx4: vex_printf("QNarrowUn32Sto16Sx4"); return;
886 case Iop_QNarrowUn64Sto32Sx2: vex_printf("QNarrowUn64Sto32Sx2"); return;
887 case Iop_QNarrowUn16Sto8Ux8: vex_printf("QNarrowUn16Sto8Ux8"); return;
888 case Iop_QNarrowUn32Sto16Ux4: vex_printf("QNarrowUn32Sto16Ux4"); return;
889 case Iop_QNarrowUn64Sto32Ux2: vex_printf("QNarrowUn64Sto32Ux2"); return;
890 case Iop_Widen8Uto16x8: vex_printf("Widen8Uto16x8"); return;
891 case Iop_Widen16Uto32x4: vex_printf("Widen16Uto32x4"); return;
892 case Iop_Widen32Uto64x2: vex_printf("Widen32Uto64x2"); return;
893 case Iop_Widen8Sto16x8: vex_printf("Widen8Sto16x8"); return;
894 case Iop_Widen16Sto32x4: vex_printf("Widen16Sto32x4"); return;
895 case Iop_Widen32Sto64x2: vex_printf("Widen32Sto64x2"); return;
896
897 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
898 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
899 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
900 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
901 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
902 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
903 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
904 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
905
906 case Iop_CatOddLanes8x16: vex_printf("CatOddLanes8x16"); return;
907 case Iop_CatOddLanes16x8: vex_printf("CatOddLanes16x8"); return;
908 case Iop_CatOddLanes32x4: vex_printf("CatOddLanes32x4"); return;
909 case Iop_CatEvenLanes8x16: vex_printf("CatEvenLanes8x16"); return;
910 case Iop_CatEvenLanes16x8: vex_printf("CatEvenLanes16x8"); return;
911 case Iop_CatEvenLanes32x4: vex_printf("CatEvenLanes32x4"); return;
912
913 case Iop_InterleaveOddLanes8x16: vex_printf("InterleaveOddLanes8x16"); return;
914 case Iop_InterleaveOddLanes16x8: vex_printf("InterleaveOddLanes16x8"); return;
915 case Iop_InterleaveOddLanes32x4: vex_printf("InterleaveOddLanes32x4"); return;
916 case Iop_InterleaveEvenLanes8x16: vex_printf("InterleaveEvenLanes8x16"); return;
917 case Iop_InterleaveEvenLanes16x8: vex_printf("InterleaveEvenLanes16x8"); return;
918 case Iop_InterleaveEvenLanes32x4: vex_printf("InterleaveEvenLanes32x4"); return;
919
920 case Iop_GetElem8x16: vex_printf("GetElem8x16"); return;
921 case Iop_GetElem16x8: vex_printf("GetElem16x8"); return;
922 case Iop_GetElem32x4: vex_printf("GetElem32x4"); return;
923 case Iop_GetElem64x2: vex_printf("GetElem64x2"); return;
924
925 case Iop_GetElem8x8: vex_printf("GetElem8x8"); return;
926 case Iop_GetElem16x4: vex_printf("GetElem16x4"); return;
927 case Iop_GetElem32x2: vex_printf("GetElem32x2"); return;
928 case Iop_SetElem8x8: vex_printf("SetElem8x8"); return;
929 case Iop_SetElem16x4: vex_printf("SetElem16x4"); return;
930 case Iop_SetElem32x2: vex_printf("SetElem32x2"); return;
931
932 case Iop_Extract64: vex_printf("Extract64"); return;
933 case Iop_ExtractV128: vex_printf("ExtractV128"); return;
934
935 case Iop_Perm8x16: vex_printf("Perm8x16"); return;
936 case Iop_Perm32x4: vex_printf("Perm32x4"); return;
937 case Iop_Reverse16_8x16: vex_printf("Reverse16_8x16"); return;
938 case Iop_Reverse32_8x16: vex_printf("Reverse32_8x16"); return;
939 case Iop_Reverse32_16x8: vex_printf("Reverse32_16x8"); return;
940 case Iop_Reverse64_8x16: vex_printf("Reverse64_8x16"); return;
941 case Iop_Reverse64_16x8: vex_printf("Reverse64_16x8"); return;
942 case Iop_Reverse64_32x4: vex_printf("Reverse64_32x4"); return;
943
944 case Iop_F32ToFixed32Ux4_RZ: vex_printf("F32ToFixed32Ux4_RZ"); return;
945 case Iop_F32ToFixed32Sx4_RZ: vex_printf("F32ToFixed32Sx4_RZ"); return;
946 case Iop_Fixed32UToF32x4_RN: vex_printf("Fixed32UToF32x4_RN"); return;
947 case Iop_Fixed32SToF32x4_RN: vex_printf("Fixed32SToF32x4_RN"); return;
948 case Iop_F32ToFixed32Ux2_RZ: vex_printf("F32ToFixed32Ux2_RZ"); return;
949 case Iop_F32ToFixed32Sx2_RZ: vex_printf("F32ToFixed32Sx2_RZ"); return;
950 case Iop_Fixed32UToF32x2_RN: vex_printf("Fixed32UToF32x2_RN"); return;
951 case Iop_Fixed32SToF32x2_RN: vex_printf("Fixed32SToF32x2_RN"); return;
952
953 case Iop_D32toD64: vex_printf("D32toD64"); return;
954 case Iop_D64toD32: vex_printf("D64toD32"); return;
955 case Iop_AddD64: vex_printf("AddD64"); return;
956 case Iop_SubD64: vex_printf("SubD64"); return;
957 case Iop_MulD64: vex_printf("MulD64"); return;
958 case Iop_DivD64: vex_printf("DivD64"); return;
959 case Iop_ShlD64: vex_printf("ShlD64"); return;
960 case Iop_ShrD64: vex_printf("ShrD64"); return;
961 case Iop_D64toI64S: vex_printf("D64toI64S"); return;
962 case Iop_I64StoD64: vex_printf("I64StoD64"); return;
963 case Iop_I64StoD128: vex_printf("I64StoD128"); return;
964 case Iop_D64toD128: vex_printf("D64toD128"); return;
965 case Iop_D128toD64: vex_printf("D128toD64"); return;
966 case Iop_D128toI64S: vex_printf("D128toI64S"); return;
967 case Iop_AddD128: vex_printf("AddD128"); return;
968 case Iop_SubD128: vex_printf("SubD128"); return;
969 case Iop_MulD128: vex_printf("MulD128"); return;
970 case Iop_DivD128: vex_printf("DivD128"); return;
971 case Iop_ShlD128: vex_printf("ShlD128"); return;
972 case Iop_ShrD128: vex_printf("ShrD128"); return;
973 case Iop_RoundD64toInt: vex_printf("Iop_RoundD64toInt"); return;
974 case Iop_RoundD128toInt: vex_printf("Iop_RoundD128toInt"); return;
975 case Iop_QuantizeD64: vex_printf("Iop_QuantizeD64"); return;
976 case Iop_QuantizeD128: vex_printf("Iop_QuantizeD128"); return;
977 case Iop_ExtractExpD64: vex_printf("Iop_ExtractExpD64"); return;
978 case Iop_ExtractExpD128: vex_printf("Iop_ExtractExpD128"); return;
979 case Iop_InsertExpD64: vex_printf("Iop_InsertExpD64"); return;
980 case Iop_InsertExpD128: vex_printf("Iop_InsertExpD128"); return;
981 case Iop_CmpD64: vex_printf("CmpD64"); return;
982 case Iop_CmpD128: vex_printf("CmpD128"); return;
983 case Iop_D64HLtoD128: vex_printf("D64HLtoD128"); return;
984 case Iop_D128HItoD64: vex_printf("D128HItoD64"); return;
985 case Iop_D128LOtoD64: vex_printf("D128LOtoD64"); return;
986 case Iop_SignificanceRoundD64: vex_printf("Iop_SignificanceRoundD64");
987 return;
988 case Iop_SignificanceRoundD128: vex_printf("Iop_SignificanceRoundD128");
989 return;
990 case Iop_ReinterpI64asD64: vex_printf("ReinterpI64asD64"); return;
991 case Iop_ReinterpD64asI64: vex_printf("ReinterpD64asI64"); return;
992 case Iop_V256to64_0: vex_printf("V256to64_0"); return;
993 case Iop_V256to64_1: vex_printf("V256to64_1"); return;
994 case Iop_V256to64_2: vex_printf("V256to64_2"); return;
995 case Iop_V256to64_3: vex_printf("V256to64_3"); return;
996 case Iop_64x4toV256: vex_printf("64x4toV256"); return;
997 case Iop_V256toV128_0: vex_printf("V256toV128_0"); return;
998 case Iop_V256toV128_1: vex_printf("V256toV128_1"); return;
999 case Iop_V128HLtoV256: vex_printf("V128HLtoV256"); return;
1000 case Iop_DPBtoBCD: vex_printf("DPBtoBCD"); return;
1001 case Iop_BCDtoDPB: vex_printf("BCDtoDPB"); return;
1002 case Iop_Add64Fx4: vex_printf("Add64Fx4"); return;
1003 case Iop_Sub64Fx4: vex_printf("Sub64Fx4"); return;
1004 case Iop_Mul64Fx4: vex_printf("Mul64Fx4"); return;
1005 case Iop_Div64Fx4: vex_printf("Div64Fx4"); return;
1006 case Iop_Add32Fx8: vex_printf("Add32Fx8"); return;
1007 case Iop_Sub32Fx8: vex_printf("Sub32Fx8"); return;
1008 case Iop_Mul32Fx8: vex_printf("Mul32Fx8"); return;
1009 case Iop_Div32Fx8: vex_printf("Div32Fx8"); return;
1010 case Iop_AndV256: vex_printf("AndV256"); return;
1011 case Iop_OrV256: vex_printf("OrV256"); return;
1012 case Iop_XorV256: vex_printf("XorV256"); return;
1013 case Iop_NotV256: vex_printf("NotV256"); return;
1014 case Iop_CmpNEZ64x4: vex_printf("CmpNEZ64x4"); return;
1015 case Iop_CmpNEZ32x8: vex_printf("CmpNEZ32x8"); return;
1016 default: vpanic("ppIROp(1)");
1017 }
1018
1019 vassert(str);
1020 switch (op - base) {
1021 case 0: vex_printf("%s",str); vex_printf("8"); break;
1022 case 1: vex_printf("%s",str); vex_printf("16"); break;
1023 case 2: vex_printf("%s",str); vex_printf("32"); break;
1024 case 3: vex_printf("%s",str); vex_printf("64"); break;
1025 default: vpanic("ppIROp(2)");
1026 }
1027 }
1028
ppIRExpr(IRExpr * e)1029 void ppIRExpr ( IRExpr* e )
1030 {
1031 Int i;
1032 switch (e->tag) {
1033 case Iex_Binder:
1034 vex_printf("BIND-%d", e->Iex.Binder.binder);
1035 break;
1036 case Iex_Get:
1037 vex_printf( "GET:" );
1038 ppIRType(e->Iex.Get.ty);
1039 vex_printf("(%d)", e->Iex.Get.offset);
1040 break;
1041 case Iex_GetI:
1042 vex_printf( "GETI" );
1043 ppIRRegArray(e->Iex.GetI.descr);
1044 vex_printf("[");
1045 ppIRExpr(e->Iex.GetI.ix);
1046 vex_printf(",%d]", e->Iex.GetI.bias);
1047 break;
1048 case Iex_RdTmp:
1049 ppIRTemp(e->Iex.RdTmp.tmp);
1050 break;
1051 case Iex_Qop: {
1052 IRQop *qop = e->Iex.Qop.details;
1053 ppIROp(qop->op);
1054 vex_printf( "(" );
1055 ppIRExpr(qop->arg1);
1056 vex_printf( "," );
1057 ppIRExpr(qop->arg2);
1058 vex_printf( "," );
1059 ppIRExpr(qop->arg3);
1060 vex_printf( "," );
1061 ppIRExpr(qop->arg4);
1062 vex_printf( ")" );
1063 break;
1064 }
1065 case Iex_Triop: {
1066 IRTriop *triop = e->Iex.Triop.details;
1067 ppIROp(triop->op);
1068 vex_printf( "(" );
1069 ppIRExpr(triop->arg1);
1070 vex_printf( "," );
1071 ppIRExpr(triop->arg2);
1072 vex_printf( "," );
1073 ppIRExpr(triop->arg3);
1074 vex_printf( ")" );
1075 break;
1076 }
1077 case Iex_Binop:
1078 ppIROp(e->Iex.Binop.op);
1079 vex_printf( "(" );
1080 ppIRExpr(e->Iex.Binop.arg1);
1081 vex_printf( "," );
1082 ppIRExpr(e->Iex.Binop.arg2);
1083 vex_printf( ")" );
1084 break;
1085 case Iex_Unop:
1086 ppIROp(e->Iex.Unop.op);
1087 vex_printf( "(" );
1088 ppIRExpr(e->Iex.Unop.arg);
1089 vex_printf( ")" );
1090 break;
1091 case Iex_Load:
1092 vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" );
1093 ppIRType(e->Iex.Load.ty);
1094 vex_printf( "(" );
1095 ppIRExpr(e->Iex.Load.addr);
1096 vex_printf( ")" );
1097 break;
1098 case Iex_Const:
1099 ppIRConst(e->Iex.Const.con);
1100 break;
1101 case Iex_CCall:
1102 ppIRCallee(e->Iex.CCall.cee);
1103 vex_printf("(");
1104 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
1105 ppIRExpr(e->Iex.CCall.args[i]);
1106 if (e->Iex.CCall.args[i+1] != NULL)
1107 vex_printf(",");
1108 }
1109 vex_printf("):");
1110 ppIRType(e->Iex.CCall.retty);
1111 break;
1112 case Iex_Mux0X:
1113 vex_printf("Mux0X(");
1114 ppIRExpr(e->Iex.Mux0X.cond);
1115 vex_printf(",");
1116 ppIRExpr(e->Iex.Mux0X.expr0);
1117 vex_printf(",");
1118 ppIRExpr(e->Iex.Mux0X.exprX);
1119 vex_printf(")");
1120 break;
1121 default:
1122 vpanic("ppIRExpr");
1123 }
1124 }
1125
ppIREffect(IREffect fx)1126 void ppIREffect ( IREffect fx )
1127 {
1128 switch (fx) {
1129 case Ifx_None: vex_printf("noFX"); return;
1130 case Ifx_Read: vex_printf("RdFX"); return;
1131 case Ifx_Write: vex_printf("WrFX"); return;
1132 case Ifx_Modify: vex_printf("MoFX"); return;
1133 default: vpanic("ppIREffect");
1134 }
1135 }
1136
ppIRDirty(IRDirty * d)1137 void ppIRDirty ( IRDirty* d )
1138 {
1139 Int i;
1140 if (d->tmp != IRTemp_INVALID) {
1141 ppIRTemp(d->tmp);
1142 vex_printf(" = ");
1143 }
1144 vex_printf("DIRTY ");
1145 ppIRExpr(d->guard);
1146 if (d->needsBBP)
1147 vex_printf(" NeedsBBP");
1148 if (d->mFx != Ifx_None) {
1149 vex_printf(" ");
1150 ppIREffect(d->mFx);
1151 vex_printf("-mem(");
1152 ppIRExpr(d->mAddr);
1153 vex_printf(",%d)", d->mSize);
1154 }
1155 for (i = 0; i < d->nFxState; i++) {
1156 vex_printf(" ");
1157 ppIREffect(d->fxState[i].fx);
1158 vex_printf("-gst(%u,%u", (UInt)d->fxState[i].offset,
1159 (UInt)d->fxState[i].size);
1160 if (d->fxState[i].nRepeats > 0) {
1161 vex_printf(",reps%u,step%u", (UInt)d->fxState[i].nRepeats,
1162 (UInt)d->fxState[i].repeatLen);
1163 }
1164 vex_printf(")");
1165 }
1166 vex_printf(" ::: ");
1167 ppIRCallee(d->cee);
1168 vex_printf("(");
1169 for (i = 0; d->args[i] != NULL; i++) {
1170 ppIRExpr(d->args[i]);
1171 if (d->args[i+1] != NULL) {
1172 vex_printf(",");
1173 }
1174 }
1175 vex_printf(")");
1176 }
1177
ppIRCAS(IRCAS * cas)1178 void ppIRCAS ( IRCAS* cas )
1179 {
1180 /* Print even structurally invalid constructions, as an aid to
1181 debugging. */
1182 if (cas->oldHi != IRTemp_INVALID) {
1183 ppIRTemp(cas->oldHi);
1184 vex_printf(",");
1185 }
1186 ppIRTemp(cas->oldLo);
1187 vex_printf(" = CAS%s(", cas->end==Iend_LE ? "le" : "be" );
1188 ppIRExpr(cas->addr);
1189 vex_printf("::");
1190 if (cas->expdHi) {
1191 ppIRExpr(cas->expdHi);
1192 vex_printf(",");
1193 }
1194 ppIRExpr(cas->expdLo);
1195 vex_printf("->");
1196 if (cas->dataHi) {
1197 ppIRExpr(cas->dataHi);
1198 vex_printf(",");
1199 }
1200 ppIRExpr(cas->dataLo);
1201 vex_printf(")");
1202 }
1203
ppIRPutI(IRPutI * puti)1204 void ppIRPutI ( IRPutI* puti )
1205 {
1206 vex_printf( "PUTI" );
1207 ppIRRegArray(puti->descr);
1208 vex_printf("[");
1209 ppIRExpr(puti->ix);
1210 vex_printf(",%d] = ", puti->bias);
1211 ppIRExpr(puti->data);
1212 }
1213
ppIRJumpKind(IRJumpKind kind)1214 void ppIRJumpKind ( IRJumpKind kind )
1215 {
1216 switch (kind) {
1217 case Ijk_Boring: vex_printf("Boring"); break;
1218 case Ijk_Call: vex_printf("Call"); break;
1219 case Ijk_Ret: vex_printf("Return"); break;
1220 case Ijk_ClientReq: vex_printf("ClientReq"); break;
1221 case Ijk_Yield: vex_printf("Yield"); break;
1222 case Ijk_EmWarn: vex_printf("EmWarn"); break;
1223 case Ijk_EmFail: vex_printf("EmFail"); break;
1224 case Ijk_NoDecode: vex_printf("NoDecode"); break;
1225 case Ijk_MapFail: vex_printf("MapFail"); break;
1226 case Ijk_TInval: vex_printf("Invalidate"); break;
1227 case Ijk_NoRedir: vex_printf("NoRedir"); break;
1228 case Ijk_SigTRAP: vex_printf("SigTRAP"); break;
1229 case Ijk_SigSEGV: vex_printf("SigSEGV"); break;
1230 case Ijk_SigBUS: vex_printf("SigBUS"); break;
1231 case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
1232 case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
1233 case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
1234 case Ijk_Sys_int129: vex_printf("Sys_int129"); break;
1235 case Ijk_Sys_int130: vex_printf("Sys_int130"); break;
1236 case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break;
1237 default: vpanic("ppIRJumpKind");
1238 }
1239 }
1240
ppIRMBusEvent(IRMBusEvent event)1241 void ppIRMBusEvent ( IRMBusEvent event )
1242 {
1243 switch (event) {
1244 case Imbe_Fence:
1245 vex_printf("Fence"); break;
1246 case Imbe_CancelReservation:
1247 vex_printf("CancelReservation"); break;
1248 default:
1249 vpanic("ppIRMBusEvent");
1250 }
1251 }
1252
ppIRStmt(IRStmt * s)1253 void ppIRStmt ( IRStmt* s )
1254 {
1255 if (!s) {
1256 vex_printf("!!! IRStmt* which is NULL !!!");
1257 return;
1258 }
1259 switch (s->tag) {
1260 case Ist_NoOp:
1261 vex_printf("IR-NoOp");
1262 break;
1263 case Ist_IMark:
1264 vex_printf( "------ IMark(0x%llx, %d, %u) ------",
1265 s->Ist.IMark.addr, s->Ist.IMark.len,
1266 (UInt)s->Ist.IMark.delta);
1267 break;
1268 case Ist_AbiHint:
1269 vex_printf("====== AbiHint(");
1270 ppIRExpr(s->Ist.AbiHint.base);
1271 vex_printf(", %d, ", s->Ist.AbiHint.len);
1272 ppIRExpr(s->Ist.AbiHint.nia);
1273 vex_printf(") ======");
1274 break;
1275 case Ist_Put:
1276 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
1277 ppIRExpr(s->Ist.Put.data);
1278 break;
1279 case Ist_PutI:
1280 ppIRPutI(s->Ist.PutI.details);
1281 break;
1282 case Ist_WrTmp:
1283 ppIRTemp(s->Ist.WrTmp.tmp);
1284 vex_printf( " = " );
1285 ppIRExpr(s->Ist.WrTmp.data);
1286 break;
1287 case Ist_Store:
1288 vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" );
1289 ppIRExpr(s->Ist.Store.addr);
1290 vex_printf( ") = ");
1291 ppIRExpr(s->Ist.Store.data);
1292 break;
1293 case Ist_CAS:
1294 ppIRCAS(s->Ist.CAS.details);
1295 break;
1296 case Ist_LLSC:
1297 if (s->Ist.LLSC.storedata == NULL) {
1298 ppIRTemp(s->Ist.LLSC.result);
1299 vex_printf(" = LD%s-Linked(",
1300 s->Ist.LLSC.end==Iend_LE ? "le" : "be");
1301 ppIRExpr(s->Ist.LLSC.addr);
1302 vex_printf(")");
1303 } else {
1304 ppIRTemp(s->Ist.LLSC.result);
1305 vex_printf(" = ( ST%s-Cond(",
1306 s->Ist.LLSC.end==Iend_LE ? "le" : "be");
1307 ppIRExpr(s->Ist.LLSC.addr);
1308 vex_printf(") = ");
1309 ppIRExpr(s->Ist.LLSC.storedata);
1310 vex_printf(" )");
1311 }
1312 break;
1313 case Ist_Dirty:
1314 ppIRDirty(s->Ist.Dirty.details);
1315 break;
1316 case Ist_MBE:
1317 vex_printf("IR-");
1318 ppIRMBusEvent(s->Ist.MBE.event);
1319 break;
1320 case Ist_Exit:
1321 vex_printf( "if (" );
1322 ppIRExpr(s->Ist.Exit.guard);
1323 vex_printf( ") { PUT(%d) = ", s->Ist.Exit.offsIP);
1324 ppIRConst(s->Ist.Exit.dst);
1325 vex_printf("; exit-");
1326 ppIRJumpKind(s->Ist.Exit.jk);
1327 vex_printf(" } ");
1328 break;
1329 default:
1330 vpanic("ppIRStmt");
1331 }
1332 }
1333
ppIRTypeEnv(IRTypeEnv * env)1334 void ppIRTypeEnv ( IRTypeEnv* env ) {
1335 UInt i;
1336 for (i = 0; i < env->types_used; i++) {
1337 if (i % 8 == 0)
1338 vex_printf( " ");
1339 ppIRTemp(i);
1340 vex_printf( ":");
1341 ppIRType(env->types[i]);
1342 if (i % 8 == 7)
1343 vex_printf( "\n");
1344 else
1345 vex_printf( " ");
1346 }
1347 if (env->types_used > 0 && env->types_used % 8 != 7)
1348 vex_printf( "\n");
1349 }
1350
ppIRSB(IRSB * bb)1351 void ppIRSB ( IRSB* bb )
1352 {
1353 Int i;
1354 vex_printf("IRSB {\n");
1355 ppIRTypeEnv(bb->tyenv);
1356 vex_printf("\n");
1357 for (i = 0; i < bb->stmts_used; i++) {
1358 vex_printf( " ");
1359 ppIRStmt(bb->stmts[i]);
1360 vex_printf( "\n");
1361 }
1362 vex_printf( " PUT(%d) = ", bb->offsIP );
1363 ppIRExpr( bb->next );
1364 vex_printf( "; exit-");
1365 ppIRJumpKind(bb->jumpkind);
1366 vex_printf( "\n}\n");
1367 }
1368
1369
1370 /*---------------------------------------------------------------*/
1371 /*--- Constructors ---*/
1372 /*---------------------------------------------------------------*/
1373
1374
1375 /* Constructors -- IRConst */
1376
IRConst_U1(Bool bit)1377 IRConst* IRConst_U1 ( Bool bit )
1378 {
1379 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1380 c->tag = Ico_U1;
1381 c->Ico.U1 = bit;
1382 /* call me paranoid; I don't care :-) */
1383 vassert(bit == False || bit == True);
1384 return c;
1385 }
IRConst_U8(UChar u8)1386 IRConst* IRConst_U8 ( UChar u8 )
1387 {
1388 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1389 c->tag = Ico_U8;
1390 c->Ico.U8 = u8;
1391 return c;
1392 }
IRConst_U16(UShort u16)1393 IRConst* IRConst_U16 ( UShort u16 )
1394 {
1395 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1396 c->tag = Ico_U16;
1397 c->Ico.U16 = u16;
1398 return c;
1399 }
IRConst_U32(UInt u32)1400 IRConst* IRConst_U32 ( UInt u32 )
1401 {
1402 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1403 c->tag = Ico_U32;
1404 c->Ico.U32 = u32;
1405 return c;
1406 }
IRConst_U64(ULong u64)1407 IRConst* IRConst_U64 ( ULong u64 )
1408 {
1409 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1410 c->tag = Ico_U64;
1411 c->Ico.U64 = u64;
1412 return c;
1413 }
IRConst_F32(Float f32)1414 IRConst* IRConst_F32 ( Float f32 )
1415 {
1416 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1417 c->tag = Ico_F32;
1418 c->Ico.F32 = f32;
1419 return c;
1420 }
IRConst_F32i(UInt f32i)1421 IRConst* IRConst_F32i ( UInt f32i )
1422 {
1423 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1424 c->tag = Ico_F32i;
1425 c->Ico.F32i = f32i;
1426 return c;
1427 }
IRConst_F64(Double f64)1428 IRConst* IRConst_F64 ( Double f64 )
1429 {
1430 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1431 c->tag = Ico_F64;
1432 c->Ico.F64 = f64;
1433 return c;
1434 }
IRConst_F64i(ULong f64i)1435 IRConst* IRConst_F64i ( ULong f64i )
1436 {
1437 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1438 c->tag = Ico_F64i;
1439 c->Ico.F64i = f64i;
1440 return c;
1441 }
IRConst_V128(UShort con)1442 IRConst* IRConst_V128 ( UShort con )
1443 {
1444 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1445 c->tag = Ico_V128;
1446 c->Ico.V128 = con;
1447 return c;
1448 }
IRConst_V256(UInt con)1449 IRConst* IRConst_V256 ( UInt con )
1450 {
1451 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
1452 c->tag = Ico_V256;
1453 c->Ico.V256 = con;
1454 return c;
1455 }
1456
1457 /* Constructors -- IRCallee */
1458
mkIRCallee(Int regparms,HChar * name,void * addr)1459 IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr )
1460 {
1461 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
1462 ce->regparms = regparms;
1463 ce->name = name;
1464 ce->addr = addr;
1465 ce->mcx_mask = 0;
1466 vassert(regparms >= 0 && regparms <= 3);
1467 vassert(name != NULL);
1468 vassert(addr != 0);
1469 return ce;
1470 }
1471
1472
1473 /* Constructors -- IRRegArray */
1474
mkIRRegArray(Int base,IRType elemTy,Int nElems)1475 IRRegArray* mkIRRegArray ( Int base, IRType elemTy, Int nElems )
1476 {
1477 IRRegArray* arr = LibVEX_Alloc(sizeof(IRRegArray));
1478 arr->base = base;
1479 arr->elemTy = elemTy;
1480 arr->nElems = nElems;
1481 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
1482 vassert(!(arr->elemTy == Ity_I1));
1483 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
1484 return arr;
1485 }
1486
1487
1488 /* Constructors -- IRExpr */
1489
IRExpr_Binder(Int binder)1490 IRExpr* IRExpr_Binder ( Int binder ) {
1491 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1492 e->tag = Iex_Binder;
1493 e->Iex.Binder.binder = binder;
1494 return e;
1495 }
IRExpr_Get(Int off,IRType ty)1496 IRExpr* IRExpr_Get ( Int off, IRType ty ) {
1497 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1498 e->tag = Iex_Get;
1499 e->Iex.Get.offset = off;
1500 e->Iex.Get.ty = ty;
1501 return e;
1502 }
IRExpr_GetI(IRRegArray * descr,IRExpr * ix,Int bias)1503 IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ) {
1504 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1505 e->tag = Iex_GetI;
1506 e->Iex.GetI.descr = descr;
1507 e->Iex.GetI.ix = ix;
1508 e->Iex.GetI.bias = bias;
1509 return e;
1510 }
IRExpr_RdTmp(IRTemp tmp)1511 IRExpr* IRExpr_RdTmp ( IRTemp tmp ) {
1512 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1513 e->tag = Iex_RdTmp;
1514 e->Iex.RdTmp.tmp = tmp;
1515 return e;
1516 }
IRExpr_Qop(IROp op,IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4)1517 IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1518 IRExpr* arg3, IRExpr* arg4 ) {
1519 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1520 IRQop* qop = LibVEX_Alloc(sizeof(IRQop));
1521 qop->op = op;
1522 qop->arg1 = arg1;
1523 qop->arg2 = arg2;
1524 qop->arg3 = arg3;
1525 qop->arg4 = arg4;
1526 e->tag = Iex_Qop;
1527 e->Iex.Qop.details = qop;
1528 return e;
1529 }
IRExpr_Triop(IROp op,IRExpr * arg1,IRExpr * arg2,IRExpr * arg3)1530 IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1531 IRExpr* arg2, IRExpr* arg3 ) {
1532 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1533 IRTriop* triop = LibVEX_Alloc(sizeof(IRTriop));
1534 triop->op = op;
1535 triop->arg1 = arg1;
1536 triop->arg2 = arg2;
1537 triop->arg3 = arg3;
1538 e->tag = Iex_Triop;
1539 e->Iex.Triop.details = triop;
1540 return e;
1541 }
IRExpr_Binop(IROp op,IRExpr * arg1,IRExpr * arg2)1542 IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
1543 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1544 e->tag = Iex_Binop;
1545 e->Iex.Binop.op = op;
1546 e->Iex.Binop.arg1 = arg1;
1547 e->Iex.Binop.arg2 = arg2;
1548 return e;
1549 }
IRExpr_Unop(IROp op,IRExpr * arg)1550 IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
1551 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1552 e->tag = Iex_Unop;
1553 e->Iex.Unop.op = op;
1554 e->Iex.Unop.arg = arg;
1555 return e;
1556 }
IRExpr_Load(IREndness end,IRType ty,IRExpr * addr)1557 IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) {
1558 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1559 e->tag = Iex_Load;
1560 e->Iex.Load.end = end;
1561 e->Iex.Load.ty = ty;
1562 e->Iex.Load.addr = addr;
1563 vassert(end == Iend_LE || end == Iend_BE);
1564 return e;
1565 }
IRExpr_Const(IRConst * con)1566 IRExpr* IRExpr_Const ( IRConst* con ) {
1567 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1568 e->tag = Iex_Const;
1569 e->Iex.Const.con = con;
1570 return e;
1571 }
IRExpr_CCall(IRCallee * cee,IRType retty,IRExpr ** args)1572 IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
1573 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1574 e->tag = Iex_CCall;
1575 e->Iex.CCall.cee = cee;
1576 e->Iex.CCall.retty = retty;
1577 e->Iex.CCall.args = args;
1578 return e;
1579 }
IRExpr_Mux0X(IRExpr * cond,IRExpr * expr0,IRExpr * exprX)1580 IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
1581 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1582 e->tag = Iex_Mux0X;
1583 e->Iex.Mux0X.cond = cond;
1584 e->Iex.Mux0X.expr0 = expr0;
1585 e->Iex.Mux0X.exprX = exprX;
1586 return e;
1587 }
1588
1589
1590 /* Constructors for NULL-terminated IRExpr expression vectors,
1591 suitable for use as arg lists in clean/dirty helper calls. */
1592
mkIRExprVec_0(void)1593 IRExpr** mkIRExprVec_0 ( void ) {
1594 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
1595 vec[0] = NULL;
1596 return vec;
1597 }
mkIRExprVec_1(IRExpr * arg1)1598 IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
1599 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
1600 vec[0] = arg1;
1601 vec[1] = NULL;
1602 return vec;
1603 }
mkIRExprVec_2(IRExpr * arg1,IRExpr * arg2)1604 IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
1605 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
1606 vec[0] = arg1;
1607 vec[1] = arg2;
1608 vec[2] = NULL;
1609 return vec;
1610 }
mkIRExprVec_3(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3)1611 IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
1612 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
1613 vec[0] = arg1;
1614 vec[1] = arg2;
1615 vec[2] = arg3;
1616 vec[3] = NULL;
1617 return vec;
1618 }
mkIRExprVec_4(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4)1619 IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1620 IRExpr* arg4 ) {
1621 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
1622 vec[0] = arg1;
1623 vec[1] = arg2;
1624 vec[2] = arg3;
1625 vec[3] = arg4;
1626 vec[4] = NULL;
1627 return vec;
1628 }
mkIRExprVec_5(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4,IRExpr * arg5)1629 IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1630 IRExpr* arg4, IRExpr* arg5 ) {
1631 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
1632 vec[0] = arg1;
1633 vec[1] = arg2;
1634 vec[2] = arg3;
1635 vec[3] = arg4;
1636 vec[4] = arg5;
1637 vec[5] = NULL;
1638 return vec;
1639 }
mkIRExprVec_6(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4,IRExpr * arg5,IRExpr * arg6)1640 IRExpr** mkIRExprVec_6 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1641 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6 ) {
1642 IRExpr** vec = LibVEX_Alloc(7 * sizeof(IRExpr*));
1643 vec[0] = arg1;
1644 vec[1] = arg2;
1645 vec[2] = arg3;
1646 vec[3] = arg4;
1647 vec[4] = arg5;
1648 vec[5] = arg6;
1649 vec[6] = NULL;
1650 return vec;
1651 }
mkIRExprVec_7(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4,IRExpr * arg5,IRExpr * arg6,IRExpr * arg7)1652 IRExpr** mkIRExprVec_7 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1653 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6,
1654 IRExpr* arg7 ) {
1655 IRExpr** vec = LibVEX_Alloc(8 * sizeof(IRExpr*));
1656 vec[0] = arg1;
1657 vec[1] = arg2;
1658 vec[2] = arg3;
1659 vec[3] = arg4;
1660 vec[4] = arg5;
1661 vec[5] = arg6;
1662 vec[6] = arg7;
1663 vec[7] = NULL;
1664 return vec;
1665 }
mkIRExprVec_8(IRExpr * arg1,IRExpr * arg2,IRExpr * arg3,IRExpr * arg4,IRExpr * arg5,IRExpr * arg6,IRExpr * arg7,IRExpr * arg8)1666 IRExpr** mkIRExprVec_8 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1667 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6,
1668 IRExpr* arg7, IRExpr* arg8 ) {
1669 IRExpr** vec = LibVEX_Alloc(9 * sizeof(IRExpr*));
1670 vec[0] = arg1;
1671 vec[1] = arg2;
1672 vec[2] = arg3;
1673 vec[3] = arg4;
1674 vec[4] = arg5;
1675 vec[5] = arg6;
1676 vec[6] = arg7;
1677 vec[7] = arg8;
1678 vec[8] = NULL;
1679 return vec;
1680 }
1681
1682
1683 /* Constructors -- IRDirty */
1684
emptyIRDirty(void)1685 IRDirty* emptyIRDirty ( void ) {
1686 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
1687 d->cee = NULL;
1688 d->guard = NULL;
1689 d->args = NULL;
1690 d->tmp = IRTemp_INVALID;
1691 d->mFx = Ifx_None;
1692 d->mAddr = NULL;
1693 d->mSize = 0;
1694 d->needsBBP = False;
1695 d->nFxState = 0;
1696 return d;
1697 }
1698
1699
1700 /* Constructors -- IRCAS */
1701
mkIRCAS(IRTemp oldHi,IRTemp oldLo,IREndness end,IRExpr * addr,IRExpr * expdHi,IRExpr * expdLo,IRExpr * dataHi,IRExpr * dataLo)1702 IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1703 IREndness end, IRExpr* addr,
1704 IRExpr* expdHi, IRExpr* expdLo,
1705 IRExpr* dataHi, IRExpr* dataLo ) {
1706 IRCAS* cas = LibVEX_Alloc(sizeof(IRCAS));
1707 cas->oldHi = oldHi;
1708 cas->oldLo = oldLo;
1709 cas->end = end;
1710 cas->addr = addr;
1711 cas->expdHi = expdHi;
1712 cas->expdLo = expdLo;
1713 cas->dataHi = dataHi;
1714 cas->dataLo = dataLo;
1715 return cas;
1716 }
1717
1718
1719 /* Constructors -- IRPutI */
1720
mkIRPutI(IRRegArray * descr,IRExpr * ix,Int bias,IRExpr * data)1721 IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
1722 Int bias, IRExpr* data )
1723 {
1724 IRPutI* puti = LibVEX_Alloc(sizeof(IRPutI));
1725 puti->descr = descr;
1726 puti->ix = ix;
1727 puti->bias = bias;
1728 puti->data = data;
1729 return puti;
1730 }
1731
1732
1733 /* Constructors -- IRStmt */
1734
IRStmt_NoOp(void)1735 IRStmt* IRStmt_NoOp ( void )
1736 {
1737 /* Just use a single static closure. */
1738 static IRStmt static_closure;
1739 static_closure.tag = Ist_NoOp;
1740 return &static_closure;
1741 }
IRStmt_IMark(Addr64 addr,Int len,UChar delta)1742 IRStmt* IRStmt_IMark ( Addr64 addr, Int len, UChar delta ) {
1743 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1744 s->tag = Ist_IMark;
1745 s->Ist.IMark.addr = addr;
1746 s->Ist.IMark.len = len;
1747 s->Ist.IMark.delta = delta;
1748 return s;
1749 }
IRStmt_AbiHint(IRExpr * base,Int len,IRExpr * nia)1750 IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ) {
1751 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1752 s->tag = Ist_AbiHint;
1753 s->Ist.AbiHint.base = base;
1754 s->Ist.AbiHint.len = len;
1755 s->Ist.AbiHint.nia = nia;
1756 return s;
1757 }
IRStmt_Put(Int off,IRExpr * data)1758 IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
1759 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1760 s->tag = Ist_Put;
1761 s->Ist.Put.offset = off;
1762 s->Ist.Put.data = data;
1763 return s;
1764 }
IRStmt_PutI(IRPutI * details)1765 IRStmt* IRStmt_PutI ( IRPutI* details ) {
1766 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1767 s->tag = Ist_PutI;
1768 s->Ist.PutI.details = details;
1769 return s;
1770 }
IRStmt_WrTmp(IRTemp tmp,IRExpr * data)1771 IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ) {
1772 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1773 s->tag = Ist_WrTmp;
1774 s->Ist.WrTmp.tmp = tmp;
1775 s->Ist.WrTmp.data = data;
1776 return s;
1777 }
IRStmt_Store(IREndness end,IRExpr * addr,IRExpr * data)1778 IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) {
1779 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1780 s->tag = Ist_Store;
1781 s->Ist.Store.end = end;
1782 s->Ist.Store.addr = addr;
1783 s->Ist.Store.data = data;
1784 vassert(end == Iend_LE || end == Iend_BE);
1785 return s;
1786 }
IRStmt_CAS(IRCAS * cas)1787 IRStmt* IRStmt_CAS ( IRCAS* cas ) {
1788 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1789 s->tag = Ist_CAS;
1790 s->Ist.CAS.details = cas;
1791 return s;
1792 }
IRStmt_LLSC(IREndness end,IRTemp result,IRExpr * addr,IRExpr * storedata)1793 IRStmt* IRStmt_LLSC ( IREndness end,
1794 IRTemp result, IRExpr* addr, IRExpr* storedata ) {
1795 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1796 s->tag = Ist_LLSC;
1797 s->Ist.LLSC.end = end;
1798 s->Ist.LLSC.result = result;
1799 s->Ist.LLSC.addr = addr;
1800 s->Ist.LLSC.storedata = storedata;
1801 return s;
1802 }
IRStmt_Dirty(IRDirty * d)1803 IRStmt* IRStmt_Dirty ( IRDirty* d )
1804 {
1805 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1806 s->tag = Ist_Dirty;
1807 s->Ist.Dirty.details = d;
1808 return s;
1809 }
IRStmt_MBE(IRMBusEvent event)1810 IRStmt* IRStmt_MBE ( IRMBusEvent event )
1811 {
1812 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1813 s->tag = Ist_MBE;
1814 s->Ist.MBE.event = event;
1815 return s;
1816 }
IRStmt_Exit(IRExpr * guard,IRJumpKind jk,IRConst * dst,Int offsIP)1817 IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
1818 Int offsIP ) {
1819 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1820 s->tag = Ist_Exit;
1821 s->Ist.Exit.guard = guard;
1822 s->Ist.Exit.jk = jk;
1823 s->Ist.Exit.dst = dst;
1824 s->Ist.Exit.offsIP = offsIP;
1825 return s;
1826 }
1827
1828
1829 /* Constructors -- IRTypeEnv */
1830
emptyIRTypeEnv(void)1831 IRTypeEnv* emptyIRTypeEnv ( void )
1832 {
1833 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
1834 env->types = LibVEX_Alloc(8 * sizeof(IRType));
1835 env->types_size = 8;
1836 env->types_used = 0;
1837 return env;
1838 }
1839
1840
1841 /* Constructors -- IRSB */
1842
emptyIRSB(void)1843 IRSB* emptyIRSB ( void )
1844 {
1845 IRSB* bb = LibVEX_Alloc(sizeof(IRSB));
1846 bb->tyenv = emptyIRTypeEnv();
1847 bb->stmts_used = 0;
1848 bb->stmts_size = 8;
1849 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
1850 bb->next = NULL;
1851 bb->jumpkind = Ijk_Boring;
1852 bb->offsIP = 0;
1853 return bb;
1854 }
1855
1856
1857 /*---------------------------------------------------------------*/
1858 /*--- (Deep) copy constructors. These make complete copies ---*/
1859 /*--- the original, which can be modified without affecting ---*/
1860 /*--- the original. ---*/
1861 /*---------------------------------------------------------------*/
1862
1863 /* Copying IR Expr vectors (for call args). */
1864
1865 /* Shallow copy of an IRExpr vector */
1866
shallowCopyIRExprVec(IRExpr ** vec)1867 IRExpr** shallowCopyIRExprVec ( IRExpr** vec )
1868 {
1869 Int i;
1870 IRExpr** newvec;
1871 for (i = 0; vec[i]; i++)
1872 ;
1873 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
1874 for (i = 0; vec[i]; i++)
1875 newvec[i] = vec[i];
1876 newvec[i] = NULL;
1877 return newvec;
1878 }
1879
1880 /* Deep copy of an IRExpr vector */
1881
deepCopyIRExprVec(IRExpr ** vec)1882 IRExpr** deepCopyIRExprVec ( IRExpr** vec )
1883 {
1884 Int i;
1885 IRExpr** newvec = shallowCopyIRExprVec( vec );
1886 for (i = 0; newvec[i]; i++)
1887 newvec[i] = deepCopyIRExpr(newvec[i]);
1888 return newvec;
1889 }
1890
1891 /* Deep copy constructors for all heap-allocated IR types follow. */
1892
deepCopyIRConst(IRConst * c)1893 IRConst* deepCopyIRConst ( IRConst* c )
1894 {
1895 switch (c->tag) {
1896 case Ico_U1: return IRConst_U1(c->Ico.U1);
1897 case Ico_U8: return IRConst_U8(c->Ico.U8);
1898 case Ico_U16: return IRConst_U16(c->Ico.U16);
1899 case Ico_U32: return IRConst_U32(c->Ico.U32);
1900 case Ico_U64: return IRConst_U64(c->Ico.U64);
1901 case Ico_F32: return IRConst_F32(c->Ico.F32);
1902 case Ico_F32i: return IRConst_F32i(c->Ico.F32i);
1903 case Ico_F64: return IRConst_F64(c->Ico.F64);
1904 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
1905 case Ico_V128: return IRConst_V128(c->Ico.V128);
1906 default: vpanic("deepCopyIRConst");
1907 }
1908 }
1909
deepCopyIRCallee(IRCallee * ce)1910 IRCallee* deepCopyIRCallee ( IRCallee* ce )
1911 {
1912 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
1913 ce2->mcx_mask = ce->mcx_mask;
1914 return ce2;
1915 }
1916
deepCopyIRRegArray(IRRegArray * d)1917 IRRegArray* deepCopyIRRegArray ( IRRegArray* d )
1918 {
1919 return mkIRRegArray(d->base, d->elemTy, d->nElems);
1920 }
1921
deepCopyIRExpr(IRExpr * e)1922 IRExpr* deepCopyIRExpr ( IRExpr* e )
1923 {
1924 switch (e->tag) {
1925 case Iex_Get:
1926 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
1927 case Iex_GetI:
1928 return IRExpr_GetI(deepCopyIRRegArray(e->Iex.GetI.descr),
1929 deepCopyIRExpr(e->Iex.GetI.ix),
1930 e->Iex.GetI.bias);
1931 case Iex_RdTmp:
1932 return IRExpr_RdTmp(e->Iex.RdTmp.tmp);
1933 case Iex_Qop: {
1934 IRQop* qop = e->Iex.Qop.details;
1935
1936 return IRExpr_Qop(qop->op,
1937 deepCopyIRExpr(qop->arg1),
1938 deepCopyIRExpr(qop->arg2),
1939 deepCopyIRExpr(qop->arg3),
1940 deepCopyIRExpr(qop->arg4));
1941 }
1942 case Iex_Triop: {
1943 IRTriop *triop = e->Iex.Triop.details;
1944
1945 return IRExpr_Triop(triop->op,
1946 deepCopyIRExpr(triop->arg1),
1947 deepCopyIRExpr(triop->arg2),
1948 deepCopyIRExpr(triop->arg3));
1949 }
1950 case Iex_Binop:
1951 return IRExpr_Binop(e->Iex.Binop.op,
1952 deepCopyIRExpr(e->Iex.Binop.arg1),
1953 deepCopyIRExpr(e->Iex.Binop.arg2));
1954 case Iex_Unop:
1955 return IRExpr_Unop(e->Iex.Unop.op,
1956 deepCopyIRExpr(e->Iex.Unop.arg));
1957 case Iex_Load:
1958 return IRExpr_Load(e->Iex.Load.end,
1959 e->Iex.Load.ty,
1960 deepCopyIRExpr(e->Iex.Load.addr));
1961 case Iex_Const:
1962 return IRExpr_Const(deepCopyIRConst(e->Iex.Const.con));
1963 case Iex_CCall:
1964 return IRExpr_CCall(deepCopyIRCallee(e->Iex.CCall.cee),
1965 e->Iex.CCall.retty,
1966 deepCopyIRExprVec(e->Iex.CCall.args));
1967
1968 case Iex_Mux0X:
1969 return IRExpr_Mux0X(deepCopyIRExpr(e->Iex.Mux0X.cond),
1970 deepCopyIRExpr(e->Iex.Mux0X.expr0),
1971 deepCopyIRExpr(e->Iex.Mux0X.exprX));
1972 default:
1973 vpanic("deepCopyIRExpr");
1974 }
1975 }
1976
deepCopyIRDirty(IRDirty * d)1977 IRDirty* deepCopyIRDirty ( IRDirty* d )
1978 {
1979 Int i;
1980 IRDirty* d2 = emptyIRDirty();
1981 d2->cee = deepCopyIRCallee(d->cee);
1982 d2->guard = deepCopyIRExpr(d->guard);
1983 d2->args = deepCopyIRExprVec(d->args);
1984 d2->tmp = d->tmp;
1985 d2->mFx = d->mFx;
1986 d2->mAddr = d->mAddr==NULL ? NULL : deepCopyIRExpr(d->mAddr);
1987 d2->mSize = d->mSize;
1988 d2->needsBBP = d->needsBBP;
1989 d2->nFxState = d->nFxState;
1990 for (i = 0; i < d2->nFxState; i++)
1991 d2->fxState[i] = d->fxState[i];
1992 return d2;
1993 }
1994
deepCopyIRCAS(IRCAS * cas)1995 IRCAS* deepCopyIRCAS ( IRCAS* cas )
1996 {
1997 return mkIRCAS( cas->oldHi, cas->oldLo, cas->end,
1998 deepCopyIRExpr(cas->addr),
1999 cas->expdHi==NULL ? NULL : deepCopyIRExpr(cas->expdHi),
2000 deepCopyIRExpr(cas->expdLo),
2001 cas->dataHi==NULL ? NULL : deepCopyIRExpr(cas->dataHi),
2002 deepCopyIRExpr(cas->dataLo) );
2003 }
2004
deepCopyIRPutI(IRPutI * puti)2005 IRPutI* deepCopyIRPutI ( IRPutI * puti )
2006 {
2007 return mkIRPutI( deepCopyIRRegArray(puti->descr),
2008 deepCopyIRExpr(puti->ix),
2009 puti->bias,
2010 deepCopyIRExpr(puti->data));
2011 }
2012
deepCopyIRStmt(IRStmt * s)2013 IRStmt* deepCopyIRStmt ( IRStmt* s )
2014 {
2015 switch (s->tag) {
2016 case Ist_NoOp:
2017 return IRStmt_NoOp();
2018 case Ist_AbiHint:
2019 return IRStmt_AbiHint(deepCopyIRExpr(s->Ist.AbiHint.base),
2020 s->Ist.AbiHint.len,
2021 deepCopyIRExpr(s->Ist.AbiHint.nia));
2022 case Ist_IMark:
2023 return IRStmt_IMark(s->Ist.IMark.addr,
2024 s->Ist.IMark.len,
2025 s->Ist.IMark.delta);
2026 case Ist_Put:
2027 return IRStmt_Put(s->Ist.Put.offset,
2028 deepCopyIRExpr(s->Ist.Put.data));
2029 case Ist_PutI:
2030 return IRStmt_PutI(deepCopyIRPutI(s->Ist.PutI.details));
2031 case Ist_WrTmp:
2032 return IRStmt_WrTmp(s->Ist.WrTmp.tmp,
2033 deepCopyIRExpr(s->Ist.WrTmp.data));
2034 case Ist_Store:
2035 return IRStmt_Store(s->Ist.Store.end,
2036 deepCopyIRExpr(s->Ist.Store.addr),
2037 deepCopyIRExpr(s->Ist.Store.data));
2038 case Ist_CAS:
2039 return IRStmt_CAS(deepCopyIRCAS(s->Ist.CAS.details));
2040 case Ist_LLSC:
2041 return IRStmt_LLSC(s->Ist.LLSC.end,
2042 s->Ist.LLSC.result,
2043 deepCopyIRExpr(s->Ist.LLSC.addr),
2044 s->Ist.LLSC.storedata
2045 ? deepCopyIRExpr(s->Ist.LLSC.storedata)
2046 : NULL);
2047 case Ist_Dirty:
2048 return IRStmt_Dirty(deepCopyIRDirty(s->Ist.Dirty.details));
2049 case Ist_MBE:
2050 return IRStmt_MBE(s->Ist.MBE.event);
2051 case Ist_Exit:
2052 return IRStmt_Exit(deepCopyIRExpr(s->Ist.Exit.guard),
2053 s->Ist.Exit.jk,
2054 deepCopyIRConst(s->Ist.Exit.dst),
2055 s->Ist.Exit.offsIP);
2056 default:
2057 vpanic("deepCopyIRStmt");
2058 }
2059 }
2060
deepCopyIRTypeEnv(IRTypeEnv * src)2061 IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* src )
2062 {
2063 Int i;
2064 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
2065 dst->types_size = src->types_size;
2066 dst->types_used = src->types_used;
2067 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
2068 for (i = 0; i < src->types_used; i++)
2069 dst->types[i] = src->types[i];
2070 return dst;
2071 }
2072
deepCopyIRSB(IRSB * bb)2073 IRSB* deepCopyIRSB ( IRSB* bb )
2074 {
2075 Int i;
2076 IRStmt** sts2;
2077 IRSB* bb2 = deepCopyIRSBExceptStmts(bb);
2078 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
2079 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
2080 for (i = 0; i < bb2->stmts_used; i++)
2081 sts2[i] = deepCopyIRStmt(bb->stmts[i]);
2082 bb2->stmts = sts2;
2083 return bb2;
2084 }
2085
deepCopyIRSBExceptStmts(IRSB * bb)2086 IRSB* deepCopyIRSBExceptStmts ( IRSB* bb )
2087 {
2088 IRSB* bb2 = emptyIRSB();
2089 bb2->tyenv = deepCopyIRTypeEnv(bb->tyenv);
2090 bb2->next = deepCopyIRExpr(bb->next);
2091 bb2->jumpkind = bb->jumpkind;
2092 bb2->offsIP = bb->offsIP;
2093 return bb2;
2094 }
2095
2096
2097 /*---------------------------------------------------------------*/
2098 /*--- Primop types ---*/
2099 /*---------------------------------------------------------------*/
2100
2101 static
typeOfPrimop(IROp op,IRType * t_dst,IRType * t_arg1,IRType * t_arg2,IRType * t_arg3,IRType * t_arg4)2102 void typeOfPrimop ( IROp op,
2103 /*OUTs*/
2104 IRType* t_dst,
2105 IRType* t_arg1, IRType* t_arg2,
2106 IRType* t_arg3, IRType* t_arg4 )
2107 {
2108 # define UNARY(_ta1,_td) \
2109 *t_dst = (_td); *t_arg1 = (_ta1); break
2110 # define BINARY(_ta1,_ta2,_td) \
2111 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
2112 # define TERNARY(_ta1,_ta2,_ta3,_td) \
2113 *t_dst = (_td); *t_arg1 = (_ta1); \
2114 *t_arg2 = (_ta2); *t_arg3 = (_ta3); break
2115 # define QUATERNARY(_ta1,_ta2,_ta3,_ta4,_td) \
2116 *t_dst = (_td); *t_arg1 = (_ta1); \
2117 *t_arg2 = (_ta2); *t_arg3 = (_ta3); \
2118 *t_arg4 = (_ta4); break
2119 # define COMPARISON(_ta) \
2120 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
2121 # define UNARY_COMPARISON(_ta) \
2122 *t_dst = Ity_I1; *t_arg1 = (_ta); break;
2123
2124 /* Rounding mode values are always Ity_I32, encoded as per
2125 IRRoundingMode */
2126 const IRType ity_RMode = Ity_I32;
2127
2128 *t_dst = Ity_INVALID;
2129 *t_arg1 = Ity_INVALID;
2130 *t_arg2 = Ity_INVALID;
2131 *t_arg3 = Ity_INVALID;
2132 *t_arg4 = Ity_INVALID;
2133 switch (op) {
2134 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
2135 case Iop_Or8: case Iop_And8: case Iop_Xor8:
2136 BINARY(Ity_I8,Ity_I8, Ity_I8);
2137
2138 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
2139 case Iop_Or16: case Iop_And16: case Iop_Xor16:
2140 BINARY(Ity_I16,Ity_I16, Ity_I16);
2141
2142 case Iop_CmpORD32U:
2143 case Iop_CmpORD32S:
2144 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
2145 case Iop_Or32: case Iop_And32: case Iop_Xor32:
2146 case Iop_Max32U:
2147 case Iop_QAdd32S: case Iop_QSub32S:
2148 case Iop_Add16x2: case Iop_Sub16x2:
2149 case Iop_QAdd16Sx2: case Iop_QAdd16Ux2:
2150 case Iop_QSub16Sx2: case Iop_QSub16Ux2:
2151 case Iop_HAdd16Ux2: case Iop_HAdd16Sx2:
2152 case Iop_HSub16Ux2: case Iop_HSub16Sx2:
2153 case Iop_Add8x4: case Iop_Sub8x4:
2154 case Iop_QAdd8Sx4: case Iop_QAdd8Ux4:
2155 case Iop_QSub8Sx4: case Iop_QSub8Ux4:
2156 case Iop_HAdd8Ux4: case Iop_HAdd8Sx4:
2157 case Iop_HSub8Ux4: case Iop_HSub8Sx4:
2158 case Iop_Sad8Ux4:
2159 BINARY(Ity_I32,Ity_I32, Ity_I32);
2160
2161 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
2162 case Iop_Or64: case Iop_And64: case Iop_Xor64:
2163 case Iop_CmpORD64U:
2164 case Iop_CmpORD64S:
2165 case Iop_Avg8Ux8: case Iop_Avg16Ux4:
2166 case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2:
2167 case Iop_Add32Fx2: case Iop_Sub32Fx2:
2168 case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2:
2169 case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2:
2170 case Iop_CmpGT8Ux8: case Iop_CmpGT16Ux4: case Iop_CmpGT32Ux2:
2171 case Iop_CmpGT32Fx2: case Iop_CmpEQ32Fx2: case Iop_CmpGE32Fx2:
2172 case Iop_InterleaveHI8x8: case Iop_InterleaveLO8x8:
2173 case Iop_InterleaveHI16x4: case Iop_InterleaveLO16x4:
2174 case Iop_InterleaveHI32x2: case Iop_InterleaveLO32x2:
2175 case Iop_CatOddLanes8x8: case Iop_CatEvenLanes8x8:
2176 case Iop_CatOddLanes16x4: case Iop_CatEvenLanes16x4:
2177 case Iop_InterleaveOddLanes8x8: case Iop_InterleaveEvenLanes8x8:
2178 case Iop_InterleaveOddLanes16x4: case Iop_InterleaveEvenLanes16x4:
2179 case Iop_Perm8x8:
2180 case Iop_Max8Ux8: case Iop_Max16Ux4: case Iop_Max32Ux2:
2181 case Iop_Max8Sx8: case Iop_Max16Sx4: case Iop_Max32Sx2:
2182 case Iop_Max32Fx2: case Iop_Min32Fx2:
2183 case Iop_PwMax32Fx2: case Iop_PwMin32Fx2:
2184 case Iop_Min8Ux8: case Iop_Min16Ux4: case Iop_Min32Ux2:
2185 case Iop_Min8Sx8: case Iop_Min16Sx4: case Iop_Min32Sx2:
2186 case Iop_PwMax8Ux8: case Iop_PwMax16Ux4: case Iop_PwMax32Ux2:
2187 case Iop_PwMax8Sx8: case Iop_PwMax16Sx4: case Iop_PwMax32Sx2:
2188 case Iop_PwMin8Ux8: case Iop_PwMin16Ux4: case Iop_PwMin32Ux2:
2189 case Iop_PwMin8Sx8: case Iop_PwMin16Sx4: case Iop_PwMin32Sx2:
2190 case Iop_Mul8x8: case Iop_Mul16x4: case Iop_Mul32x2:
2191 case Iop_Mul32Fx2:
2192 case Iop_PolynomialMul8x8:
2193 case Iop_MulHi16Sx4: case Iop_MulHi16Ux4:
2194 case Iop_QDMulHi16Sx4: case Iop_QDMulHi32Sx2:
2195 case Iop_QRDMulHi16Sx4: case Iop_QRDMulHi32Sx2:
2196 case Iop_QAdd8Sx8: case Iop_QAdd16Sx4:
2197 case Iop_QAdd32Sx2: case Iop_QAdd64Sx1:
2198 case Iop_QAdd8Ux8: case Iop_QAdd16Ux4:
2199 case Iop_QAdd32Ux2: case Iop_QAdd64Ux1:
2200 case Iop_PwAdd8x8: case Iop_PwAdd16x4: case Iop_PwAdd32x2:
2201 case Iop_PwAdd32Fx2:
2202 case Iop_QNarrowBin32Sto16Sx4:
2203 case Iop_QNarrowBin16Sto8Sx8: case Iop_QNarrowBin16Sto8Ux8:
2204 case Iop_NarrowBin16to8x8: case Iop_NarrowBin32to16x4:
2205 case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2:
2206 case Iop_QSub8Sx8: case Iop_QSub16Sx4:
2207 case Iop_QSub32Sx2: case Iop_QSub64Sx1:
2208 case Iop_QSub8Ux8: case Iop_QSub16Ux4:
2209 case Iop_QSub32Ux2: case Iop_QSub64Ux1:
2210 case Iop_Shl8x8: case Iop_Shl16x4: case Iop_Shl32x2:
2211 case Iop_Shr8x8: case Iop_Shr16x4: case Iop_Shr32x2:
2212 case Iop_Sar8x8: case Iop_Sar16x4: case Iop_Sar32x2:
2213 case Iop_Sal8x8: case Iop_Sal16x4: case Iop_Sal32x2: case Iop_Sal64x1:
2214 case Iop_QShl8x8: case Iop_QShl16x4: case Iop_QShl32x2: case Iop_QShl64x1:
2215 case Iop_QSal8x8: case Iop_QSal16x4: case Iop_QSal32x2: case Iop_QSal64x1:
2216 case Iop_Recps32Fx2:
2217 case Iop_Rsqrts32Fx2:
2218 BINARY(Ity_I64,Ity_I64, Ity_I64);
2219
2220 case Iop_ShlN32x2: case Iop_ShlN16x4: case Iop_ShlN8x8:
2221 case Iop_ShrN32x2: case Iop_ShrN16x4: case Iop_ShrN8x8:
2222 case Iop_SarN32x2: case Iop_SarN16x4: case Iop_SarN8x8:
2223 case Iop_QShlN8x8: case Iop_QShlN16x4:
2224 case Iop_QShlN32x2: case Iop_QShlN64x1:
2225 case Iop_QShlN8Sx8: case Iop_QShlN16Sx4:
2226 case Iop_QShlN32Sx2: case Iop_QShlN64Sx1:
2227 case Iop_QSalN8x8: case Iop_QSalN16x4:
2228 case Iop_QSalN32x2: case Iop_QSalN64x1:
2229 BINARY(Ity_I64,Ity_I8, Ity_I64);
2230
2231 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
2232 BINARY(Ity_I8,Ity_I8, Ity_I8);
2233 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
2234 BINARY(Ity_I16,Ity_I8, Ity_I16);
2235 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
2236 BINARY(Ity_I32,Ity_I8, Ity_I32);
2237 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
2238 BINARY(Ity_I64,Ity_I8, Ity_I64);
2239
2240 case Iop_Not8:
2241 UNARY(Ity_I8, Ity_I8);
2242 case Iop_Not16:
2243 UNARY(Ity_I16, Ity_I16);
2244 case Iop_Not32:
2245 case Iop_CmpNEZ16x2: case Iop_CmpNEZ8x4:
2246 UNARY(Ity_I32, Ity_I32);
2247
2248 case Iop_Not64:
2249 case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8:
2250 case Iop_Cnt8x8:
2251 case Iop_Clz8Sx8: case Iop_Clz16Sx4: case Iop_Clz32Sx2:
2252 case Iop_Cls8Sx8: case Iop_Cls16Sx4: case Iop_Cls32Sx2:
2253 case Iop_PwAddL8Ux8: case Iop_PwAddL16Ux4: case Iop_PwAddL32Ux2:
2254 case Iop_PwAddL8Sx8: case Iop_PwAddL16Sx4: case Iop_PwAddL32Sx2:
2255 case Iop_Reverse64_8x8: case Iop_Reverse64_16x4: case Iop_Reverse64_32x2:
2256 case Iop_Reverse32_8x8: case Iop_Reverse32_16x4:
2257 case Iop_Reverse16_8x8:
2258 case Iop_FtoI32Sx2_RZ: case Iop_FtoI32Ux2_RZ:
2259 case Iop_I32StoFx2: case Iop_I32UtoFx2:
2260 case Iop_Recip32x2: case Iop_Recip32Fx2:
2261 case Iop_Abs32Fx2:
2262 case Iop_Rsqrte32Fx2:
2263 case Iop_Rsqrte32x2:
2264 case Iop_Neg32Fx2:
2265 case Iop_Abs8x8: case Iop_Abs16x4: case Iop_Abs32x2:
2266 UNARY(Ity_I64, Ity_I64);
2267
2268 case Iop_CmpEQ8: case Iop_CmpNE8:
2269 case Iop_CasCmpEQ8: case Iop_CasCmpNE8:
2270 COMPARISON(Ity_I8);
2271 case Iop_CmpEQ16: case Iop_CmpNE16:
2272 case Iop_CasCmpEQ16: case Iop_CasCmpNE16:
2273 COMPARISON(Ity_I16);
2274 case Iop_CmpEQ32: case Iop_CmpNE32:
2275 case Iop_CasCmpEQ32: case Iop_CasCmpNE32:
2276 case Iop_CmpLT32S: case Iop_CmpLE32S:
2277 case Iop_CmpLT32U: case Iop_CmpLE32U:
2278 COMPARISON(Ity_I32);
2279 case Iop_CmpEQ64: case Iop_CmpNE64:
2280 case Iop_CasCmpEQ64: case Iop_CasCmpNE64:
2281 case Iop_CmpLT64S: case Iop_CmpLE64S:
2282 case Iop_CmpLT64U: case Iop_CmpLE64U:
2283 COMPARISON(Ity_I64);
2284
2285 case Iop_CmpNEZ8: UNARY_COMPARISON(Ity_I8);
2286 case Iop_CmpNEZ16: UNARY_COMPARISON(Ity_I16);
2287 case Iop_CmpNEZ32: UNARY_COMPARISON(Ity_I32);
2288 case Iop_CmpNEZ64: UNARY_COMPARISON(Ity_I64);
2289
2290 case Iop_Left8: UNARY(Ity_I8, Ity_I8);
2291 case Iop_Left16: UNARY(Ity_I16,Ity_I16);
2292 case Iop_CmpwNEZ32: case Iop_Left32: UNARY(Ity_I32,Ity_I32);
2293 case Iop_CmpwNEZ64: case Iop_Left64: UNARY(Ity_I64,Ity_I64);
2294
2295 case Iop_MullU8: case Iop_MullS8:
2296 BINARY(Ity_I8,Ity_I8, Ity_I16);
2297 case Iop_MullU16: case Iop_MullS16:
2298 BINARY(Ity_I16,Ity_I16, Ity_I32);
2299 case Iop_MullU32: case Iop_MullS32:
2300 BINARY(Ity_I32,Ity_I32, Ity_I64);
2301 case Iop_MullU64: case Iop_MullS64:
2302 BINARY(Ity_I64,Ity_I64, Ity_I128);
2303
2304 case Iop_Clz32: case Iop_Ctz32:
2305 UNARY(Ity_I32, Ity_I32);
2306
2307 case Iop_Clz64: case Iop_Ctz64:
2308 UNARY(Ity_I64, Ity_I64);
2309
2310 case Iop_DivU32: case Iop_DivS32: case Iop_DivU32E: case Iop_DivS32E:
2311 BINARY(Ity_I32,Ity_I32, Ity_I32);
2312
2313 case Iop_DivU64: case Iop_DivS64: case Iop_DivS64E: case Iop_DivU64E:
2314 BINARY(Ity_I64,Ity_I64, Ity_I64);
2315
2316 case Iop_DivModU64to32: case Iop_DivModS64to32:
2317 BINARY(Ity_I64,Ity_I32, Ity_I64);
2318
2319 case Iop_DivModU128to64: case Iop_DivModS128to64:
2320 BINARY(Ity_I128,Ity_I64, Ity_I128);
2321
2322 case Iop_DivModS64to64:
2323 BINARY(Ity_I64,Ity_I64, Ity_I128);
2324
2325 case Iop_16HIto8: case Iop_16to8:
2326 UNARY(Ity_I16, Ity_I8);
2327 case Iop_8HLto16:
2328 BINARY(Ity_I8,Ity_I8, Ity_I16);
2329
2330 case Iop_32HIto16: case Iop_32to16:
2331 UNARY(Ity_I32, Ity_I16);
2332 case Iop_16HLto32:
2333 BINARY(Ity_I16,Ity_I16, Ity_I32);
2334
2335 case Iop_64HIto32: case Iop_64to32:
2336 UNARY(Ity_I64, Ity_I32);
2337 case Iop_32HLto64:
2338 BINARY(Ity_I32,Ity_I32, Ity_I64);
2339
2340 case Iop_128HIto64: case Iop_128to64:
2341 UNARY(Ity_I128, Ity_I64);
2342 case Iop_64HLto128:
2343 BINARY(Ity_I64,Ity_I64, Ity_I128);
2344
2345 case Iop_Not1: UNARY(Ity_I1, Ity_I1);
2346 case Iop_1Uto8: UNARY(Ity_I1, Ity_I8);
2347 case Iop_1Sto8: UNARY(Ity_I1, Ity_I8);
2348 case Iop_1Sto16: UNARY(Ity_I1, Ity_I16);
2349 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I1, Ity_I32);
2350 case Iop_1Sto64: case Iop_1Uto64: UNARY(Ity_I1, Ity_I64);
2351 case Iop_32to1: UNARY(Ity_I32, Ity_I1);
2352 case Iop_64to1: UNARY(Ity_I64, Ity_I1);
2353
2354 case Iop_8Uto32: case Iop_8Sto32:
2355 UNARY(Ity_I8, Ity_I32);
2356
2357 case Iop_8Uto16: case Iop_8Sto16:
2358 UNARY(Ity_I8, Ity_I16);
2359
2360 case Iop_16Uto32: case Iop_16Sto32:
2361 UNARY(Ity_I16, Ity_I32);
2362
2363 case Iop_32Sto64: case Iop_32Uto64:
2364 UNARY(Ity_I32, Ity_I64);
2365
2366 case Iop_8Uto64: case Iop_8Sto64:
2367 UNARY(Ity_I8, Ity_I64);
2368
2369 case Iop_16Uto64: case Iop_16Sto64:
2370 UNARY(Ity_I16, Ity_I64);
2371 case Iop_64to16:
2372 UNARY(Ity_I64, Ity_I16);
2373
2374 case Iop_32to8: UNARY(Ity_I32, Ity_I8);
2375 case Iop_64to8: UNARY(Ity_I64, Ity_I8);
2376
2377 case Iop_AddF64: case Iop_SubF64:
2378 case Iop_MulF64: case Iop_DivF64:
2379 case Iop_AddF64r32: case Iop_SubF64r32:
2380 case Iop_MulF64r32: case Iop_DivF64r32:
2381 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
2382
2383 case Iop_AddF32: case Iop_SubF32:
2384 case Iop_MulF32: case Iop_DivF32:
2385 TERNARY(ity_RMode,Ity_F32,Ity_F32, Ity_F32);
2386
2387 case Iop_NegF64: case Iop_AbsF64:
2388 UNARY(Ity_F64, Ity_F64);
2389
2390 case Iop_NegF32: case Iop_AbsF32:
2391 UNARY(Ity_F32, Ity_F32);
2392
2393 case Iop_SqrtF64:
2394 case Iop_SqrtF64r32:
2395 BINARY(ity_RMode,Ity_F64, Ity_F64);
2396
2397 case Iop_SqrtF32:
2398 case Iop_RoundF32toInt:
2399 BINARY(ity_RMode,Ity_F32, Ity_F32);
2400
2401 case Iop_CmpF32:
2402 BINARY(Ity_F32,Ity_F32, Ity_I32);
2403
2404 case Iop_CmpF64:
2405 BINARY(Ity_F64,Ity_F64, Ity_I32);
2406
2407 case Iop_CmpF128:
2408 BINARY(Ity_F128,Ity_F128, Ity_I32);
2409
2410 case Iop_F64toI16S: BINARY(ity_RMode,Ity_F64, Ity_I16);
2411 case Iop_F64toI32S: BINARY(ity_RMode,Ity_F64, Ity_I32);
2412 case Iop_F64toI64S: case Iop_F64toI64U:
2413 BINARY(ity_RMode,Ity_F64, Ity_I64);
2414
2415 case Iop_F64toI32U: BINARY(ity_RMode,Ity_F64, Ity_I32);
2416
2417 case Iop_I16StoF64: UNARY(Ity_I16, Ity_F64);
2418 case Iop_I32StoF64: UNARY(Ity_I32, Ity_F64);
2419 case Iop_I64StoF64: BINARY(ity_RMode,Ity_I64, Ity_F64);
2420 case Iop_I64UtoF64: BINARY(ity_RMode,Ity_I64, Ity_F64);
2421 case Iop_I64UtoF32: BINARY(ity_RMode,Ity_I64, Ity_F32);
2422
2423 case Iop_I32UtoF64: UNARY(Ity_I32, Ity_F64);
2424
2425 case Iop_F32toI16S: BINARY(ity_RMode,Ity_F32, Ity_I16);
2426 case Iop_F32toI32S: BINARY(ity_RMode,Ity_F32, Ity_I32);
2427 case Iop_F32toI64S: BINARY(ity_RMode,Ity_F32, Ity_I64);
2428
2429 case Iop_I16StoF32: UNARY(Ity_I16, Ity_F32);
2430 case Iop_I32StoF32: BINARY(ity_RMode,Ity_I32, Ity_F32);
2431 case Iop_I64StoF32: BINARY(ity_RMode,Ity_I64, Ity_F32);
2432
2433 case Iop_F32toF64: UNARY(Ity_F32, Ity_F64);
2434 case Iop_F64toF32: BINARY(ity_RMode,Ity_F64, Ity_F32);
2435
2436 case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64);
2437 case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64);
2438 case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32);
2439 case Iop_ReinterpF32asI32: UNARY(Ity_F32, Ity_I32);
2440
2441 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
2442 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
2443 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
2444
2445 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
2446 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_I32);
2447
2448 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64:
2449 case Iop_2xm1F64:
2450 case Iop_RoundF64toInt: BINARY(ity_RMode,Ity_F64, Ity_F64);
2451
2452 case Iop_MAddF64: case Iop_MSubF64:
2453 case Iop_MAddF64r32: case Iop_MSubF64r32:
2454 QUATERNARY(ity_RMode,Ity_F64,Ity_F64,Ity_F64, Ity_F64);
2455
2456 case Iop_Est5FRSqrt:
2457 case Iop_RoundF64toF64_NEAREST: case Iop_RoundF64toF64_NegINF:
2458 case Iop_RoundF64toF64_PosINF: case Iop_RoundF64toF64_ZERO:
2459 UNARY(Ity_F64, Ity_F64);
2460 case Iop_RoundF64toF32:
2461 BINARY(ity_RMode,Ity_F64, Ity_F64);
2462 case Iop_CalcFPRF:
2463 UNARY(Ity_F64, Ity_I32);
2464 case Iop_TruncF64asF32:
2465 UNARY(Ity_F64, Ity_F32);
2466
2467 case Iop_I32UtoFx4:
2468 case Iop_I32StoFx4:
2469 case Iop_QFtoI32Ux4_RZ:
2470 case Iop_QFtoI32Sx4_RZ:
2471 case Iop_FtoI32Ux4_RZ:
2472 case Iop_FtoI32Sx4_RZ:
2473 case Iop_RoundF32x4_RM:
2474 case Iop_RoundF32x4_RP:
2475 case Iop_RoundF32x4_RN:
2476 case Iop_RoundF32x4_RZ:
2477 case Iop_Abs32Fx4:
2478 case Iop_Rsqrte32Fx4:
2479 case Iop_Rsqrte32x4:
2480 UNARY(Ity_V128, Ity_V128);
2481
2482 case Iop_64HLtoV128:
2483 BINARY(Ity_I64,Ity_I64, Ity_V128);
2484
2485 case Iop_V128to64: case Iop_V128HIto64:
2486 case Iop_NarrowUn16to8x8:
2487 case Iop_NarrowUn32to16x4:
2488 case Iop_NarrowUn64to32x2:
2489 case Iop_QNarrowUn16Uto8Ux8:
2490 case Iop_QNarrowUn32Uto16Ux4:
2491 case Iop_QNarrowUn64Uto32Ux2:
2492 case Iop_QNarrowUn16Sto8Sx8:
2493 case Iop_QNarrowUn32Sto16Sx4:
2494 case Iop_QNarrowUn64Sto32Sx2:
2495 case Iop_QNarrowUn16Sto8Ux8:
2496 case Iop_QNarrowUn32Sto16Ux4:
2497 case Iop_QNarrowUn64Sto32Ux2:
2498 case Iop_F32toF16x4:
2499 UNARY(Ity_V128, Ity_I64);
2500
2501 case Iop_Widen8Uto16x8:
2502 case Iop_Widen16Uto32x4:
2503 case Iop_Widen32Uto64x2:
2504 case Iop_Widen8Sto16x8:
2505 case Iop_Widen16Sto32x4:
2506 case Iop_Widen32Sto64x2:
2507 case Iop_F16toF32x4:
2508 UNARY(Ity_I64, Ity_V128);
2509
2510 case Iop_V128to32: UNARY(Ity_V128, Ity_I32);
2511 case Iop_32UtoV128: UNARY(Ity_I32, Ity_V128);
2512 case Iop_64UtoV128: UNARY(Ity_I64, Ity_V128);
2513 case Iop_SetV128lo32: BINARY(Ity_V128,Ity_I32, Ity_V128);
2514 case Iop_SetV128lo64: BINARY(Ity_V128,Ity_I64, Ity_V128);
2515
2516 case Iop_Dup8x16: UNARY(Ity_I8, Ity_V128);
2517 case Iop_Dup16x8: UNARY(Ity_I16, Ity_V128);
2518 case Iop_Dup32x4: UNARY(Ity_I32, Ity_V128);
2519 case Iop_Dup8x8: UNARY(Ity_I8, Ity_I64);
2520 case Iop_Dup16x4: UNARY(Ity_I16, Ity_I64);
2521 case Iop_Dup32x2: UNARY(Ity_I32, Ity_I64);
2522
2523 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
2524 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
2525 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
2526 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
2527 case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4:
2528 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
2529 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
2530 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
2531 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
2532 case Iop_Add32Fx4: case Iop_Add32F0x4:
2533 case Iop_Add64Fx2: case Iop_Add64F0x2:
2534 case Iop_Div32Fx4: case Iop_Div32F0x4:
2535 case Iop_Div64Fx2: case Iop_Div64F0x2:
2536 case Iop_Max32Fx4: case Iop_Max32F0x4:
2537 case Iop_PwMax32Fx4: case Iop_PwMin32Fx4:
2538 case Iop_Max64Fx2: case Iop_Max64F0x2:
2539 case Iop_Min32Fx4: case Iop_Min32F0x4:
2540 case Iop_Min64Fx2: case Iop_Min64F0x2:
2541 case Iop_Mul32Fx4: case Iop_Mul32F0x4:
2542 case Iop_Mul64Fx2: case Iop_Mul64F0x2:
2543 case Iop_Sub32Fx4: case Iop_Sub32F0x4:
2544 case Iop_Sub64Fx2: case Iop_Sub64F0x2:
2545 case Iop_AndV128: case Iop_OrV128: case Iop_XorV128:
2546 case Iop_Add8x16: case Iop_Add16x8:
2547 case Iop_Add32x4: case Iop_Add64x2:
2548 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8:
2549 case Iop_QAdd32Ux4: //case Iop_QAdd64Ux2:
2550 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8:
2551 case Iop_QAdd32Sx4: case Iop_QAdd64Sx2:
2552 case Iop_PwAdd8x16: case Iop_PwAdd16x8: case Iop_PwAdd32x4:
2553 case Iop_Sub8x16: case Iop_Sub16x8:
2554 case Iop_Sub32x4: case Iop_Sub64x2:
2555 case Iop_QSub8Ux16: case Iop_QSub16Ux8:
2556 case Iop_QSub32Ux4: //case Iop_QSub64Ux2:
2557 case Iop_QSub8Sx16: case Iop_QSub16Sx8:
2558 case Iop_QSub32Sx4: case Iop_QSub64Sx2:
2559 case Iop_Mul8x16: case Iop_Mul16x8: case Iop_Mul32x4:
2560 case Iop_PolynomialMul8x16:
2561 case Iop_MulHi16Ux8: case Iop_MulHi32Ux4:
2562 case Iop_MulHi16Sx8: case Iop_MulHi32Sx4:
2563 case Iop_QDMulHi16Sx8: case Iop_QDMulHi32Sx4:
2564 case Iop_QRDMulHi16Sx8: case Iop_QRDMulHi32Sx4:
2565 case Iop_MullEven8Ux16: case Iop_MullEven16Ux8:
2566 case Iop_MullEven8Sx16: case Iop_MullEven16Sx8:
2567 case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4:
2568 case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4:
2569 case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4:
2570 case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4:
2571 case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4:
2572 case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4:
2573 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
2574 case Iop_CmpEQ64x2:
2575 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
2576 case Iop_CmpGT64Sx2:
2577 case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4:
2578 case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4: case Iop_Shl64x2:
2579 case Iop_QShl8x16: case Iop_QShl16x8:
2580 case Iop_QShl32x4: case Iop_QShl64x2:
2581 case Iop_QSal8x16: case Iop_QSal16x8:
2582 case Iop_QSal32x4: case Iop_QSal64x2:
2583 case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4: case Iop_Shr64x2:
2584 case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4: case Iop_Sar64x2:
2585 case Iop_Sal8x16: case Iop_Sal16x8: case Iop_Sal32x4: case Iop_Sal64x2:
2586 case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4:
2587 case Iop_QNarrowBin16Sto8Ux16: case Iop_QNarrowBin32Sto16Ux8:
2588 case Iop_QNarrowBin16Sto8Sx16: case Iop_QNarrowBin32Sto16Sx8:
2589 case Iop_QNarrowBin16Uto8Ux16: case Iop_QNarrowBin32Uto16Ux8:
2590 case Iop_NarrowBin16to8x16: case Iop_NarrowBin32to16x8:
2591 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
2592 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
2593 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
2594 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
2595 case Iop_CatOddLanes8x16: case Iop_CatEvenLanes8x16:
2596 case Iop_CatOddLanes16x8: case Iop_CatEvenLanes16x8:
2597 case Iop_CatOddLanes32x4: case Iop_CatEvenLanes32x4:
2598 case Iop_InterleaveOddLanes8x16: case Iop_InterleaveEvenLanes8x16:
2599 case Iop_InterleaveOddLanes16x8: case Iop_InterleaveEvenLanes16x8:
2600 case Iop_InterleaveOddLanes32x4: case Iop_InterleaveEvenLanes32x4:
2601 case Iop_Perm8x16: case Iop_Perm32x4:
2602 case Iop_Recps32Fx4:
2603 case Iop_Rsqrts32Fx4:
2604 BINARY(Ity_V128,Ity_V128, Ity_V128);
2605
2606 case Iop_PolynomialMull8x8:
2607 case Iop_Mull8Ux8: case Iop_Mull8Sx8:
2608 case Iop_Mull16Ux4: case Iop_Mull16Sx4:
2609 case Iop_Mull32Ux2: case Iop_Mull32Sx2:
2610 BINARY(Ity_I64, Ity_I64, Ity_V128);
2611
2612 case Iop_NotV128:
2613 case Iop_Recip32Fx4: case Iop_Recip32F0x4:
2614 case Iop_Recip32x4:
2615 case Iop_Recip64Fx2: case Iop_Recip64F0x2:
2616 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
2617 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
2618 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4:
2619 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2:
2620 case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8:
2621 case Iop_CmpNEZ32x4: case Iop_CmpNEZ64x2:
2622 case Iop_Cnt8x16:
2623 case Iop_Clz8Sx16: case Iop_Clz16Sx8: case Iop_Clz32Sx4:
2624 case Iop_Cls8Sx16: case Iop_Cls16Sx8: case Iop_Cls32Sx4:
2625 case Iop_PwAddL8Ux16: case Iop_PwAddL16Ux8: case Iop_PwAddL32Ux4:
2626 case Iop_PwAddL8Sx16: case Iop_PwAddL16Sx8: case Iop_PwAddL32Sx4:
2627 case Iop_Reverse64_8x16: case Iop_Reverse64_16x8: case Iop_Reverse64_32x4:
2628 case Iop_Reverse32_8x16: case Iop_Reverse32_16x8:
2629 case Iop_Reverse16_8x16:
2630 case Iop_Neg32Fx4:
2631 case Iop_Abs8x16: case Iop_Abs16x8: case Iop_Abs32x4:
2632 UNARY(Ity_V128, Ity_V128);
2633
2634 case Iop_ShlV128: case Iop_ShrV128:
2635 case Iop_ShlN8x16: case Iop_ShlN16x8:
2636 case Iop_ShlN32x4: case Iop_ShlN64x2:
2637 case Iop_ShrN8x16: case Iop_ShrN16x8:
2638 case Iop_ShrN32x4: case Iop_ShrN64x2:
2639 case Iop_SarN8x16: case Iop_SarN16x8:
2640 case Iop_SarN32x4: case Iop_SarN64x2:
2641 case Iop_QShlN8x16: case Iop_QShlN16x8:
2642 case Iop_QShlN32x4: case Iop_QShlN64x2:
2643 case Iop_QShlN8Sx16: case Iop_QShlN16Sx8:
2644 case Iop_QShlN32Sx4: case Iop_QShlN64Sx2:
2645 case Iop_QSalN8x16: case Iop_QSalN16x8:
2646 case Iop_QSalN32x4: case Iop_QSalN64x2:
2647 BINARY(Ity_V128,Ity_I8, Ity_V128);
2648
2649 case Iop_F32ToFixed32Ux4_RZ:
2650 case Iop_F32ToFixed32Sx4_RZ:
2651 case Iop_Fixed32UToF32x4_RN:
2652 case Iop_Fixed32SToF32x4_RN:
2653 BINARY(Ity_V128, Ity_I8, Ity_V128);
2654
2655 case Iop_F32ToFixed32Ux2_RZ:
2656 case Iop_F32ToFixed32Sx2_RZ:
2657 case Iop_Fixed32UToF32x2_RN:
2658 case Iop_Fixed32SToF32x2_RN:
2659 BINARY(Ity_I64, Ity_I8, Ity_I64);
2660
2661 case Iop_GetElem8x16:
2662 BINARY(Ity_V128, Ity_I8, Ity_I8);
2663 case Iop_GetElem16x8:
2664 BINARY(Ity_V128, Ity_I8, Ity_I16);
2665 case Iop_GetElem32x4:
2666 BINARY(Ity_V128, Ity_I8, Ity_I32);
2667 case Iop_GetElem64x2:
2668 BINARY(Ity_V128, Ity_I8, Ity_I64);
2669 case Iop_GetElem8x8:
2670 BINARY(Ity_I64, Ity_I8, Ity_I8);
2671 case Iop_GetElem16x4:
2672 BINARY(Ity_I64, Ity_I8, Ity_I16);
2673 case Iop_GetElem32x2:
2674 BINARY(Ity_I64, Ity_I8, Ity_I32);
2675 case Iop_SetElem8x8:
2676 TERNARY(Ity_I64, Ity_I8, Ity_I8, Ity_I64);
2677 case Iop_SetElem16x4:
2678 TERNARY(Ity_I64, Ity_I8, Ity_I16, Ity_I64);
2679 case Iop_SetElem32x2:
2680 TERNARY(Ity_I64, Ity_I8, Ity_I32, Ity_I64);
2681
2682 case Iop_Extract64:
2683 TERNARY(Ity_I64, Ity_I64, Ity_I8, Ity_I64);
2684 case Iop_ExtractV128:
2685 TERNARY(Ity_V128, Ity_V128, Ity_I8, Ity_V128);
2686
2687 case Iop_QDMulLong16Sx4: case Iop_QDMulLong32Sx2:
2688 BINARY(Ity_I64, Ity_I64, Ity_V128);
2689
2690 /* s390 specific */
2691 case Iop_MAddF32:
2692 case Iop_MSubF32:
2693 QUATERNARY(ity_RMode,Ity_F32,Ity_F32,Ity_F32, Ity_F32);
2694
2695 case Iop_F64HLtoF128:
2696 BINARY(Ity_F64,Ity_F64, Ity_F128);
2697
2698 case Iop_F128HItoF64:
2699 case Iop_F128LOtoF64:
2700 UNARY(Ity_F128, Ity_F64);
2701
2702 case Iop_AddF128:
2703 case Iop_SubF128:
2704 case Iop_MulF128:
2705 case Iop_DivF128:
2706 TERNARY(ity_RMode,Ity_F128,Ity_F128, Ity_F128);
2707
2708 case Iop_NegF128:
2709 case Iop_AbsF128:
2710 UNARY(Ity_F128, Ity_F128);
2711
2712 case Iop_SqrtF128:
2713 BINARY(ity_RMode,Ity_F128, Ity_F128);
2714
2715 case Iop_I32StoF128: UNARY(Ity_I32, Ity_F128);
2716 case Iop_I64StoF128: UNARY(Ity_I64, Ity_F128);
2717
2718 case Iop_F128toI32S: BINARY(ity_RMode,Ity_F128, Ity_I32);
2719 case Iop_F128toI64S: BINARY(ity_RMode,Ity_F128, Ity_I64);
2720
2721 case Iop_F32toF128: UNARY(Ity_F32, Ity_F128);
2722 case Iop_F64toF128: UNARY(Ity_F64, Ity_F128);
2723
2724 case Iop_F128toF32: BINARY(ity_RMode,Ity_F128, Ity_F32);
2725 case Iop_F128toF64: BINARY(ity_RMode,Ity_F128, Ity_F64);
2726
2727 case Iop_D32toD64:
2728 case Iop_ExtractExpD64:
2729 UNARY(Ity_D64, Ity_D64);
2730
2731 case Iop_InsertExpD64:
2732 BINARY(Ity_D64,Ity_D64, Ity_D64);
2733
2734 case Iop_ExtractExpD128:
2735 UNARY(Ity_D128, Ity_D64);
2736
2737 case Iop_InsertExpD128:
2738 BINARY(Ity_D64,Ity_D128, Ity_D128);
2739
2740 case Iop_D64toD128:
2741 UNARY(Ity_D64, Ity_D128);
2742
2743 case Iop_ReinterpD64asI64:
2744 UNARY(Ity_D64, Ity_I64);
2745
2746 case Iop_ReinterpI64asD64:
2747 UNARY(Ity_I64, Ity_D64);
2748
2749 case Iop_RoundD64toInt:
2750 BINARY(ity_RMode,Ity_D64, Ity_D64);
2751
2752 case Iop_RoundD128toInt:
2753 BINARY(ity_RMode,Ity_D128, Ity_D128);
2754
2755 case Iop_I64StoD128: /* I64 bit pattern stored in Float register */
2756 UNARY(Ity_D64, Ity_D128);
2757
2758 case Iop_DPBtoBCD:
2759 case Iop_BCDtoDPB:
2760 UNARY(Ity_I64, Ity_I64);
2761
2762 case Iop_D128HItoD64:
2763 case Iop_D128LOtoD64:
2764 UNARY(Ity_D128, Ity_D64);
2765
2766 case Iop_D128toI64S:
2767 BINARY(ity_RMode, Ity_D128, Ity_D64);
2768
2769 case Iop_D64HLtoD128:
2770 BINARY(Ity_D64, Ity_D64, Ity_D128);
2771
2772 case Iop_ShlD64:
2773 case Iop_ShrD64:
2774 BINARY(Ity_D64, Ity_I8, Ity_D64 );
2775
2776 case Iop_D64toD32:
2777 case Iop_D64toI64S:
2778 BINARY(ity_RMode, Ity_D64, Ity_D64);
2779
2780 case Iop_I64StoD64: /* I64 bit pattern stored in Float register */
2781 BINARY(ity_RMode, Ity_D64, Ity_D64);
2782
2783 case Iop_CmpD64:
2784 BINARY(Ity_D64,Ity_D64, Ity_I32);
2785
2786 case Iop_CmpD128:
2787 BINARY(Ity_D128,Ity_D128, Ity_I32);
2788
2789 case Iop_QuantizeD64:
2790 case Iop_SignificanceRoundD64:
2791 TERNARY(ity_RMode,Ity_D64,Ity_D64, Ity_D64);
2792
2793 case Iop_QuantizeD128:
2794 case Iop_SignificanceRoundD128:
2795 TERNARY(ity_RMode,Ity_D128,Ity_D128, Ity_D128);
2796
2797 case Iop_ShlD128:
2798 case Iop_ShrD128:
2799 BINARY(Ity_D128, Ity_I8, Ity_D128 );
2800
2801 case Iop_AddD64:
2802 case Iop_SubD64:
2803 case Iop_MulD64:
2804 case Iop_DivD64:
2805 TERNARY( ity_RMode, Ity_D64, Ity_D64, Ity_D64 );
2806
2807 case Iop_D128toD64:
2808 BINARY( ity_RMode, Ity_D128, Ity_D64 );
2809
2810 case Iop_AddD128:
2811 case Iop_SubD128:
2812 case Iop_MulD128:
2813 case Iop_DivD128:
2814 TERNARY(ity_RMode,Ity_D128,Ity_D128, Ity_D128);
2815
2816 case Iop_V256to64_0: case Iop_V256to64_1:
2817 case Iop_V256to64_2: case Iop_V256to64_3:
2818 UNARY(Ity_V256, Ity_I64);
2819
2820 case Iop_64x4toV256:
2821 QUATERNARY(Ity_I64, Ity_I64, Ity_I64, Ity_I64, Ity_V256);
2822
2823 case Iop_Add64Fx4: case Iop_Sub64Fx4:
2824 case Iop_Mul64Fx4: case Iop_Div64Fx4:
2825 case Iop_Add32Fx8: case Iop_Sub32Fx8:
2826 case Iop_Mul32Fx8: case Iop_Div32Fx8:
2827 case Iop_AndV256: case Iop_OrV256:
2828 case Iop_XorV256:
2829 case Iop_Max32Fx8: case Iop_Min32Fx8:
2830 case Iop_Max64Fx4: case Iop_Min64Fx4:
2831 BINARY(Ity_V256,Ity_V256, Ity_V256);
2832
2833 case Iop_V256toV128_1: case Iop_V256toV128_0:
2834 UNARY(Ity_V256, Ity_V128);
2835
2836 case Iop_V128HLtoV256:
2837 BINARY(Ity_V128,Ity_V128, Ity_V256);
2838
2839 case Iop_NotV256:
2840 case Iop_RSqrt32Fx8:
2841 case Iop_Sqrt32Fx8:
2842 case Iop_Sqrt64Fx4:
2843 case Iop_Recip32Fx8:
2844 case Iop_CmpNEZ64x4: case Iop_CmpNEZ32x8:
2845 UNARY(Ity_V256, Ity_V256);
2846
2847 default:
2848 ppIROp(op);
2849 vpanic("typeOfPrimop");
2850 }
2851 # undef UNARY
2852 # undef BINARY
2853 # undef TERNARY
2854 # undef COMPARISON
2855 # undef UNARY_COMPARISON
2856 }
2857
2858
2859 /*---------------------------------------------------------------*/
2860 /*--- Helper functions for the IR -- IR Basic Blocks ---*/
2861 /*---------------------------------------------------------------*/
2862
addStmtToIRSB(IRSB * bb,IRStmt * st)2863 void addStmtToIRSB ( IRSB* bb, IRStmt* st )
2864 {
2865 Int i;
2866 if (bb->stmts_used == bb->stmts_size) {
2867 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
2868 for (i = 0; i < bb->stmts_size; i++)
2869 stmts2[i] = bb->stmts[i];
2870 bb->stmts = stmts2;
2871 bb->stmts_size *= 2;
2872 }
2873 vassert(bb->stmts_used < bb->stmts_size);
2874 bb->stmts[bb->stmts_used] = st;
2875 bb->stmts_used++;
2876 }
2877
2878
2879 /*---------------------------------------------------------------*/
2880 /*--- Helper functions for the IR -- IR Type Environments ---*/
2881 /*---------------------------------------------------------------*/
2882
2883 /* Allocate a new IRTemp, given its type. */
2884
newIRTemp(IRTypeEnv * env,IRType ty)2885 IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
2886 {
2887 vassert(env);
2888 vassert(env->types_used >= 0);
2889 vassert(env->types_size >= 0);
2890 vassert(env->types_used <= env->types_size);
2891 if (env->types_used < env->types_size) {
2892 env->types[env->types_used] = ty;
2893 return env->types_used++;
2894 } else {
2895 Int i;
2896 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
2897 IRType* new_types
2898 = LibVEX_Alloc(new_size * sizeof(IRType));
2899 for (i = 0; i < env->types_used; i++)
2900 new_types[i] = env->types[i];
2901 env->types = new_types;
2902 env->types_size = new_size;
2903 return newIRTemp(env, ty);
2904 }
2905 }
2906
2907
2908 /*---------------------------------------------------------------*/
2909 /*--- Helper functions for the IR -- finding types of exprs ---*/
2910 /*---------------------------------------------------------------*/
2911
2912 inline
typeOfIRTemp(IRTypeEnv * env,IRTemp tmp)2913 IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
2914 {
2915 vassert(tmp >= 0);
2916 vassert(tmp < env->types_used);
2917 return env->types[tmp];
2918 }
2919
2920
typeOfIRConst(IRConst * con)2921 IRType typeOfIRConst ( IRConst* con )
2922 {
2923 switch (con->tag) {
2924 case Ico_U1: return Ity_I1;
2925 case Ico_U8: return Ity_I8;
2926 case Ico_U16: return Ity_I16;
2927 case Ico_U32: return Ity_I32;
2928 case Ico_U64: return Ity_I64;
2929 case Ico_F32: return Ity_F32;
2930 case Ico_F32i: return Ity_F32;
2931 case Ico_F64: return Ity_F64;
2932 case Ico_F64i: return Ity_F64;
2933 case Ico_V128: return Ity_V128;
2934 case Ico_V256: return Ity_V256;
2935 default: vpanic("typeOfIRConst");
2936 }
2937 }
2938
typeOfIRExpr(IRTypeEnv * tyenv,IRExpr * e)2939 IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
2940 {
2941 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
2942 start:
2943 switch (e->tag) {
2944 case Iex_Load:
2945 return e->Iex.Load.ty;
2946 case Iex_Get:
2947 return e->Iex.Get.ty;
2948 case Iex_GetI:
2949 return e->Iex.GetI.descr->elemTy;
2950 case Iex_RdTmp:
2951 return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp);
2952 case Iex_Const:
2953 return typeOfIRConst(e->Iex.Const.con);
2954 case Iex_Qop:
2955 typeOfPrimop(e->Iex.Qop.details->op,
2956 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2957 return t_dst;
2958 case Iex_Triop:
2959 typeOfPrimop(e->Iex.Triop.details->op,
2960 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2961 return t_dst;
2962 case Iex_Binop:
2963 typeOfPrimop(e->Iex.Binop.op,
2964 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2965 return t_dst;
2966 case Iex_Unop:
2967 typeOfPrimop(e->Iex.Unop.op,
2968 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2969 return t_dst;
2970 case Iex_CCall:
2971 return e->Iex.CCall.retty;
2972 case Iex_Mux0X:
2973 e = e->Iex.Mux0X.expr0;
2974 goto start;
2975 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
2976 case Iex_Binder:
2977 vpanic("typeOfIRExpr: Binder is not a valid expression");
2978 default:
2979 ppIRExpr(e);
2980 vpanic("typeOfIRExpr");
2981 }
2982 }
2983
2984 /* Is this any value actually in the enumeration 'IRType' ? */
isPlausibleIRType(IRType ty)2985 Bool isPlausibleIRType ( IRType ty )
2986 {
2987 switch (ty) {
2988 case Ity_INVALID: case Ity_I1:
2989 case Ity_I8: case Ity_I16: case Ity_I32:
2990 case Ity_I64: case Ity_I128:
2991 case Ity_F32: case Ity_F64: case Ity_F128:
2992 case Ity_D32: case Ity_D64: case Ity_D128:
2993 case Ity_V128: case Ity_V256:
2994 return True;
2995 default:
2996 return False;
2997 }
2998 }
2999
3000
3001 /*---------------------------------------------------------------*/
3002 /*--- Sanity checking -- FLATNESS ---*/
3003 /*---------------------------------------------------------------*/
3004
3005 /* Check that the canonical flatness constraints hold on an
3006 IRStmt. The only place where any expression is allowed to be
3007 non-atomic is the RHS of IRStmt_Tmp. */
3008
3009 /* Relies on:
3010 inline static Bool isAtom ( IRExpr* e ) {
3011 return e->tag == Iex_RdTmp || e->tag == Iex_Const;
3012 }
3013 */
3014
isFlatIRStmt(IRStmt * st)3015 Bool isFlatIRStmt ( IRStmt* st )
3016 {
3017 Int i;
3018 IRExpr* e;
3019 IRDirty* di;
3020 IRCAS* cas;
3021 IRPutI* puti;
3022 IRQop* qop;
3023 IRTriop* triop;
3024
3025 switch (st->tag) {
3026 case Ist_AbiHint:
3027 return isIRAtom(st->Ist.AbiHint.base)
3028 && isIRAtom(st->Ist.AbiHint.nia);
3029 case Ist_Put:
3030 return isIRAtom(st->Ist.Put.data);
3031 case Ist_PutI:
3032 puti = st->Ist.PutI.details;
3033 return toBool( isIRAtom(puti->ix)
3034 && isIRAtom(puti->data) );
3035 case Ist_WrTmp:
3036 /* This is the only interesting case. The RHS can be any
3037 expression, *but* all its subexpressions *must* be
3038 atoms. */
3039 e = st->Ist.WrTmp.data;
3040 switch (e->tag) {
3041 case Iex_Binder: return True;
3042 case Iex_Get: return True;
3043 case Iex_GetI: return isIRAtom(e->Iex.GetI.ix);
3044 case Iex_RdTmp: return True;
3045 case Iex_Qop: qop = e->Iex.Qop.details;
3046 return toBool(
3047 isIRAtom(qop->arg1)
3048 && isIRAtom(qop->arg2)
3049 && isIRAtom(qop->arg3)
3050 && isIRAtom(qop->arg4));
3051 case Iex_Triop: triop = e->Iex.Triop.details;
3052 return toBool(
3053 isIRAtom(triop->arg1)
3054 && isIRAtom(triop->arg2)
3055 && isIRAtom(triop->arg3));
3056 case Iex_Binop: return toBool(
3057 isIRAtom(e->Iex.Binop.arg1)
3058 && isIRAtom(e->Iex.Binop.arg2));
3059 case Iex_Unop: return isIRAtom(e->Iex.Unop.arg);
3060 case Iex_Load: return isIRAtom(e->Iex.Load.addr);
3061 case Iex_Const: return True;
3062 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
3063 if (!isIRAtom(e->Iex.CCall.args[i]))
3064 return False;
3065 return True;
3066 case Iex_Mux0X: return toBool (
3067 isIRAtom(e->Iex.Mux0X.cond)
3068 && isIRAtom(e->Iex.Mux0X.expr0)
3069 && isIRAtom(e->Iex.Mux0X.exprX));
3070 default: vpanic("isFlatIRStmt(e)");
3071 }
3072 /*notreached*/
3073 vassert(0);
3074 case Ist_Store:
3075 return toBool( isIRAtom(st->Ist.Store.addr)
3076 && isIRAtom(st->Ist.Store.data) );
3077 case Ist_CAS:
3078 cas = st->Ist.CAS.details;
3079 return toBool( isIRAtom(cas->addr)
3080 && (cas->expdHi ? isIRAtom(cas->expdHi) : True)
3081 && isIRAtom(cas->expdLo)
3082 && (cas->dataHi ? isIRAtom(cas->dataHi) : True)
3083 && isIRAtom(cas->dataLo) );
3084 case Ist_LLSC:
3085 return toBool( isIRAtom(st->Ist.LLSC.addr)
3086 && (st->Ist.LLSC.storedata
3087 ? isIRAtom(st->Ist.LLSC.storedata) : True) );
3088 case Ist_Dirty:
3089 di = st->Ist.Dirty.details;
3090 if (!isIRAtom(di->guard))
3091 return False;
3092 for (i = 0; di->args[i]; i++)
3093 if (!isIRAtom(di->args[i]))
3094 return False;
3095 if (di->mAddr && !isIRAtom(di->mAddr))
3096 return False;
3097 return True;
3098 case Ist_NoOp:
3099 case Ist_IMark:
3100 case Ist_MBE:
3101 return True;
3102 case Ist_Exit:
3103 return isIRAtom(st->Ist.Exit.guard);
3104 default:
3105 vpanic("isFlatIRStmt(st)");
3106 }
3107 }
3108
3109
3110 /*---------------------------------------------------------------*/
3111 /*--- Sanity checking ---*/
3112 /*---------------------------------------------------------------*/
3113
3114 /* Checks:
3115
3116 Everything is type-consistent. No ill-typed anything.
3117 The target address at the end of the BB is a 32- or 64-
3118 bit expression, depending on the guest's word size.
3119
3120 Each temp is assigned only once, before its uses.
3121 */
3122
countArgs(IRExpr ** args)3123 static inline Int countArgs ( IRExpr** args )
3124 {
3125 Int i;
3126 for (i = 0; args[i]; i++)
3127 ;
3128 return i;
3129 }
3130
3131 static
3132 __attribute((noreturn))
sanityCheckFail(IRSB * bb,IRStmt * stmt,HChar * what)3133 void sanityCheckFail ( IRSB* bb, IRStmt* stmt, HChar* what )
3134 {
3135 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
3136 ppIRSB(bb);
3137 if (stmt) {
3138 vex_printf("\nIN STATEMENT:\n\n");
3139 ppIRStmt(stmt);
3140 }
3141 vex_printf("\n\nERROR = %s\n\n", what );
3142 vpanic("sanityCheckFail: exiting due to bad IR");
3143 }
3144
saneIRRegArray(IRRegArray * arr)3145 static Bool saneIRRegArray ( IRRegArray* arr )
3146 {
3147 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
3148 return False;
3149 if (arr->elemTy == Ity_I1)
3150 return False;
3151 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
3152 return False;
3153 return True;
3154 }
3155
saneIRCallee(IRCallee * cee)3156 static Bool saneIRCallee ( IRCallee* cee )
3157 {
3158 if (cee->name == NULL)
3159 return False;
3160 if (cee->addr == 0)
3161 return False;
3162 if (cee->regparms < 0 || cee->regparms > 3)
3163 return False;
3164 return True;
3165 }
3166
saneIRConst(IRConst * con)3167 static Bool saneIRConst ( IRConst* con )
3168 {
3169 switch (con->tag) {
3170 case Ico_U1:
3171 return toBool( con->Ico.U1 == True || con->Ico.U1 == False );
3172 default:
3173 /* Is there anything we can meaningfully check? I don't
3174 think so. */
3175 return True;
3176 }
3177 }
3178
3179 /* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
3180 range ones. Report any which are read and for which the current
3181 def_count is zero. */
3182
3183 static
useBeforeDef_Temp(IRSB * bb,IRStmt * stmt,IRTemp tmp,Int * def_counts)3184 void useBeforeDef_Temp ( IRSB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
3185 {
3186 if (tmp < 0 || tmp >= bb->tyenv->types_used)
3187 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
3188 if (def_counts[tmp] < 1)
3189 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
3190 }
3191
3192 static
useBeforeDef_Expr(IRSB * bb,IRStmt * stmt,IRExpr * expr,Int * def_counts)3193 void useBeforeDef_Expr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
3194 {
3195 Int i;
3196 switch (expr->tag) {
3197 case Iex_Get:
3198 break;
3199 case Iex_GetI:
3200 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
3201 break;
3202 case Iex_RdTmp:
3203 useBeforeDef_Temp(bb,stmt,expr->Iex.RdTmp.tmp,def_counts);
3204 break;
3205 case Iex_Qop: {
3206 IRQop* qop = expr->Iex.Qop.details;
3207 useBeforeDef_Expr(bb,stmt,qop->arg1,def_counts);
3208 useBeforeDef_Expr(bb,stmt,qop->arg2,def_counts);
3209 useBeforeDef_Expr(bb,stmt,qop->arg3,def_counts);
3210 useBeforeDef_Expr(bb,stmt,qop->arg4,def_counts);
3211 break;
3212 }
3213 case Iex_Triop: {
3214 IRTriop* triop = expr->Iex.Triop.details;
3215 useBeforeDef_Expr(bb,stmt,triop->arg1,def_counts);
3216 useBeforeDef_Expr(bb,stmt,triop->arg2,def_counts);
3217 useBeforeDef_Expr(bb,stmt,triop->arg3,def_counts);
3218 break;
3219 }
3220 case Iex_Binop:
3221 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
3222 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
3223 break;
3224 case Iex_Unop:
3225 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
3226 break;
3227 case Iex_Load:
3228 useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
3229 break;
3230 case Iex_Const:
3231 break;
3232 case Iex_CCall:
3233 for (i = 0; expr->Iex.CCall.args[i]; i++)
3234 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
3235 break;
3236 case Iex_Mux0X:
3237 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
3238 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
3239 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
3240 break;
3241 default:
3242 vpanic("useBeforeDef_Expr");
3243 }
3244 }
3245
3246 static
useBeforeDef_Stmt(IRSB * bb,IRStmt * stmt,Int * def_counts)3247 void useBeforeDef_Stmt ( IRSB* bb, IRStmt* stmt, Int* def_counts )
3248 {
3249 Int i;
3250 IRDirty* d;
3251 IRCAS* cas;
3252 IRPutI* puti;
3253 switch (stmt->tag) {
3254 case Ist_IMark:
3255 break;
3256 case Ist_AbiHint:
3257 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
3258 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.nia,def_counts);
3259 break;
3260 case Ist_Put:
3261 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
3262 break;
3263 case Ist_PutI:
3264 puti = stmt->Ist.PutI.details;
3265 useBeforeDef_Expr(bb,stmt,puti->ix,def_counts);
3266 useBeforeDef_Expr(bb,stmt,puti->data,def_counts);
3267 break;
3268 case Ist_WrTmp:
3269 useBeforeDef_Expr(bb,stmt,stmt->Ist.WrTmp.data,def_counts);
3270 break;
3271 case Ist_Store:
3272 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
3273 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
3274 break;
3275 case Ist_CAS:
3276 cas = stmt->Ist.CAS.details;
3277 useBeforeDef_Expr(bb,stmt,cas->addr,def_counts);
3278 if (cas->expdHi)
3279 useBeforeDef_Expr(bb,stmt,cas->expdHi,def_counts);
3280 useBeforeDef_Expr(bb,stmt,cas->expdLo,def_counts);
3281 if (cas->dataHi)
3282 useBeforeDef_Expr(bb,stmt,cas->dataHi,def_counts);
3283 useBeforeDef_Expr(bb,stmt,cas->dataLo,def_counts);
3284 break;
3285 case Ist_LLSC:
3286 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.addr,def_counts);
3287 if (stmt->Ist.LLSC.storedata != NULL)
3288 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.storedata,def_counts);
3289 break;
3290 case Ist_Dirty:
3291 d = stmt->Ist.Dirty.details;
3292 for (i = 0; d->args[i] != NULL; i++)
3293 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
3294 if (d->mFx != Ifx_None)
3295 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
3296 break;
3297 case Ist_NoOp:
3298 case Ist_MBE:
3299 break;
3300 case Ist_Exit:
3301 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
3302 break;
3303 default:
3304 vpanic("useBeforeDef_Stmt");
3305 }
3306 }
3307
3308 static
tcExpr(IRSB * bb,IRStmt * stmt,IRExpr * expr,IRType gWordTy)3309 void tcExpr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
3310 {
3311 Int i;
3312 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
3313 IRTypeEnv* tyenv = bb->tyenv;
3314 switch (expr->tag) {
3315 case Iex_Get:
3316 case Iex_RdTmp:
3317 break;
3318 case Iex_GetI:
3319 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
3320 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
3321 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
3322 if (!saneIRRegArray(expr->Iex.GetI.descr))
3323 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
3324 break;
3325 case Iex_Qop: {
3326 IRType ttarg1, ttarg2, ttarg3, ttarg4;
3327 IRQop* qop = expr->Iex.Qop.details;
3328 tcExpr(bb,stmt, qop->arg1, gWordTy );
3329 tcExpr(bb,stmt, qop->arg2, gWordTy );
3330 tcExpr(bb,stmt, qop->arg3, gWordTy );
3331 tcExpr(bb,stmt, qop->arg4, gWordTy );
3332 typeOfPrimop(qop->op,
3333 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
3334 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
3335 || t_arg3 == Ity_INVALID || t_arg4 == Ity_INVALID) {
3336 vex_printf(" op name: " );
3337 ppIROp(qop->op);
3338 vex_printf("\n");
3339 sanityCheckFail(bb,stmt,
3340 "Iex.Qop: wrong arity op\n"
3341 "... name of op precedes BB printout\n");
3342 }
3343 ttarg1 = typeOfIRExpr(tyenv, qop->arg1);
3344 ttarg2 = typeOfIRExpr(tyenv, qop->arg2);
3345 ttarg3 = typeOfIRExpr(tyenv, qop->arg3);
3346 ttarg4 = typeOfIRExpr(tyenv, qop->arg4);
3347 if (t_arg1 != ttarg1 || t_arg2 != ttarg2
3348 || t_arg3 != ttarg3 || t_arg4 != ttarg4) {
3349 vex_printf(" op name: ");
3350 ppIROp(qop->op);
3351 vex_printf("\n");
3352 vex_printf(" op type is (");
3353 ppIRType(t_arg1);
3354 vex_printf(",");
3355 ppIRType(t_arg2);
3356 vex_printf(",");
3357 ppIRType(t_arg3);
3358 vex_printf(",");
3359 ppIRType(t_arg4);
3360 vex_printf(") -> ");
3361 ppIRType (t_dst);
3362 vex_printf("\narg tys are (");
3363 ppIRType(ttarg1);
3364 vex_printf(",");
3365 ppIRType(ttarg2);
3366 vex_printf(",");
3367 ppIRType(ttarg3);
3368 vex_printf(",");
3369 ppIRType(ttarg4);
3370 vex_printf(")\n");
3371 sanityCheckFail(bb,stmt,
3372 "Iex.Qop: arg tys don't match op tys\n"
3373 "... additional details precede BB printout\n");
3374 }
3375 break;
3376 }
3377 case Iex_Triop: {
3378 IRType ttarg1, ttarg2, ttarg3;
3379 IRTriop *triop = expr->Iex.Triop.details;
3380 tcExpr(bb,stmt, triop->arg1, gWordTy );
3381 tcExpr(bb,stmt, triop->arg2, gWordTy );
3382 tcExpr(bb,stmt, triop->arg3, gWordTy );
3383 typeOfPrimop(triop->op,
3384 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
3385 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
3386 || t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) {
3387 vex_printf(" op name: " );
3388 ppIROp(triop->op);
3389 vex_printf("\n");
3390 sanityCheckFail(bb,stmt,
3391 "Iex.Triop: wrong arity op\n"
3392 "... name of op precedes BB printout\n");
3393 }
3394 ttarg1 = typeOfIRExpr(tyenv, triop->arg1);
3395 ttarg2 = typeOfIRExpr(tyenv, triop->arg2);
3396 ttarg3 = typeOfIRExpr(tyenv, triop->arg3);
3397 if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
3398 vex_printf(" op name: ");
3399 ppIROp(triop->op);
3400 vex_printf("\n");
3401 vex_printf(" op type is (");
3402 ppIRType(t_arg1);
3403 vex_printf(",");
3404 ppIRType(t_arg2);
3405 vex_printf(",");
3406 ppIRType(t_arg3);
3407 vex_printf(") -> ");
3408 ppIRType (t_dst);
3409 vex_printf("\narg tys are (");
3410 ppIRType(ttarg1);
3411 vex_printf(",");
3412 ppIRType(ttarg2);
3413 vex_printf(",");
3414 ppIRType(ttarg3);
3415 vex_printf(")\n");
3416 sanityCheckFail(bb,stmt,
3417 "Iex.Triop: arg tys don't match op tys\n"
3418 "... additional details precede BB printout\n");
3419 }
3420 break;
3421 }
3422 case Iex_Binop: {
3423 IRType ttarg1, ttarg2;
3424 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
3425 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
3426 typeOfPrimop(expr->Iex.Binop.op,
3427 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
3428 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
3429 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) {
3430 vex_printf(" op name: " );
3431 ppIROp(expr->Iex.Binop.op);
3432 vex_printf("\n");
3433 sanityCheckFail(bb,stmt,
3434 "Iex.Binop: wrong arity op\n"
3435 "... name of op precedes BB printout\n");
3436 }
3437 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
3438 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
3439 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
3440 vex_printf(" op name: ");
3441 ppIROp(expr->Iex.Binop.op);
3442 vex_printf("\n");
3443 vex_printf(" op type is (");
3444 ppIRType(t_arg1);
3445 vex_printf(",");
3446 ppIRType(t_arg2);
3447 vex_printf(") -> ");
3448 ppIRType (t_dst);
3449 vex_printf("\narg tys are (");
3450 ppIRType(ttarg1);
3451 vex_printf(",");
3452 ppIRType(ttarg2);
3453 vex_printf(")\n");
3454 sanityCheckFail(bb,stmt,
3455 "Iex.Binop: arg tys don't match op tys\n"
3456 "... additional details precede BB printout\n");
3457 }
3458 break;
3459 }
3460 case Iex_Unop:
3461 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
3462 typeOfPrimop(expr->Iex.Unop.op,
3463 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
3464 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
3465 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
3466 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
3467 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
3468 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
3469 break;
3470 case Iex_Load:
3471 tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
3472 if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
3473 sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
3474 if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
3475 sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
3476 break;
3477 case Iex_CCall:
3478 if (!saneIRCallee(expr->Iex.CCall.cee))
3479 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
3480 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
3481 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
3482 for (i = 0; expr->Iex.CCall.args[i]; i++) {
3483 if (i >= 32)
3484 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
3485 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
3486 }
3487 if (expr->Iex.CCall.retty == Ity_I1)
3488 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
3489 for (i = 0; expr->Iex.CCall.args[i]; i++)
3490 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
3491 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
3492 break;
3493 case Iex_Const:
3494 if (!saneIRConst(expr->Iex.Const.con))
3495 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
3496 break;
3497 case Iex_Mux0X:
3498 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
3499 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
3500 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
3501 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
3502 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
3503 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
3504 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
3505 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
3506 break;
3507 default:
3508 vpanic("tcExpr");
3509 }
3510 }
3511
3512
3513 static
tcStmt(IRSB * bb,IRStmt * stmt,IRType gWordTy)3514 void tcStmt ( IRSB* bb, IRStmt* stmt, IRType gWordTy )
3515 {
3516 Int i;
3517 IRDirty* d;
3518 IRCAS* cas;
3519 IRPutI* puti;
3520 IRType tyExpd, tyData;
3521 IRTypeEnv* tyenv = bb->tyenv;
3522 switch (stmt->tag) {
3523 case Ist_IMark:
3524 /* Somewhat heuristic, but rule out totally implausible
3525 instruction sizes and deltas. */
3526 if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20)
3527 sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible");
3528 if (stmt->Ist.IMark.delta > 1)
3529 sanityCheckFail(bb,stmt,"IRStmt.IMark.delta: implausible");
3530 break;
3531 case Ist_AbiHint:
3532 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
3533 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
3534 "not :: guest word type");
3535 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy)
3536 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: "
3537 "not :: guest word type");
3538 break;
3539 case Ist_Put:
3540 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
3541 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
3542 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
3543 break;
3544 case Ist_PutI:
3545 puti = stmt->Ist.PutI.details;
3546 tcExpr( bb, stmt, puti->data, gWordTy );
3547 tcExpr( bb, stmt, puti->ix, gWordTy );
3548 if (typeOfIRExpr(tyenv,puti->data) == Ity_I1)
3549 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
3550 if (typeOfIRExpr(tyenv,puti->data)
3551 != puti->descr->elemTy)
3552 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
3553 if (typeOfIRExpr(tyenv,puti->ix) != Ity_I32)
3554 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
3555 if (!saneIRRegArray(puti->descr))
3556 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
3557 break;
3558 case Ist_WrTmp:
3559 tcExpr( bb, stmt, stmt->Ist.WrTmp.data, gWordTy );
3560 if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
3561 != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
3562 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
3563 break;
3564 case Ist_Store:
3565 tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
3566 tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
3567 if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
3568 sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type");
3569 if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
3570 sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1");
3571 if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
3572 sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness");
3573 break;
3574 case Ist_CAS:
3575 cas = stmt->Ist.CAS.details;
3576 /* make sure it's definitely either a CAS or a DCAS */
3577 if (cas->oldHi == IRTemp_INVALID
3578 && cas->expdHi == NULL && cas->dataHi == NULL) {
3579 /* fine; it's a single cas */
3580 }
3581 else
3582 if (cas->oldHi != IRTemp_INVALID
3583 && cas->expdHi != NULL && cas->dataHi != NULL) {
3584 /* fine; it's a double cas */
3585 }
3586 else {
3587 /* it's some el-mutanto hybrid */
3588 goto bad_cas;
3589 }
3590 /* check the address type */
3591 tcExpr( bb, stmt, cas->addr, gWordTy );
3592 if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
3593 /* check types on the {old,expd,data}Lo components agree */
3594 tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
3595 tyData = typeOfIRExpr(tyenv, cas->dataLo);
3596 if (tyExpd != tyData) goto bad_cas;
3597 if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo))
3598 goto bad_cas;
3599 /* check the base element type is sane */
3600 if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32
3601 || (gWordTy == Ity_I64 && tyExpd == Ity_I64)) {
3602 /* fine */
3603 } else {
3604 goto bad_cas;
3605 }
3606 /* If it's a DCAS, check types on the {old,expd,data}Hi
3607 components too */
3608 if (cas->oldHi != IRTemp_INVALID) {
3609 tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
3610 tyData = typeOfIRExpr(tyenv, cas->dataHi);
3611 if (tyExpd != tyData) goto bad_cas;
3612 if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi))
3613 goto bad_cas;
3614 /* and finally check that oldLo and oldHi have the same
3615 type. This forces equivalence amongst all 6 types. */
3616 if (typeOfIRTemp(tyenv, cas->oldHi)
3617 != typeOfIRTemp(tyenv, cas->oldLo))
3618 goto bad_cas;
3619 }
3620 break;
3621 bad_cas:
3622 sanityCheckFail(bb,stmt,"IRStmt.CAS: ill-formed");
3623 break;
3624 case Ist_LLSC: {
3625 IRType tyRes;
3626 if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy)
3627 sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type");
3628 if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE)
3629 sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness");
3630 tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result);
3631 if (stmt->Ist.LLSC.storedata == NULL) {
3632 /* it's a LL */
3633 if (tyRes != Ity_I64 && tyRes != Ity_I32
3634 && tyRes != Ity_I16 && tyRes != Ity_I8)
3635 sanityCheckFail(bb,stmt,"Ist.LLSC(LL).result :: bogus");
3636 } else {
3637 /* it's a SC */
3638 if (tyRes != Ity_I1)
3639 sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1");
3640 tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata);
3641 if (tyData != Ity_I64 && tyData != Ity_I32
3642 && tyData != Ity_I16 && tyData != Ity_I8)
3643 sanityCheckFail(bb,stmt,
3644 "Ist.LLSC(SC).result :: storedata bogus");
3645 }
3646 break;
3647 }
3648 case Ist_Dirty:
3649 /* Mostly check for various kinds of ill-formed dirty calls. */
3650 d = stmt->Ist.Dirty.details;
3651 if (d->cee == NULL) goto bad_dirty;
3652 if (!saneIRCallee(d->cee)) goto bad_dirty;
3653 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
3654 if (d->mFx == Ifx_None) {
3655 if (d->mAddr != NULL || d->mSize != 0)
3656 goto bad_dirty;
3657 } else {
3658 if (d->mAddr == NULL || d->mSize == 0)
3659 goto bad_dirty;
3660 }
3661 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
3662 goto bad_dirty;
3663 if (d->nFxState == 0 && d->needsBBP)
3664 goto bad_dirty;
3665 for (i = 0; i < d->nFxState; i++) {
3666 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
3667 if (d->fxState[i].size <= 0) goto bad_dirty;
3668 if (d->fxState[i].nRepeats == 0) {
3669 if (d->fxState[i].repeatLen != 0) goto bad_dirty;
3670 } else {
3671 if (d->fxState[i].repeatLen <= d->fxState[i].size)
3672 goto bad_dirty;
3673 /* the % is safe because of the .size check above */
3674 if ((d->fxState[i].repeatLen % d->fxState[i].size) != 0)
3675 goto bad_dirty;
3676 }
3677 }
3678 /* check guard */
3679 if (d->guard == NULL) goto bad_dirty;
3680 tcExpr( bb, stmt, d->guard, gWordTy );
3681 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
3682 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
3683 /* A dirty helper that is executed conditionally (or not at
3684 all) may not return a value. Hence if .tmp is not
3685 IRTemp_INVALID, .guard must be manifestly True at JIT
3686 time. */
3687 if (d->tmp != IRTemp_INVALID
3688 && (d->guard->tag != Iex_Const
3689 || d->guard->Iex.Const.con->Ico.U1 == 0))
3690 sanityCheckFail(bb,stmt,"IRStmt.Dirty with a return value"
3691 " is executed under a condition");
3692 /* check types, minimally */
3693 if (d->tmp != IRTemp_INVALID
3694 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
3695 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
3696 for (i = 0; d->args[i] != NULL; i++) {
3697 if (i >= 32)
3698 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
3699 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
3700 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
3701 }
3702 break;
3703 bad_dirty:
3704 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
3705 break;
3706 case Ist_NoOp:
3707 break;
3708 case Ist_MBE:
3709 switch (stmt->Ist.MBE.event) {
3710 case Imbe_Fence: case Imbe_CancelReservation:
3711 break;
3712 default: sanityCheckFail(bb,stmt,"IRStmt.MBE.event: unknown");
3713 break;
3714 }
3715 break;
3716 case Ist_Exit:
3717 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
3718 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
3719 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
3720 if (!saneIRConst(stmt->Ist.Exit.dst))
3721 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
3722 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
3723 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
3724 /* because it would intersect with host_EvC_* */
3725 if (stmt->Ist.Exit.offsIP < 16)
3726 sanityCheckFail(bb,stmt,"IRStmt.Exit.offsIP: too low");
3727 break;
3728 default:
3729 vpanic("tcStmt");
3730 }
3731 }
3732
sanityCheckIRSB(IRSB * bb,HChar * caller,Bool require_flat,IRType guest_word_size)3733 void sanityCheckIRSB ( IRSB* bb, HChar* caller,
3734 Bool require_flat, IRType guest_word_size )
3735 {
3736 Int i;
3737 IRStmt* stmt;
3738 Int n_temps = bb->tyenv->types_used;
3739 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
3740
3741 if (0)
3742 vex_printf("sanityCheck: %s\n", caller);
3743
3744 vassert(guest_word_size == Ity_I32
3745 || guest_word_size == Ity_I64);
3746
3747 if (bb->stmts_used < 0 || bb->stmts_size < 8
3748 || bb->stmts_used > bb->stmts_size)
3749 /* this BB is so strange we can't even print it */
3750 vpanic("sanityCheckIRSB: stmts array limits wierd");
3751
3752 /* Ensure each temp has a plausible type. */
3753 for (i = 0; i < n_temps; i++) {
3754 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
3755 if (!isPlausibleIRType(ty)) {
3756 vex_printf("Temp t%d declared with implausible type 0x%x\n",
3757 i, (UInt)ty);
3758 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
3759 }
3760 }
3761
3762 /* Check for flatness, if required. */
3763 if (require_flat) {
3764 for (i = 0; i < bb->stmts_used; i++) {
3765 stmt = bb->stmts[i];
3766 if (!stmt)
3767 sanityCheckFail(bb, stmt, "IRStmt: is NULL");
3768 if (!isFlatIRStmt(stmt))
3769 sanityCheckFail(bb, stmt, "IRStmt: is not flat");
3770 }
3771 if (!isIRAtom(bb->next))
3772 sanityCheckFail(bb, NULL, "bb->next is not an atom");
3773 }
3774
3775 /* Count the defs of each temp. Only one def is allowed.
3776 Also, check that each used temp has already been defd. */
3777
3778 for (i = 0; i < n_temps; i++)
3779 def_counts[i] = 0;
3780
3781 for (i = 0; i < bb->stmts_used; i++) {
3782 IRDirty* d;
3783 IRCAS* cas;
3784 stmt = bb->stmts[i];
3785 /* Check any temps used by this statement. */
3786 useBeforeDef_Stmt(bb,stmt,def_counts);
3787
3788 /* Now make note of any temps defd by this statement. */
3789 switch (stmt->tag) {
3790 case Ist_WrTmp:
3791 if (stmt->Ist.WrTmp.tmp < 0 || stmt->Ist.WrTmp.tmp >= n_temps)
3792 sanityCheckFail(bb, stmt,
3793 "IRStmt.Tmp: destination tmp is out of range");
3794 def_counts[stmt->Ist.WrTmp.tmp]++;
3795 if (def_counts[stmt->Ist.WrTmp.tmp] > 1)
3796 sanityCheckFail(bb, stmt,
3797 "IRStmt.Tmp: destination tmp is assigned more than once");
3798 break;
3799 case Ist_Store:
3800 break;
3801 case Ist_Dirty:
3802 if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
3803 d = stmt->Ist.Dirty.details;
3804 if (d->tmp < 0 || d->tmp >= n_temps)
3805 sanityCheckFail(bb, stmt,
3806 "IRStmt.Dirty: destination tmp is out of range");
3807 def_counts[d->tmp]++;
3808 if (def_counts[d->tmp] > 1)
3809 sanityCheckFail(bb, stmt,
3810 "IRStmt.Dirty: destination tmp is assigned more than once");
3811 }
3812 break;
3813 case Ist_CAS:
3814 cas = stmt->Ist.CAS.details;
3815 if (cas->oldHi != IRTemp_INVALID) {
3816 if (cas->oldHi < 0 || cas->oldHi >= n_temps)
3817 sanityCheckFail(bb, stmt,
3818 "IRStmt.CAS: destination tmpHi is out of range");
3819 def_counts[cas->oldHi]++;
3820 if (def_counts[cas->oldHi] > 1)
3821 sanityCheckFail(bb, stmt,
3822 "IRStmt.CAS: destination tmpHi is assigned more than once");
3823 }
3824 if (cas->oldLo < 0 || cas->oldLo >= n_temps)
3825 sanityCheckFail(bb, stmt,
3826 "IRStmt.CAS: destination tmpLo is out of range");
3827 def_counts[cas->oldLo]++;
3828 if (def_counts[cas->oldLo] > 1)
3829 sanityCheckFail(bb, stmt,
3830 "IRStmt.CAS: destination tmpLo is assigned more than once");
3831 break;
3832 case Ist_LLSC:
3833 if (stmt->Ist.LLSC.result < 0 || stmt->Ist.LLSC.result >= n_temps)
3834 sanityCheckFail(bb, stmt,
3835 "IRStmt.LLSC: destination tmp is out of range");
3836 def_counts[stmt->Ist.LLSC.result]++;
3837 if (def_counts[stmt->Ist.LLSC.result] > 1)
3838 sanityCheckFail(bb, stmt,
3839 "IRStmt.LLSC: destination tmp is assigned more than once");
3840 break;
3841 default:
3842 /* explicitly handle the rest, so as to keep gcc quiet */
3843 break;
3844 }
3845 }
3846
3847 /* Typecheck everything. */
3848 for (i = 0; i < bb->stmts_used; i++)
3849 if (bb->stmts[i])
3850 tcStmt( bb, bb->stmts[i], guest_word_size );
3851 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
3852 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
3853 /* because it would intersect with host_EvC_* */
3854 if (bb->offsIP < 16)
3855 sanityCheckFail(bb, NULL, "bb->offsIP: too low");
3856
3857 }
3858
3859 /*---------------------------------------------------------------*/
3860 /*--- Misc helper functions ---*/
3861 /*---------------------------------------------------------------*/
3862
eqIRConst(IRConst * c1,IRConst * c2)3863 Bool eqIRConst ( IRConst* c1, IRConst* c2 )
3864 {
3865 if (c1->tag != c2->tag)
3866 return False;
3867
3868 switch (c1->tag) {
3869 case Ico_U1: return toBool( (1 & c1->Ico.U1) == (1 & c2->Ico.U1) );
3870 case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 );
3871 case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 );
3872 case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 );
3873 case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 );
3874 case Ico_F32: return toBool( c1->Ico.F32 == c2->Ico.F32 );
3875 case Ico_F32i: return toBool( c1->Ico.F32i == c2->Ico.F32i );
3876 case Ico_F64: return toBool( c1->Ico.F64 == c2->Ico.F64 );
3877 case Ico_F64i: return toBool( c1->Ico.F64i == c2->Ico.F64i );
3878 case Ico_V128: return toBool( c1->Ico.V128 == c2->Ico.V128 );
3879 case Ico_V256: return toBool( c1->Ico.V256 == c2->Ico.V256 );
3880 default: vpanic("eqIRConst");
3881 }
3882 }
3883
eqIRRegArray(IRRegArray * descr1,IRRegArray * descr2)3884 Bool eqIRRegArray ( IRRegArray* descr1, IRRegArray* descr2 )
3885 {
3886 return toBool( descr1->base == descr2->base
3887 && descr1->elemTy == descr2->elemTy
3888 && descr1->nElems == descr2->nElems );
3889 }
3890
sizeofIRType(IRType ty)3891 Int sizeofIRType ( IRType ty )
3892 {
3893 switch (ty) {
3894 case Ity_I8: return 1;
3895 case Ity_I16: return 2;
3896 case Ity_I32: return 4;
3897 case Ity_I64: return 8;
3898 case Ity_I128: return 16;
3899 case Ity_F32: return 4;
3900 case Ity_F64: return 8;
3901 case Ity_F128: return 16;
3902 case Ity_D32: return 4;
3903 case Ity_D64: return 8;
3904 case Ity_D128: return 16;
3905 case Ity_V128: return 16;
3906 case Ity_V256: return 32;
3907 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
3908 vpanic("sizeofIRType");
3909 }
3910 }
3911
mkIRExpr_HWord(HWord hw)3912 IRExpr* mkIRExpr_HWord ( HWord hw )
3913 {
3914 vassert(sizeof(void*) == sizeof(HWord));
3915 if (sizeof(HWord) == 4)
3916 return IRExpr_Const(IRConst_U32((UInt)hw));
3917 if (sizeof(HWord) == 8)
3918 return IRExpr_Const(IRConst_U64((ULong)hw));
3919 vpanic("mkIRExpr_HWord");
3920 }
3921
unsafeIRDirty_0_N(Int regparms,HChar * name,void * addr,IRExpr ** args)3922 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
3923 IRExpr** args )
3924 {
3925 IRDirty* d = emptyIRDirty();
3926 d->cee = mkIRCallee ( regparms, name, addr );
3927 d->guard = IRExpr_Const(IRConst_U1(True));
3928 d->args = args;
3929 return d;
3930 }
3931
unsafeIRDirty_1_N(IRTemp dst,Int regparms,HChar * name,void * addr,IRExpr ** args)3932 IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
3933 Int regparms, HChar* name, void* addr,
3934 IRExpr** args )
3935 {
3936 IRDirty* d = emptyIRDirty();
3937 d->cee = mkIRCallee ( regparms, name, addr );
3938 d->guard = IRExpr_Const(IRConst_U1(True));
3939 d->args = args;
3940 d->tmp = dst;
3941 return d;
3942 }
3943
mkIRExprCCall(IRType retty,Int regparms,HChar * name,void * addr,IRExpr ** args)3944 IRExpr* mkIRExprCCall ( IRType retty,
3945 Int regparms, HChar* name, void* addr,
3946 IRExpr** args )
3947 {
3948 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
3949 retty, args );
3950 }
3951
eqIRAtom(IRExpr * a1,IRExpr * a2)3952 Bool eqIRAtom ( IRExpr* a1, IRExpr* a2 )
3953 {
3954 vassert(isIRAtom(a1));
3955 vassert(isIRAtom(a2));
3956 if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp)
3957 return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp);
3958 if (a1->tag == Iex_Const && a2->tag == Iex_Const)
3959 return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
3960 return False;
3961 }
3962
3963 /*---------------------------------------------------------------*/
3964 /*--- end ir_defs.c ---*/
3965 /*---------------------------------------------------------------*/
3966