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