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