]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/ir_defs.c
Inital import
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / ir_defs.c
1
2 /*---------------------------------------------------------------*/
3 /*--- begin                                         ir_defs.c ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2004-2010 OpenWorks LLP
11       info@open-works.net
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35
36 #include "libvex_basictypes.h"
37 #include "libvex_ir.h"
38 #include "libvex.h"
39
40 #include "main_util.h"
41
42
43 /*---------------------------------------------------------------*/
44 /*--- Printing the IR                                         ---*/
45 /*---------------------------------------------------------------*/
46
47 void ppIRType ( IRType ty )
48 {
49    switch (ty) {
50       case Ity_INVALID: vex_printf("Ity_INVALID"); break;
51       case Ity_I1:      vex_printf( "I1");   break;
52       case Ity_I8:      vex_printf( "I8");   break;
53       case Ity_I16:     vex_printf( "I16");  break;
54       case Ity_I32:     vex_printf( "I32");  break;
55       case Ity_I64:     vex_printf( "I64");  break;
56       case Ity_I128:    vex_printf( "I128"); break;
57       case Ity_F32:     vex_printf( "F32");  break;
58       case Ity_F64:     vex_printf( "F64");  break;
59       case Ity_V128:    vex_printf( "V128"); break;
60       default: vex_printf("ty = 0x%x\n", (Int)ty);
61                vpanic("ppIRType");
62    }
63 }
64
65 void ppIRConst ( IRConst* con )
66 {
67    union { ULong i64; Double f64; } u;
68    vassert(sizeof(ULong) == sizeof(Double));
69    switch (con->tag) {
70       case Ico_U1:   vex_printf( "%d:I1",        con->Ico.U1 ? 1 : 0); break;
71       case Ico_U8:   vex_printf( "0x%x:I8",      (UInt)(con->Ico.U8)); break;
72       case Ico_U16:  vex_printf( "0x%x:I16",     (UInt)(con->Ico.U16)); break;
73       case Ico_U32:  vex_printf( "0x%x:I32",     (UInt)(con->Ico.U32)); break;
74       case Ico_U64:  vex_printf( "0x%llx:I64",   (ULong)(con->Ico.U64)); break;
75       case Ico_F64:  u.f64 = con->Ico.F64;
76                      vex_printf( "F64{0x%llx}",  u.i64);
77                      break;
78       case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
79       case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break;
80       default: vpanic("ppIRConst");
81    }
82 }
83
84 void ppIRCallee ( IRCallee* ce )
85 {
86    vex_printf("%s", ce->name);
87    if (ce->regparms > 0)
88       vex_printf("[rp=%d]", ce->regparms);
89    if (ce->mcx_mask > 0)
90       vex_printf("[mcx=0x%x]", ce->mcx_mask);
91    vex_printf("{%p}", (void*)ce->addr);
92 }
93
94 void ppIRRegArray ( IRRegArray* arr )
95 {
96    vex_printf("(%d:%dx", arr->base, arr->nElems);
97    ppIRType(arr->elemTy);
98    vex_printf(")");
99 }
100
101 void ppIRTemp ( IRTemp tmp )
102 {
103    if (tmp == IRTemp_INVALID)
104       vex_printf("IRTemp_INVALID");
105    else
106       vex_printf( "t%d", (Int)tmp);
107 }
108
109 void ppIROp ( IROp op )
110 {
111    HChar* str = NULL; 
112    IROp   base;
113    switch (op) {
114       case Iop_Add8 ... Iop_Add64:
115          str = "Add"; base = Iop_Add8; break;
116       case Iop_Sub8 ... Iop_Sub64:
117          str = "Sub"; base = Iop_Sub8; break;
118       case Iop_Mul8 ... Iop_Mul64:
119          str = "Mul"; base = Iop_Mul8; break;
120       case Iop_Or8 ... Iop_Or64:
121          str = "Or"; base = Iop_Or8; break;
122       case Iop_And8 ... Iop_And64:
123          str = "And"; base = Iop_And8; break;
124       case Iop_Xor8 ... Iop_Xor64:
125          str = "Xor"; base = Iop_Xor8; break;
126       case Iop_Shl8 ... Iop_Shl64:
127          str = "Shl"; base = Iop_Shl8; break;
128       case Iop_Shr8 ... Iop_Shr64:
129          str = "Shr"; base = Iop_Shr8; break;
130       case Iop_Sar8 ... Iop_Sar64:
131          str = "Sar"; base = Iop_Sar8; break;
132       case Iop_CmpEQ8 ... Iop_CmpEQ64:
133          str = "CmpEQ"; base = Iop_CmpEQ8; break;
134       case Iop_CmpNE8 ... Iop_CmpNE64:
135          str = "CmpNE"; base = Iop_CmpNE8; break;
136       case Iop_CasCmpEQ8 ... Iop_CasCmpEQ64:
137          str = "CasCmpEQ"; base = Iop_CasCmpEQ8; break;
138       case Iop_CasCmpNE8 ... Iop_CasCmpNE64:
139          str = "CasCmpNE"; base = Iop_CasCmpNE8; break;
140       case Iop_Not8 ... Iop_Not64:
141          str = "Not"; base = Iop_Not8; break;
142       /* other cases must explicitly "return;" */
143       case Iop_8Uto16:   vex_printf("8Uto16");  return;
144       case Iop_8Uto32:   vex_printf("8Uto32");  return;
145       case Iop_16Uto32:  vex_printf("16Uto32"); return;
146       case Iop_8Sto16:   vex_printf("8Sto16");  return;
147       case Iop_8Sto32:   vex_printf("8Sto32");  return;
148       case Iop_16Sto32:  vex_printf("16Sto32"); return;
149       case Iop_32Sto64:  vex_printf("32Sto64"); return;
150       case Iop_32Uto64:  vex_printf("32Uto64"); return;
151       case Iop_32to8:    vex_printf("32to8");   return;
152       case Iop_16Uto64:  vex_printf("16Uto64"); return;
153       case Iop_16Sto64:  vex_printf("16Sto64"); return;
154       case Iop_8Uto64:   vex_printf("8Uto64"); return;
155       case Iop_8Sto64:   vex_printf("8Sto64"); return;
156       case Iop_64to16:   vex_printf("64to16"); return;
157       case Iop_64to8:    vex_printf("64to8");  return;
158
159       case Iop_Not1:     vex_printf("Not1");    return;
160       case Iop_32to1:    vex_printf("32to1");   return;
161       case Iop_64to1:    vex_printf("64to1");   return;
162       case Iop_1Uto8:    vex_printf("1Uto8");   return;
163       case Iop_1Uto32:   vex_printf("1Uto32");  return;
164       case Iop_1Uto64:   vex_printf("1Uto64");  return;
165       case Iop_1Sto8:    vex_printf("1Sto8");  return;
166       case Iop_1Sto16:   vex_printf("1Sto16");  return;
167       case Iop_1Sto32:   vex_printf("1Sto32");  return;
168       case Iop_1Sto64:   vex_printf("1Sto64");  return;
169
170       case Iop_MullS8:   vex_printf("MullS8");  return;
171       case Iop_MullS16:  vex_printf("MullS16"); return;
172       case Iop_MullS32:  vex_printf("MullS32"); return;
173       case Iop_MullS64:  vex_printf("MullS64"); return;
174       case Iop_MullU8:   vex_printf("MullU8");  return;
175       case Iop_MullU16:  vex_printf("MullU16"); return;
176       case Iop_MullU32:  vex_printf("MullU32"); return;
177       case Iop_MullU64:  vex_printf("MullU64"); return;
178
179       case Iop_Clz64:    vex_printf("Clz64"); return;
180       case Iop_Clz32:    vex_printf("Clz32"); return;
181       case Iop_Ctz64:    vex_printf("Ctz64"); return;
182       case Iop_Ctz32:    vex_printf("Ctz32"); return;
183
184       case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
185       case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
186       case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
187       case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
188
189       case Iop_CmpLT64S: vex_printf("CmpLT64S"); return;
190       case Iop_CmpLE64S: vex_printf("CmpLE64S"); return;
191       case Iop_CmpLT64U: vex_printf("CmpLT64U"); return;
192       case Iop_CmpLE64U: vex_printf("CmpLE64U"); return;
193
194       case Iop_CmpNEZ8:  vex_printf("CmpNEZ8"); return;
195       case Iop_CmpNEZ16: vex_printf("CmpNEZ16"); return;
196       case Iop_CmpNEZ32: vex_printf("CmpNEZ32"); return;
197       case Iop_CmpNEZ64: vex_printf("CmpNEZ64"); return;
198
199       case Iop_CmpwNEZ32: vex_printf("CmpwNEZ32"); return;
200       case Iop_CmpwNEZ64: vex_printf("CmpwNEZ64"); return;
201
202       case Iop_Left8:  vex_printf("Left8"); return;
203       case Iop_Left16: vex_printf("Left16"); return;
204       case Iop_Left32: vex_printf("Left32"); return;
205       case Iop_Left64: vex_printf("Left64"); return;
206       case Iop_Max32U: vex_printf("Max32U"); return;
207
208       case Iop_CmpORD32U: vex_printf("CmpORD32U"); return;
209       case Iop_CmpORD32S: vex_printf("CmpORD32S"); return;
210
211       case Iop_CmpORD64U: vex_printf("CmpORD64U"); return;
212       case Iop_CmpORD64S: vex_printf("CmpORD64S"); return;
213
214       case Iop_DivU32: vex_printf("DivU32"); return;
215       case Iop_DivS32: vex_printf("DivS32"); return;
216       case Iop_DivU64: vex_printf("DivU64"); return;
217       case Iop_DivS64: vex_printf("DivS64"); return;
218
219       case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
220       case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
221
222       case Iop_DivModU128to64: vex_printf("DivModU128to64"); return;
223       case Iop_DivModS128to64: vex_printf("DivModS128to64"); return;
224
225       case Iop_16HIto8:  vex_printf("16HIto8"); return;
226       case Iop_16to8:    vex_printf("16to8");   return;
227       case Iop_8HLto16:  vex_printf("8HLto16"); return;
228
229       case Iop_32HIto16: vex_printf("32HIto16"); return;
230       case Iop_32to16:   vex_printf("32to16");   return;
231       case Iop_16HLto32: vex_printf("16HLto32"); return;
232
233       case Iop_64HIto32: vex_printf("64HIto32"); return;
234       case Iop_64to32:   vex_printf("64to32");   return;
235       case Iop_32HLto64: vex_printf("32HLto64"); return;
236
237       case Iop_128HIto64: vex_printf("128HIto64"); return;
238       case Iop_128to64:   vex_printf("128to64");   return;
239       case Iop_64HLto128: vex_printf("64HLto128"); return;
240
241       case Iop_AddF64:    vex_printf("AddF64"); return;
242       case Iop_SubF64:    vex_printf("SubF64"); return;
243       case Iop_MulF64:    vex_printf("MulF64"); return;
244       case Iop_DivF64:    vex_printf("DivF64"); return;
245       case Iop_AddF64r32: vex_printf("AddF64r32"); return;
246       case Iop_SubF64r32: vex_printf("SubF64r32"); return;
247       case Iop_MulF64r32: vex_printf("MulF64r32"); return;
248       case Iop_DivF64r32: vex_printf("DivF64r32"); return;
249       case Iop_AddF32:    vex_printf("AddF32"); return;
250       case Iop_SubF32:    vex_printf("SubF32"); return;
251       case Iop_MulF32:    vex_printf("MulF32"); return;
252       case Iop_DivF32:    vex_printf("DivF32"); return;
253
254       case Iop_ScaleF64:      vex_printf("ScaleF64"); return;
255       case Iop_AtanF64:       vex_printf("AtanF64"); return;
256       case Iop_Yl2xF64:       vex_printf("Yl2xF64"); return;
257       case Iop_Yl2xp1F64:     vex_printf("Yl2xp1F64"); return;
258       case Iop_PRemF64:       vex_printf("PRemF64"); return;
259       case Iop_PRemC3210F64:  vex_printf("PRemC3210F64"); return;
260       case Iop_PRem1F64:      vex_printf("PRem1F64"); return;
261       case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
262       case Iop_NegF64:        vex_printf("NegF64"); return;
263       case Iop_AbsF64:        vex_printf("AbsF64"); return;
264       case Iop_NegF32:        vex_printf("NegF32"); return;
265       case Iop_AbsF32:        vex_printf("AbsF32"); return;
266       case Iop_SqrtF64:       vex_printf("SqrtF64"); return;
267       case Iop_SqrtF32:       vex_printf("SqrtF32"); return;
268       case Iop_SinF64:    vex_printf("SinF64"); return;
269       case Iop_CosF64:    vex_printf("CosF64"); return;
270       case Iop_TanF64:    vex_printf("TanF64"); return;
271       case Iop_2xm1F64:   vex_printf("2xm1F64"); return;
272
273       case Iop_MAddF64:    vex_printf("MAddF64"); return;
274       case Iop_MSubF64:    vex_printf("MSubF64"); return;
275       case Iop_MAddF64r32: vex_printf("MAddF64r32"); return;
276       case Iop_MSubF64r32: vex_printf("MSubF64r32"); return;
277
278       case Iop_Est5FRSqrt:    vex_printf("Est5FRSqrt"); return;
279       case Iop_RoundF64toF64_NEAREST: vex_printf("RoundF64toF64_NEAREST"); return;
280       case Iop_RoundF64toF64_NegINF: vex_printf("RoundF64toF64_NegINF"); return;
281       case Iop_RoundF64toF64_PosINF: vex_printf("RoundF64toF64_PosINF"); return;
282       case Iop_RoundF64toF64_ZERO: vex_printf("RoundF64toF64_ZERO"); return;
283
284       case Iop_TruncF64asF32: vex_printf("TruncF64asF32"); return;
285       case Iop_CalcFPRF:      vex_printf("CalcFPRF"); return;
286
287       case Iop_CmpF64:    vex_printf("CmpF64"); return;
288
289       case Iop_F64toI16S: vex_printf("F64toI16S"); return;
290       case Iop_F64toI32S: vex_printf("F64toI32S"); return;
291       case Iop_F64toI64S: vex_printf("F64toI64S"); return;
292
293       case Iop_F64toI32U: vex_printf("F64toI32U"); return;
294
295       case Iop_I16StoF64: vex_printf("I16StoF64"); return;
296       case Iop_I32StoF64: vex_printf("I32StoF64"); return;
297       case Iop_I64StoF64: vex_printf("I64StoF64"); return;
298
299       case Iop_I32UtoF64: vex_printf("I32UtoF64"); return;
300
301       case Iop_F32toF64: vex_printf("F32toF64"); return;
302       case Iop_F64toF32: vex_printf("F64toF32"); return;
303
304       case Iop_RoundF64toInt: vex_printf("RoundF64toInt"); return;
305       case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return;
306
307       case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
308       case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
309       case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return;
310       case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
311
312       case Iop_I32UtoFx4: vex_printf("I32UtoFx4"); return;
313       case Iop_I32StoFx4: vex_printf("I32StoFx4"); return;
314
315       case Iop_QFtoI32Ux4_RZ: vex_printf("QFtoI32Ux4_RZ"); return;
316       case Iop_QFtoI32Sx4_RZ: vex_printf("QFtoI32Sx4_RZ"); return;
317
318       case Iop_RoundF32x4_RM: vex_printf("RoundF32x4_RM"); return;
319       case Iop_RoundF32x4_RP: vex_printf("RoundF32x4_RP"); return;
320       case Iop_RoundF32x4_RN: vex_printf("RoundF32x4_RN"); return;
321       case Iop_RoundF32x4_RZ: vex_printf("RoundF32x4_RZ"); return;
322
323       case Iop_Add8x8: vex_printf("Add8x8"); return;
324       case Iop_Add16x4: vex_printf("Add16x4"); return;
325       case Iop_Add32x2: vex_printf("Add32x2"); return;
326       case Iop_QAdd8Ux8: vex_printf("QAdd8Ux8"); return;
327       case Iop_QAdd16Ux4: vex_printf("QAdd16Ux4"); return;
328       case Iop_QAdd8Sx8: vex_printf("QAdd8Sx8"); return;
329       case Iop_QAdd16Sx4: vex_printf("QAdd16Sx4"); return;
330       case Iop_Sub8x8: vex_printf("Sub8x8"); return;
331       case Iop_Sub16x4: vex_printf("Sub16x4"); return;
332       case Iop_Sub32x2: vex_printf("Sub32x2"); return;
333       case Iop_QSub8Ux8: vex_printf("QSub8Ux8"); return;
334       case Iop_QSub16Ux4: vex_printf("QSub16Ux4"); return;
335       case Iop_QSub8Sx8: vex_printf("QSub8Sx8"); return;
336       case Iop_QSub16Sx4: vex_printf("QSub16Sx4"); return;
337       case Iop_Mul16x4: vex_printf("Mul16x4"); return;
338       case Iop_Mul32x2: vex_printf("Mul32x2"); return;
339       case Iop_MulHi16Ux4: vex_printf("MulHi16Ux4"); return;
340       case Iop_MulHi16Sx4: vex_printf("MulHi16Sx4"); return;
341       case Iop_Avg8Ux8: vex_printf("Avg8Ux8"); return;
342       case Iop_Avg16Ux4: vex_printf("Avg16Ux4"); return;
343       case Iop_Max16Sx4: vex_printf("Max16Sx4"); return;
344       case Iop_Max8Ux8: vex_printf("Max8Ux8"); return;
345       case Iop_Min16Sx4: vex_printf("Min16Sx4"); return;
346       case Iop_Min8Ux8: vex_printf("Min8Ux8"); return;
347       case Iop_CmpEQ8x8: vex_printf("CmpEQ8x8"); return;
348       case Iop_CmpEQ16x4: vex_printf("CmpEQ16x4"); return;
349       case Iop_CmpEQ32x2: vex_printf("CmpEQ32x2"); return;
350       case Iop_CmpGT8Sx8: vex_printf("CmpGT8Sx8"); return;
351       case Iop_CmpGT16Sx4: vex_printf("CmpGT16Sx4"); return;
352       case Iop_CmpGT32Sx2: vex_printf("CmpGT32Sx2"); return;
353       case Iop_ShlN8x8: vex_printf("ShlN8x8"); return;
354       case Iop_ShlN16x4: vex_printf("ShlN16x4"); return;
355       case Iop_ShlN32x2: vex_printf("ShlN32x2"); return;
356       case Iop_ShrN16x4: vex_printf("ShrN16x4"); return;
357       case Iop_ShrN32x2: vex_printf("ShrN32x2"); return;
358       case Iop_SarN8x8: vex_printf("SarN8x8"); return;
359       case Iop_SarN16x4: vex_printf("SarN16x4"); return;
360       case Iop_SarN32x2: vex_printf("SarN32x2"); return;
361       case Iop_QNarrow16Ux4: vex_printf("QNarrow16Ux4"); return;
362       case Iop_QNarrow16Sx4: vex_printf("QNarrow16Sx4"); return;
363       case Iop_QNarrow32Sx2: vex_printf("QNarrow32Sx2"); return;
364       case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return;
365       case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return;
366       case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return;
367       case Iop_InterleaveLO8x8: vex_printf("InterleaveLO8x8"); return;
368       case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return;
369       case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return;
370       case Iop_CatOddLanes16x4: vex_printf("CatOddLanes16x4"); return;
371       case Iop_CatEvenLanes16x4: vex_printf("CatEvenLanes16x4"); return;
372       case Iop_Perm8x8: vex_printf("Perm8x8"); return;
373
374       case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return;
375       case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return;
376       case Iop_CmpNEZ8x8:  vex_printf("CmpNEZ8x8"); return;
377
378       case Iop_Add32Fx4:  vex_printf("Add32Fx4"); return;
379       case Iop_Add32F0x4: vex_printf("Add32F0x4"); return;
380       case Iop_Add64Fx2:  vex_printf("Add64Fx2"); return;
381       case Iop_Add64F0x2: vex_printf("Add64F0x2"); return;
382
383       case Iop_Div32Fx4:  vex_printf("Div32Fx4"); return;
384       case Iop_Div32F0x4: vex_printf("Div32F0x4"); return;
385       case Iop_Div64Fx2:  vex_printf("Div64Fx2"); return;
386       case Iop_Div64F0x2: vex_printf("Div64F0x2"); return;
387
388       case Iop_Max32Fx4:  vex_printf("Max32Fx4"); return;
389       case Iop_Max32F0x4: vex_printf("Max32F0x4"); return;
390       case Iop_Max64Fx2:  vex_printf("Max64Fx2"); return;
391       case Iop_Max64F0x2: vex_printf("Max64F0x2"); return;
392
393       case Iop_Min32Fx4:  vex_printf("Min32Fx4"); return;
394       case Iop_Min32F0x4: vex_printf("Min32F0x4"); return;
395       case Iop_Min64Fx2:  vex_printf("Min64Fx2"); return;
396       case Iop_Min64F0x2: vex_printf("Min64F0x2"); return;
397
398       case Iop_Mul32Fx4:  vex_printf("Mul32Fx4"); return;
399       case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return;
400       case Iop_Mul64Fx2:  vex_printf("Mul64Fx2"); return;
401       case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return;
402
403       case Iop_Recip32Fx4:  vex_printf("Recip32Fx4"); return;
404       case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return;
405       case Iop_Recip64Fx2:  vex_printf("Recip64Fx2"); return;
406       case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return;
407
408       case Iop_RSqrt32Fx4:  vex_printf("RSqrt32Fx4"); return;
409       case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return;
410       case Iop_RSqrt64Fx2:  vex_printf("RSqrt64Fx2"); return;
411       case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return;
412
413       case Iop_Sqrt32Fx4:  vex_printf("Sqrt32Fx4"); return;
414       case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return;
415       case Iop_Sqrt64Fx2:  vex_printf("Sqrt64Fx2"); return;
416       case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return;
417
418       case Iop_Sub32Fx4:  vex_printf("Sub32Fx4"); return;
419       case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return;
420       case Iop_Sub64Fx2:  vex_printf("Sub64Fx2"); return;
421       case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return;
422
423       case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return;
424       case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return;
425       case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return;
426       case Iop_CmpGT32Fx4: vex_printf("CmpGT32Fx4"); return;
427       case Iop_CmpGE32Fx4: vex_printf("CmpGE32Fx4"); return;
428       case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return;
429       case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return;
430       case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return;
431       case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return;
432       case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return;
433
434       case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return;
435       case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return;
436       case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return;
437       case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return;
438       case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return;
439       case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return;
440       case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return;
441       case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return;
442
443       case Iop_V128to64:   vex_printf("V128to64");   return;
444       case Iop_V128HIto64: vex_printf("V128HIto64"); return;
445       case Iop_64HLtoV128: vex_printf("64HLtoV128"); return;
446
447       case Iop_64UtoV128:   vex_printf("64UtoV128"); return;
448       case Iop_SetV128lo64: vex_printf("SetV128lo64"); return;
449
450       case Iop_32UtoV128:   vex_printf("32UtoV128"); return;
451       case Iop_V128to32:    vex_printf("V128to32"); return;
452       case Iop_SetV128lo32: vex_printf("SetV128lo32"); return;
453
454       case Iop_Dup8x16: vex_printf("Dup8x16"); return;
455       case Iop_Dup16x8: vex_printf("Dup16x8"); return;
456       case Iop_Dup32x4: vex_printf("Dup32x4"); return;
457
458       case Iop_NotV128:    vex_printf("NotV128"); return;
459       case Iop_AndV128:    vex_printf("AndV128"); return;
460       case Iop_OrV128:     vex_printf("OrV128");  return;
461       case Iop_XorV128:    vex_printf("XorV128"); return;
462
463       case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return;
464       case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return;
465       case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
466       case Iop_CmpNEZ64x2: vex_printf("CmpNEZ64x2"); return;
467
468       case Iop_Add8x16:   vex_printf("Add8x16"); return;
469       case Iop_Add16x8:   vex_printf("Add16x8"); return;
470       case Iop_Add32x4:   vex_printf("Add32x4"); return;
471       case Iop_Add64x2:   vex_printf("Add64x2"); return;
472       case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
473       case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
474       case Iop_QAdd32Ux4: vex_printf("QAdd32Ux4"); return;
475       case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
476       case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
477       case Iop_QAdd32Sx4: vex_printf("QAdd32Sx4"); return;
478
479       case Iop_Sub8x16:   vex_printf("Sub8x16"); return;
480       case Iop_Sub16x8:   vex_printf("Sub16x8"); return;
481       case Iop_Sub32x4:   vex_printf("Sub32x4"); return;
482       case Iop_Sub64x2:   vex_printf("Sub64x2"); return;
483       case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
484       case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
485       case Iop_QSub32Ux4: vex_printf("QSub32Ux4"); return;
486       case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
487       case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
488       case Iop_QSub32Sx4: vex_printf("QSub32Sx4"); return;
489
490       case Iop_Mul16x8:    vex_printf("Mul16x8"); return;
491       case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
492       case Iop_MulHi32Ux4: vex_printf("MulHi32Ux4"); return;
493       case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
494       case Iop_MulHi32Sx4: vex_printf("MulHi32Sx4"); return;
495
496       case Iop_MullEven8Ux16: vex_printf("MullEven8Ux16"); return;
497       case Iop_MullEven16Ux8: vex_printf("MullEven16Ux8"); return;
498       case Iop_MullEven8Sx16: vex_printf("MullEven8Sx16"); return;
499       case Iop_MullEven16Sx8: vex_printf("MullEven16Sx8"); return;
500
501       case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
502       case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
503       case Iop_Avg32Ux4: vex_printf("Avg32Ux4"); return;
504       case Iop_Avg8Sx16: vex_printf("Avg8Sx16"); return;
505       case Iop_Avg16Sx8: vex_printf("Avg16Sx8"); return;
506       case Iop_Avg32Sx4: vex_printf("Avg32Sx4"); return;
507
508       case Iop_Max8Sx16: vex_printf("Max8Sx16"); return;
509       case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
510       case Iop_Max32Sx4: vex_printf("Max32Sx4"); return;
511       case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
512       case Iop_Max16Ux8: vex_printf("Max16Ux8"); return;
513       case Iop_Max32Ux4: vex_printf("Max32Ux4"); return;
514
515       case Iop_Min8Sx16: vex_printf("Min8Sx16"); return;
516       case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
517       case Iop_Min32Sx4: vex_printf("Min32Sx4"); return;
518       case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
519       case Iop_Min16Ux8: vex_printf("Min16Ux8"); return;
520       case Iop_Min32Ux4: vex_printf("Min32Ux4"); return;
521
522       case Iop_CmpEQ8x16:  vex_printf("CmpEQ8x16"); return;
523       case Iop_CmpEQ16x8:  vex_printf("CmpEQ16x8"); return;
524       case Iop_CmpEQ32x4:  vex_printf("CmpEQ32x4"); return;
525       case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
526       case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
527       case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
528       case Iop_CmpGT8Ux16: vex_printf("CmpGT8Ux16"); return;
529       case Iop_CmpGT16Ux8: vex_printf("CmpGT16Ux8"); return;
530       case Iop_CmpGT32Ux4: vex_printf("CmpGT32Ux4"); return;
531
532       case Iop_ShlV128: vex_printf("ShlV128"); return;
533       case Iop_ShrV128: vex_printf("ShrV128"); return;
534
535       case Iop_ShlN8x16: vex_printf("ShlN8x16"); return;
536       case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
537       case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
538       case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
539       case Iop_ShrN8x16: vex_printf("ShrN8x16"); return;
540       case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
541       case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
542       case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
543       case Iop_SarN8x16: vex_printf("SarN8x16"); return;
544       case Iop_SarN16x8: vex_printf("SarN16x8"); return;
545       case Iop_SarN32x4: vex_printf("SarN32x4"); return;
546
547       case Iop_Shl8x16: vex_printf("Shl8x16"); return;
548       case Iop_Shl16x8: vex_printf("Shl16x8"); return;
549       case Iop_Shl32x4: vex_printf("Shl32x4"); return;
550       case Iop_Shr8x16: vex_printf("Shr8x16"); return;
551       case Iop_Shr16x8: vex_printf("Shr16x8"); return;
552       case Iop_Shr32x4: vex_printf("Shr32x4"); return;
553       case Iop_Sar8x16: vex_printf("Sar8x16"); return;
554       case Iop_Sar16x8: vex_printf("Sar16x8"); return;
555       case Iop_Sar32x4: vex_printf("Sar32x4"); return;
556       case Iop_Rol8x16: vex_printf("Rol8x16"); return;
557       case Iop_Rol16x8: vex_printf("Rol16x8"); return;
558       case Iop_Rol32x4: vex_printf("Rol32x4"); return;
559
560       case Iop_Narrow16x8:   vex_printf("Narrow16x8"); return;
561       case Iop_Narrow32x4:   vex_printf("Narrow32x4"); return;
562       case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return;
563       case Iop_QNarrow32Ux4: vex_printf("QNarrow32Ux4"); return;
564       case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return;
565       case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return;
566
567       case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
568       case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
569       case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
570       case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
571       case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
572       case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
573       case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
574       case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
575
576       case Iop_Perm8x16: vex_printf("Perm8x16"); return;
577
578       default: vpanic("ppIROp(1)");
579    }
580
581    vassert(str);  
582    switch (op - base) {
583       case 0: vex_printf("%s",str); vex_printf("8"); break;
584       case 1: vex_printf("%s",str); vex_printf("16"); break;
585       case 2: vex_printf("%s",str); vex_printf("32"); break;
586       case 3: vex_printf("%s",str); vex_printf("64"); break;
587       default: vpanic("ppIROp(2)");
588    }
589 }
590
591 void ppIRExpr ( IRExpr* e )
592 {
593   Int i;
594   switch (e->tag) {
595     case Iex_Binder:
596       vex_printf("BIND-%d", e->Iex.Binder.binder);
597       break;
598     case Iex_Get:
599       vex_printf( "GET:" );
600       ppIRType(e->Iex.Get.ty);
601       vex_printf("(%d)", e->Iex.Get.offset);
602       break;
603     case Iex_GetI:
604       vex_printf( "GETI" );
605       ppIRRegArray(e->Iex.GetI.descr);
606       vex_printf("[");
607       ppIRExpr(e->Iex.GetI.ix);
608       vex_printf(",%d]", e->Iex.GetI.bias);
609       break;
610     case Iex_RdTmp:
611       ppIRTemp(e->Iex.RdTmp.tmp);
612       break;
613     case Iex_Qop:
614       ppIROp(e->Iex.Qop.op);
615       vex_printf( "(" );
616       ppIRExpr(e->Iex.Qop.arg1);
617       vex_printf( "," );
618       ppIRExpr(e->Iex.Qop.arg2);
619       vex_printf( "," );
620       ppIRExpr(e->Iex.Qop.arg3);
621       vex_printf( "," );
622       ppIRExpr(e->Iex.Qop.arg4);
623       vex_printf( ")" );
624       break;
625     case Iex_Triop:
626       ppIROp(e->Iex.Triop.op);
627       vex_printf( "(" );
628       ppIRExpr(e->Iex.Triop.arg1);
629       vex_printf( "," );
630       ppIRExpr(e->Iex.Triop.arg2);
631       vex_printf( "," );
632       ppIRExpr(e->Iex.Triop.arg3);
633       vex_printf( ")" );
634       break;
635     case Iex_Binop:
636       ppIROp(e->Iex.Binop.op);
637       vex_printf( "(" );
638       ppIRExpr(e->Iex.Binop.arg1);
639       vex_printf( "," );
640       ppIRExpr(e->Iex.Binop.arg2);
641       vex_printf( ")" );
642       break;
643     case Iex_Unop:
644       ppIROp(e->Iex.Unop.op);
645       vex_printf( "(" );
646       ppIRExpr(e->Iex.Unop.arg);
647       vex_printf( ")" );
648       break;
649     case Iex_Load:
650       vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" );
651       ppIRType(e->Iex.Load.ty);
652       vex_printf( "(" );
653       ppIRExpr(e->Iex.Load.addr);
654       vex_printf( ")" );
655       break;
656     case Iex_Const:
657       ppIRConst(e->Iex.Const.con);
658       break;
659     case Iex_CCall:
660       ppIRCallee(e->Iex.CCall.cee);
661       vex_printf("(");
662       for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
663         ppIRExpr(e->Iex.CCall.args[i]);
664         if (e->Iex.CCall.args[i+1] != NULL)
665           vex_printf(",");
666       }
667       vex_printf("):");
668       ppIRType(e->Iex.CCall.retty);
669       break;
670     case Iex_Mux0X:
671       vex_printf("Mux0X(");
672       ppIRExpr(e->Iex.Mux0X.cond);
673       vex_printf(",");
674       ppIRExpr(e->Iex.Mux0X.expr0);
675       vex_printf(",");
676       ppIRExpr(e->Iex.Mux0X.exprX);
677       vex_printf(")");
678       break;
679     default:
680       vpanic("ppIRExpr");
681   }
682 }
683
684 void ppIREffect ( IREffect fx )
685 {
686    switch (fx) {
687       case Ifx_None:   vex_printf("noFX"); return;
688       case Ifx_Read:   vex_printf("RdFX"); return;
689       case Ifx_Write:  vex_printf("WrFX"); return;
690       case Ifx_Modify: vex_printf("MoFX"); return;
691       default: vpanic("ppIREffect");
692    }
693 }
694
695 void ppIRDirty ( IRDirty* d )
696 {
697    Int i;
698    if (d->tmp != IRTemp_INVALID) {
699       ppIRTemp(d->tmp);
700       vex_printf(" = ");
701    }
702    vex_printf("DIRTY ");
703    ppIRExpr(d->guard);
704    if (d->needsBBP)
705       vex_printf(" NeedsBBP");
706    if (d->mFx != Ifx_None) {
707       vex_printf(" ");
708       ppIREffect(d->mFx);
709       vex_printf("-mem(");
710       ppIRExpr(d->mAddr);
711       vex_printf(",%d)", d->mSize);
712    }
713    for (i = 0; i < d->nFxState; i++) {
714       vex_printf(" ");
715       ppIREffect(d->fxState[i].fx);
716       vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
717    }
718    vex_printf(" ::: ");
719    ppIRCallee(d->cee);
720    vex_printf("(");
721    for (i = 0; d->args[i] != NULL; i++) {
722       ppIRExpr(d->args[i]);
723       if (d->args[i+1] != NULL) {
724          vex_printf(",");
725       }
726    }
727    vex_printf(")");
728 }
729
730 void ppIRCAS ( IRCAS* cas )
731 {
732    /* Print even structurally invalid constructions, as an aid to
733       debugging. */
734    if (cas->oldHi != IRTemp_INVALID) {
735       ppIRTemp(cas->oldHi);
736       vex_printf(",");
737    }
738    ppIRTemp(cas->oldLo);
739    vex_printf(" = CAS%s(", cas->end==Iend_LE ? "le" : "be" );
740    ppIRExpr(cas->addr);
741    vex_printf("::");
742    if (cas->expdHi) {
743       ppIRExpr(cas->expdHi);
744       vex_printf(",");
745    }
746    ppIRExpr(cas->expdLo);
747    vex_printf("->");
748    if (cas->dataHi) {
749       ppIRExpr(cas->dataHi);
750       vex_printf(",");
751    }
752    ppIRExpr(cas->dataLo);
753    vex_printf(")");
754 }
755
756 void ppIRJumpKind ( IRJumpKind kind )
757 {
758    switch (kind) {
759       case Ijk_Boring:       vex_printf("Boring"); break;
760       case Ijk_Call:         vex_printf("Call"); break;
761       case Ijk_Ret:          vex_printf("Return"); break;
762       case Ijk_ClientReq:    vex_printf("ClientReq"); break;
763       case Ijk_Yield:        vex_printf("Yield"); break;
764       case Ijk_EmWarn:       vex_printf("EmWarn"); break;
765       case Ijk_EmFail:       vex_printf("EmFail"); break;
766       case Ijk_NoDecode:     vex_printf("NoDecode"); break;
767       case Ijk_MapFail:      vex_printf("MapFail"); break;
768       case Ijk_TInval:       vex_printf("Invalidate"); break;
769       case Ijk_NoRedir:      vex_printf("NoRedir"); break;
770       case Ijk_SigTRAP:      vex_printf("SigTRAP"); break;
771       case Ijk_SigSEGV:      vex_printf("SigSEGV"); break;
772       case Ijk_SigBUS:       vex_printf("SigBUS"); break;
773       case Ijk_Sys_syscall:  vex_printf("Sys_syscall"); break;
774       case Ijk_Sys_int32:    vex_printf("Sys_int32"); break;
775       case Ijk_Sys_int48:    vex_printf("Sys_int48"); break;
776       case Ijk_Sys_int50:    vex_printf("Sys_int50"); break;
777       case Ijk_Sys_int128:   vex_printf("Sys_int128"); break;
778       case Ijk_Sys_int129:   vex_printf("Sys_int129"); break;
779       case Ijk_Sys_int130:   vex_printf("Sys_int130"); break;
780       case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break;
781       case Ijk_l4_utcb_eax:  vex_printf("l4_utcb_eax"); break;
782       case Ijk_l4_utcb_ebx:  vex_printf("l4_utcb_ebx"); break;
783       case Ijk_l4_utcb_ecx:  vex_printf("l4_utcb_ecx"); break;
784       case Ijk_l4_utcb_edx:  vex_printf("l4_utcb_edx"); break;
785       case Ijk_l4_utcb_edi:  vex_printf("l4_utcb_edi"); break;
786       case Ijk_l4_utcb_esi:  vex_printf("l4_utcb_esi"); break;
787           case Ijk_l4_ud2:       vex_printf("l4_ud2"); break;
788           case Ijk_l4_artificial: vex_printf("l4_artificial_trap"); break;
789       default:               vpanic("ppIRJumpKind");
790    }
791 }
792
793 void ppIRMBusEvent ( IRMBusEvent event )
794 {
795    switch (event) {
796       case Imbe_Fence: vex_printf("Fence"); break;
797       default:         vpanic("ppIRMBusEvent");
798    }
799 }
800
801 void ppIRStmt ( IRStmt* s )
802 {
803    if (!s) {
804       vex_printf("!!! IRStmt* which is NULL !!!");
805       return;
806    }
807    switch (s->tag) {
808       case Ist_NoOp:
809          vex_printf("IR-NoOp");
810          break;
811       case Ist_IMark:
812          vex_printf( "------ IMark(0x%llx, %d) ------", 
813                      s->Ist.IMark.addr, s->Ist.IMark.len);
814          break;
815       case Ist_AbiHint:
816          vex_printf("====== AbiHint(");
817          ppIRExpr(s->Ist.AbiHint.base);
818          vex_printf(", %d, ", s->Ist.AbiHint.len);
819          ppIRExpr(s->Ist.AbiHint.nia);
820          vex_printf(") ======");
821          break;
822       case Ist_Put:
823          vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
824          ppIRExpr(s->Ist.Put.data);
825          break;
826       case Ist_PutI:
827          vex_printf( "PUTI" );
828          ppIRRegArray(s->Ist.PutI.descr);
829          vex_printf("[");
830          ppIRExpr(s->Ist.PutI.ix);
831          vex_printf(",%d] = ", s->Ist.PutI.bias);
832          ppIRExpr(s->Ist.PutI.data);
833          break;
834       case Ist_WrTmp:
835          ppIRTemp(s->Ist.WrTmp.tmp);
836          vex_printf( " = " );
837          ppIRExpr(s->Ist.WrTmp.data);
838          break;
839       case Ist_Store:
840          vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" );
841          ppIRExpr(s->Ist.Store.addr);
842          vex_printf( ") = ");
843          ppIRExpr(s->Ist.Store.data);
844          break;
845       case Ist_CAS:
846          ppIRCAS(s->Ist.CAS.details);
847          break;
848       case Ist_LLSC:
849          if (s->Ist.LLSC.storedata == NULL) {
850             ppIRTemp(s->Ist.LLSC.result);
851             vex_printf(" = LD%s-Linked(",
852                        s->Ist.LLSC.end==Iend_LE ? "le" : "be");
853             ppIRExpr(s->Ist.LLSC.addr);
854             vex_printf(")");
855          } else {
856             ppIRTemp(s->Ist.LLSC.result);
857             vex_printf(" = ( ST%s-Cond(",
858                        s->Ist.LLSC.end==Iend_LE ? "le" : "be");
859             ppIRExpr(s->Ist.LLSC.addr);
860             vex_printf(") = ");
861             ppIRExpr(s->Ist.LLSC.storedata);
862             vex_printf(" )");
863          }
864          break;
865       case Ist_Dirty:
866          ppIRDirty(s->Ist.Dirty.details);
867          break;
868       case Ist_MBE:
869          vex_printf("IR-");
870          ppIRMBusEvent(s->Ist.MBE.event);
871          break;
872       case Ist_Exit:
873          vex_printf( "if (" );
874          ppIRExpr(s->Ist.Exit.guard);
875          vex_printf( ") goto {");
876          ppIRJumpKind(s->Ist.Exit.jk);
877          vex_printf("} ");
878          ppIRConst(s->Ist.Exit.dst);
879          break;
880       default: 
881          vpanic("ppIRStmt");
882    }
883 }
884
885 void ppIRTypeEnv ( IRTypeEnv* env ) {
886    UInt i;
887    for (i = 0; i < env->types_used; i++) {
888       if (i % 8 == 0)
889          vex_printf( "   ");
890       ppIRTemp(i);
891       vex_printf( ":");
892       ppIRType(env->types[i]);
893       if (i % 8 == 7) 
894          vex_printf( "\n"); 
895       else 
896          vex_printf( "   ");
897    }
898    if (env->types_used > 0 && env->types_used % 8 != 7) 
899       vex_printf( "\n"); 
900 }
901
902 void ppIRSB ( IRSB* bb )
903 {
904    Int i;
905    vex_printf("IRSB {\n");
906    ppIRTypeEnv(bb->tyenv);
907    vex_printf("\n");
908    for (i = 0; i < bb->stmts_used; i++) {
909       vex_printf( "   ");
910       ppIRStmt(bb->stmts[i]);
911       vex_printf( "\n");
912    }
913    vex_printf( "   goto {");
914    ppIRJumpKind(bb->jumpkind);
915    vex_printf( "} ");
916    ppIRExpr( bb->next );
917    vex_printf( "\n}\n");
918 }
919
920
921 /*---------------------------------------------------------------*/
922 /*--- Constructors                                            ---*/
923 /*---------------------------------------------------------------*/
924
925
926 /* Constructors -- IRConst */
927
928 IRConst* IRConst_U1 ( Bool bit )
929 {
930    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
931    c->tag     = Ico_U1;
932    c->Ico.U1  = bit;
933    /* call me paranoid; I don't care :-) */
934    vassert(bit == False || bit == True);
935    return c;
936 }
937 IRConst* IRConst_U8 ( UChar u8 )
938 {
939    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
940    c->tag     = Ico_U8;
941    c->Ico.U8  = u8;
942    return c;
943 }
944 IRConst* IRConst_U16 ( UShort u16 )
945 {
946    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
947    c->tag     = Ico_U16;
948    c->Ico.U16 = u16;
949    return c;
950 }
951 IRConst* IRConst_U32 ( UInt u32 )
952 {
953    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
954    c->tag     = Ico_U32;
955    c->Ico.U32 = u32;
956    return c;
957 }
958 IRConst* IRConst_U64 ( ULong u64 )
959 {
960    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
961    c->tag     = Ico_U64;
962    c->Ico.U64 = u64;
963    return c;
964 }
965 IRConst* IRConst_F64 ( Double f64 )
966 {
967    IRConst* c = LibVEX_Alloc(sizeof(IRConst));
968    c->tag     = Ico_F64;
969    c->Ico.F64 = f64;
970    return c;
971 }
972 IRConst* IRConst_F64i ( ULong f64i )
973 {
974    IRConst* c  = LibVEX_Alloc(sizeof(IRConst));
975    c->tag      = Ico_F64i;
976    c->Ico.F64i = f64i;
977    return c;
978 }
979 IRConst* IRConst_V128 ( UShort con )
980 {
981    IRConst* c  = LibVEX_Alloc(sizeof(IRConst));
982    c->tag      = Ico_V128;
983    c->Ico.V128 = con;
984    return c;
985 }
986
987 /* Constructors -- IRCallee */
988
989 IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr )
990 {
991    IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
992    ce->regparms = regparms;
993    ce->name     = name;
994    ce->addr     = addr;
995    ce->mcx_mask = 0;
996    vassert(regparms >= 0 && regparms <= 3);
997    vassert(name != NULL);
998    vassert(addr != 0);
999    return ce;
1000 }
1001
1002
1003 /* Constructors -- IRRegArray */
1004
1005 IRRegArray* mkIRRegArray ( Int base, IRType elemTy, Int nElems )
1006 {
1007    IRRegArray* arr = LibVEX_Alloc(sizeof(IRRegArray));
1008    arr->base       = base;
1009    arr->elemTy     = elemTy;
1010    arr->nElems     = nElems;
1011    vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
1012    vassert(!(arr->elemTy == Ity_I1));
1013    vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
1014    return arr;
1015 }
1016
1017
1018 /* Constructors -- IRExpr */
1019
1020 IRExpr* IRExpr_Binder ( Int binder ) {
1021    IRExpr* e            = LibVEX_Alloc(sizeof(IRExpr));
1022    e->tag               = Iex_Binder;
1023    e->Iex.Binder.binder = binder;
1024    return e;
1025 }
1026 IRExpr* IRExpr_Get ( Int off, IRType ty ) {
1027    IRExpr* e         = LibVEX_Alloc(sizeof(IRExpr));
1028    e->tag            = Iex_Get;
1029    e->Iex.Get.offset = off;
1030    e->Iex.Get.ty     = ty;
1031    return e;
1032 }
1033 IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ) {
1034    IRExpr* e         = LibVEX_Alloc(sizeof(IRExpr));
1035    e->tag            = Iex_GetI;
1036    e->Iex.GetI.descr = descr;
1037    e->Iex.GetI.ix    = ix;
1038    e->Iex.GetI.bias  = bias;
1039    return e;
1040 }
1041 IRExpr* IRExpr_RdTmp ( IRTemp tmp ) {
1042    IRExpr* e        = LibVEX_Alloc(sizeof(IRExpr));
1043    e->tag           = Iex_RdTmp;
1044    e->Iex.RdTmp.tmp = tmp;
1045    return e;
1046 }
1047 IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2, 
1048                               IRExpr* arg3, IRExpr* arg4 ) {
1049    IRExpr* e       = LibVEX_Alloc(sizeof(IRExpr));
1050    e->tag          = Iex_Qop;
1051    e->Iex.Qop.op   = op;
1052    e->Iex.Qop.arg1 = arg1;
1053    e->Iex.Qop.arg2 = arg2;
1054    e->Iex.Qop.arg3 = arg3;
1055    e->Iex.Qop.arg4 = arg4;
1056    return e;
1057 }
1058 IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1, 
1059                                  IRExpr* arg2, IRExpr* arg3 ) {
1060    IRExpr* e         = LibVEX_Alloc(sizeof(IRExpr));
1061    e->tag            = Iex_Triop;
1062    e->Iex.Triop.op   = op;
1063    e->Iex.Triop.arg1 = arg1;
1064    e->Iex.Triop.arg2 = arg2;
1065    e->Iex.Triop.arg3 = arg3;
1066    return e;
1067 }
1068 IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
1069    IRExpr* e         = LibVEX_Alloc(sizeof(IRExpr));
1070    e->tag            = Iex_Binop;
1071    e->Iex.Binop.op   = op;
1072    e->Iex.Binop.arg1 = arg1;
1073    e->Iex.Binop.arg2 = arg2;
1074    return e;
1075 }
1076 IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
1077    IRExpr* e       = LibVEX_Alloc(sizeof(IRExpr));
1078    e->tag          = Iex_Unop;
1079    e->Iex.Unop.op  = op;
1080    e->Iex.Unop.arg = arg;
1081    return e;
1082 }
1083 IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) {
1084    IRExpr* e        = LibVEX_Alloc(sizeof(IRExpr));
1085    e->tag           = Iex_Load;
1086    e->Iex.Load.end  = end;
1087    e->Iex.Load.ty   = ty;
1088    e->Iex.Load.addr = addr;
1089    vassert(end == Iend_LE || end == Iend_BE);
1090    return e;
1091 }
1092 IRExpr* IRExpr_Const ( IRConst* con ) {
1093    IRExpr* e        = LibVEX_Alloc(sizeof(IRExpr));
1094    e->tag           = Iex_Const;
1095    e->Iex.Const.con = con;
1096    return e;
1097 }
1098 IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
1099    IRExpr* e          = LibVEX_Alloc(sizeof(IRExpr));
1100    e->tag             = Iex_CCall;
1101    e->Iex.CCall.cee   = cee;
1102    e->Iex.CCall.retty = retty;
1103    e->Iex.CCall.args  = args;
1104    return e;
1105 }
1106 IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
1107    IRExpr* e          = LibVEX_Alloc(sizeof(IRExpr));
1108    e->tag             = Iex_Mux0X;
1109    e->Iex.Mux0X.cond  = cond;
1110    e->Iex.Mux0X.expr0 = expr0;
1111    e->Iex.Mux0X.exprX = exprX;
1112    return e;
1113 }
1114
1115
1116 /* Constructors for NULL-terminated IRExpr expression vectors,
1117    suitable for use as arg lists in clean/dirty helper calls. */
1118
1119 IRExpr** mkIRExprVec_0 ( void ) {
1120    IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
1121    vec[0] = NULL;
1122    return vec;
1123 }
1124 IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
1125    IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
1126    vec[0] = arg1;
1127    vec[1] = NULL;
1128    return vec;
1129 }
1130 IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
1131    IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
1132    vec[0] = arg1;
1133    vec[1] = arg2;
1134    vec[2] = NULL;
1135    return vec;
1136 }
1137 IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
1138    IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
1139    vec[0] = arg1;
1140    vec[1] = arg2;
1141    vec[2] = arg3;
1142    vec[3] = NULL;
1143    return vec;
1144 }
1145 IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1146                          IRExpr* arg4 ) {
1147    IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
1148    vec[0] = arg1;
1149    vec[1] = arg2;
1150    vec[2] = arg3;
1151    vec[3] = arg4;
1152    vec[4] = NULL;
1153    return vec;
1154 }
1155 IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1156                          IRExpr* arg4, IRExpr* arg5 ) {
1157    IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
1158    vec[0] = arg1;
1159    vec[1] = arg2;
1160    vec[2] = arg3;
1161    vec[3] = arg4;
1162    vec[4] = arg5;
1163    vec[5] = NULL;
1164    return vec;
1165 }
1166 IRExpr** mkIRExprVec_6 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1167                          IRExpr* arg4, IRExpr* arg5, IRExpr* arg6 ) {
1168    IRExpr** vec = LibVEX_Alloc(7 * sizeof(IRExpr*));
1169    vec[0] = arg1;
1170    vec[1] = arg2;
1171    vec[2] = arg3;
1172    vec[3] = arg4;
1173    vec[4] = arg5;
1174    vec[5] = arg6;
1175    vec[6] = NULL;
1176    return vec;
1177 }
1178 IRExpr** mkIRExprVec_7 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1179                          IRExpr* arg4, IRExpr* arg5, IRExpr* arg6,
1180                          IRExpr* arg7 ) {
1181    IRExpr** vec = LibVEX_Alloc(8 * sizeof(IRExpr*));
1182    vec[0] = arg1;
1183    vec[1] = arg2;
1184    vec[2] = arg3;
1185    vec[3] = arg4;
1186    vec[4] = arg5;
1187    vec[5] = arg6;
1188    vec[6] = arg7;
1189    vec[7] = NULL;
1190    return vec;
1191 }
1192
1193
1194 /* Constructors -- IRDirty */
1195
1196 IRDirty* emptyIRDirty ( void ) {
1197    IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
1198    d->cee      = NULL;
1199    d->guard    = NULL;
1200    d->args     = NULL;
1201    d->tmp      = IRTemp_INVALID;
1202    d->mFx      = Ifx_None;
1203    d->mAddr    = NULL;
1204    d->mSize    = 0;
1205    d->needsBBP = False;
1206    d->nFxState = 0;
1207    return d;
1208 }
1209
1210
1211 /* Constructors -- IRCAS */
1212
1213 IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1214                  IREndness end, IRExpr* addr, 
1215                  IRExpr* expdHi, IRExpr* expdLo,
1216                  IRExpr* dataHi, IRExpr* dataLo ) {
1217    IRCAS* cas = LibVEX_Alloc(sizeof(IRCAS));
1218    cas->oldHi  = oldHi;
1219    cas->oldLo  = oldLo;
1220    cas->end    = end;
1221    cas->addr   = addr;
1222    cas->expdHi = expdHi;
1223    cas->expdLo = expdLo;
1224    cas->dataHi = dataHi;
1225    cas->dataLo = dataLo;
1226    return cas;
1227 }
1228
1229
1230 /* Constructors -- IRStmt */
1231
1232 IRStmt* IRStmt_NoOp ( void )
1233 {
1234    /* Just use a single static closure. */
1235    static IRStmt static_closure;
1236    static_closure.tag = Ist_NoOp;
1237    return &static_closure;
1238 }
1239 IRStmt* IRStmt_IMark ( Addr64 addr, Int len ) {
1240    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1241    s->tag            = Ist_IMark;
1242    s->Ist.IMark.addr = addr;
1243    s->Ist.IMark.len  = len;
1244    return s;
1245 }
1246 IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ) {
1247    IRStmt* s           = LibVEX_Alloc(sizeof(IRStmt));
1248    s->tag              = Ist_AbiHint;
1249    s->Ist.AbiHint.base = base;
1250    s->Ist.AbiHint.len  = len;
1251    s->Ist.AbiHint.nia  = nia;
1252    return s;
1253 }
1254 IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
1255    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1256    s->tag            = Ist_Put;
1257    s->Ist.Put.offset = off;
1258    s->Ist.Put.data   = data;
1259    return s;
1260 }
1261 IRStmt* IRStmt_PutI ( IRRegArray* descr, IRExpr* ix,
1262                       Int bias, IRExpr* data ) {
1263    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1264    s->tag            = Ist_PutI;
1265    s->Ist.PutI.descr = descr;
1266    s->Ist.PutI.ix    = ix;
1267    s->Ist.PutI.bias  = bias;
1268    s->Ist.PutI.data  = data;
1269    return s;
1270 }
1271 IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ) {
1272    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1273    s->tag            = Ist_WrTmp;
1274    s->Ist.WrTmp.tmp  = tmp;
1275    s->Ist.WrTmp.data = data;
1276    return s;
1277 }
1278 IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) {
1279    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1280    s->tag            = Ist_Store;
1281    s->Ist.Store.end  = end;
1282    s->Ist.Store.addr = addr;
1283    s->Ist.Store.data = data;
1284    vassert(end == Iend_LE || end == Iend_BE);
1285    return s;
1286 }
1287 IRStmt* IRStmt_CAS ( IRCAS* cas ) {
1288    IRStmt* s          = LibVEX_Alloc(sizeof(IRStmt));
1289    s->tag             = Ist_CAS;
1290    s->Ist.CAS.details = cas;
1291    return s;
1292 }
1293 IRStmt* IRStmt_LLSC ( IREndness end,
1294                       IRTemp result, IRExpr* addr, IRExpr* storedata ) {
1295    IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1296    s->tag                = Ist_LLSC;
1297    s->Ist.LLSC.end       = end;
1298    s->Ist.LLSC.result    = result;
1299    s->Ist.LLSC.addr      = addr;
1300    s->Ist.LLSC.storedata = storedata;
1301    return s;
1302 }
1303 IRStmt* IRStmt_Dirty ( IRDirty* d )
1304 {
1305    IRStmt* s            = LibVEX_Alloc(sizeof(IRStmt));
1306    s->tag               = Ist_Dirty;
1307    s->Ist.Dirty.details = d;
1308    return s;
1309 }
1310 IRStmt* IRStmt_MBE ( IRMBusEvent event )
1311 {
1312    IRStmt* s        = LibVEX_Alloc(sizeof(IRStmt));
1313    s->tag           = Ist_MBE;
1314    s->Ist.MBE.event = event;
1315    return s;
1316 }
1317 IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
1318    IRStmt* s         = LibVEX_Alloc(sizeof(IRStmt));
1319    s->tag            = Ist_Exit;
1320    s->Ist.Exit.guard = guard;
1321    s->Ist.Exit.jk    = jk;
1322    s->Ist.Exit.dst   = dst;
1323    return s;
1324 }
1325
1326
1327 /* Constructors -- IRTypeEnv */
1328
1329 IRTypeEnv* emptyIRTypeEnv ( void )
1330 {
1331    IRTypeEnv* env   = LibVEX_Alloc(sizeof(IRTypeEnv));
1332    env->types       = LibVEX_Alloc(8 * sizeof(IRType));
1333    env->types_size  = 8;
1334    env->types_used  = 0;
1335    return env;
1336 }
1337
1338
1339 /* Constructors -- IRSB */
1340
1341 IRSB* emptyIRSB ( void )
1342 {
1343    IRSB* bb       = LibVEX_Alloc(sizeof(IRSB));
1344    bb->tyenv      = emptyIRTypeEnv();
1345    bb->stmts_used = 0;
1346    bb->stmts_size = 8;
1347    bb->stmts      = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
1348    bb->next       = NULL;
1349    bb->jumpkind   = Ijk_Boring;
1350    return bb;
1351 }
1352
1353
1354 /*---------------------------------------------------------------*/
1355 /*--- (Deep) copy constructors.  These make complete copies   ---*/
1356 /*--- the original, which can be modified without affecting   ---*/
1357 /*--- the original.                                           ---*/
1358 /*---------------------------------------------------------------*/
1359
1360 /* Copying IR Expr vectors (for call args). */
1361
1362 /* Shallow copy of an IRExpr vector */
1363
1364 IRExpr** shallowCopyIRExprVec ( IRExpr** vec )
1365 {
1366    Int      i;
1367    IRExpr** newvec;
1368    for (i = 0; vec[i]; i++)
1369       ;
1370    newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
1371    for (i = 0; vec[i]; i++)
1372       newvec[i] = vec[i];
1373    newvec[i] = NULL;
1374    return newvec;
1375 }
1376
1377 /* Deep copy of an IRExpr vector */
1378
1379 IRExpr** deepCopyIRExprVec ( IRExpr** vec )
1380 {
1381    Int      i;
1382    IRExpr** newvec = shallowCopyIRExprVec( vec );
1383    for (i = 0; newvec[i]; i++)
1384       newvec[i] = deepCopyIRExpr(newvec[i]);
1385    return newvec;
1386 }
1387
1388 /* Deep copy constructors for all heap-allocated IR types follow. */
1389
1390 IRConst* deepCopyIRConst ( IRConst* c )
1391 {
1392    switch (c->tag) {
1393       case Ico_U1:   return IRConst_U1(c->Ico.U1);
1394       case Ico_U8:   return IRConst_U8(c->Ico.U8);
1395       case Ico_U16:  return IRConst_U16(c->Ico.U16);
1396       case Ico_U32:  return IRConst_U32(c->Ico.U32);
1397       case Ico_U64:  return IRConst_U64(c->Ico.U64);
1398       case Ico_F64:  return IRConst_F64(c->Ico.F64);
1399       case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
1400       case Ico_V128: return IRConst_V128(c->Ico.V128);
1401       default: vpanic("deepCopyIRConst");
1402    }
1403 }
1404
1405 IRCallee* deepCopyIRCallee ( IRCallee* ce )
1406 {
1407    IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
1408    ce2->mcx_mask = ce->mcx_mask;
1409    return ce2;
1410 }
1411
1412 IRRegArray* deepCopyIRRegArray ( IRRegArray* d )
1413 {
1414    return mkIRRegArray(d->base, d->elemTy, d->nElems);
1415 }
1416
1417 IRExpr* deepCopyIRExpr ( IRExpr* e )
1418 {
1419    switch (e->tag) {
1420       case Iex_Get: 
1421          return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
1422       case Iex_GetI: 
1423          return IRExpr_GetI(deepCopyIRRegArray(e->Iex.GetI.descr), 
1424                             deepCopyIRExpr(e->Iex.GetI.ix),
1425                             e->Iex.GetI.bias);
1426       case Iex_RdTmp: 
1427          return IRExpr_RdTmp(e->Iex.RdTmp.tmp);
1428       case Iex_Qop: 
1429          return IRExpr_Qop(e->Iex.Qop.op,
1430                            deepCopyIRExpr(e->Iex.Qop.arg1),
1431                            deepCopyIRExpr(e->Iex.Qop.arg2),
1432                            deepCopyIRExpr(e->Iex.Qop.arg3),
1433                            deepCopyIRExpr(e->Iex.Qop.arg4));
1434       case Iex_Triop: 
1435          return IRExpr_Triop(e->Iex.Triop.op,
1436                              deepCopyIRExpr(e->Iex.Triop.arg1),
1437                              deepCopyIRExpr(e->Iex.Triop.arg2),
1438                              deepCopyIRExpr(e->Iex.Triop.arg3));
1439       case Iex_Binop: 
1440          return IRExpr_Binop(e->Iex.Binop.op,
1441                              deepCopyIRExpr(e->Iex.Binop.arg1),
1442                              deepCopyIRExpr(e->Iex.Binop.arg2));
1443       case Iex_Unop: 
1444          return IRExpr_Unop(e->Iex.Unop.op,
1445                             deepCopyIRExpr(e->Iex.Unop.arg));
1446       case Iex_Load: 
1447          return IRExpr_Load(e->Iex.Load.end,
1448                             e->Iex.Load.ty,
1449                             deepCopyIRExpr(e->Iex.Load.addr));
1450       case Iex_Const: 
1451          return IRExpr_Const(deepCopyIRConst(e->Iex.Const.con));
1452       case Iex_CCall:
1453          return IRExpr_CCall(deepCopyIRCallee(e->Iex.CCall.cee),
1454                              e->Iex.CCall.retty,
1455                              deepCopyIRExprVec(e->Iex.CCall.args));
1456
1457       case Iex_Mux0X: 
1458          return IRExpr_Mux0X(deepCopyIRExpr(e->Iex.Mux0X.cond),
1459                              deepCopyIRExpr(e->Iex.Mux0X.expr0),
1460                              deepCopyIRExpr(e->Iex.Mux0X.exprX));
1461       default:
1462          vpanic("deepCopyIRExpr");
1463    }
1464 }
1465
1466 IRDirty* deepCopyIRDirty ( IRDirty* d )
1467 {
1468    Int      i;
1469    IRDirty* d2 = emptyIRDirty();
1470    d2->cee   = deepCopyIRCallee(d->cee);
1471    d2->guard = deepCopyIRExpr(d->guard);
1472    d2->args  = deepCopyIRExprVec(d->args);
1473    d2->tmp   = d->tmp;
1474    d2->mFx   = d->mFx;
1475    d2->mAddr = d->mAddr==NULL ? NULL : deepCopyIRExpr(d->mAddr);
1476    d2->mSize = d->mSize;
1477    d2->needsBBP = d->needsBBP;
1478    d2->nFxState = d->nFxState;
1479    for (i = 0; i < d2->nFxState; i++)
1480       d2->fxState[i] = d->fxState[i];
1481    return d2;
1482 }
1483
1484 IRCAS* deepCopyIRCAS ( IRCAS* cas )
1485 {
1486    return mkIRCAS( cas->oldHi, cas->oldLo, cas->end,
1487                    deepCopyIRExpr(cas->addr),
1488                    cas->expdHi==NULL ? NULL : deepCopyIRExpr(cas->expdHi),
1489                    deepCopyIRExpr(cas->expdLo),
1490                    cas->dataHi==NULL ? NULL : deepCopyIRExpr(cas->dataHi),
1491                    deepCopyIRExpr(cas->dataLo) );
1492 }
1493
1494 IRStmt* deepCopyIRStmt ( IRStmt* s )
1495 {
1496    switch (s->tag) {
1497       case Ist_NoOp:
1498          return IRStmt_NoOp();
1499       case Ist_AbiHint:
1500          return IRStmt_AbiHint(deepCopyIRExpr(s->Ist.AbiHint.base),
1501                                s->Ist.AbiHint.len,
1502                                deepCopyIRExpr(s->Ist.AbiHint.nia));
1503       case Ist_IMark:
1504          return IRStmt_IMark(s->Ist.IMark.addr, s->Ist.IMark.len);
1505       case Ist_Put: 
1506          return IRStmt_Put(s->Ist.Put.offset, 
1507                            deepCopyIRExpr(s->Ist.Put.data));
1508       case Ist_PutI: 
1509          return IRStmt_PutI(deepCopyIRRegArray(s->Ist.PutI.descr),
1510                             deepCopyIRExpr(s->Ist.PutI.ix),
1511                             s->Ist.PutI.bias, 
1512                             deepCopyIRExpr(s->Ist.PutI.data));
1513       case Ist_WrTmp:
1514          return IRStmt_WrTmp(s->Ist.WrTmp.tmp,
1515                              deepCopyIRExpr(s->Ist.WrTmp.data));
1516       case Ist_Store: 
1517          return IRStmt_Store(s->Ist.Store.end,
1518                              deepCopyIRExpr(s->Ist.Store.addr),
1519                              deepCopyIRExpr(s->Ist.Store.data));
1520       case Ist_CAS:
1521          return IRStmt_CAS(deepCopyIRCAS(s->Ist.CAS.details));
1522       case Ist_LLSC:
1523          return IRStmt_LLSC(s->Ist.LLSC.end,
1524                             s->Ist.LLSC.result,
1525                             deepCopyIRExpr(s->Ist.LLSC.addr),
1526                             s->Ist.LLSC.storedata
1527                                ? deepCopyIRExpr(s->Ist.LLSC.storedata)
1528                                : NULL);
1529       case Ist_Dirty: 
1530          return IRStmt_Dirty(deepCopyIRDirty(s->Ist.Dirty.details));
1531       case Ist_MBE:
1532          return IRStmt_MBE(s->Ist.MBE.event);
1533       case Ist_Exit: 
1534          return IRStmt_Exit(deepCopyIRExpr(s->Ist.Exit.guard),
1535                             s->Ist.Exit.jk,
1536                             deepCopyIRConst(s->Ist.Exit.dst));
1537       default: 
1538          vpanic("deepCopyIRStmt");
1539    }
1540 }
1541
1542 IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* src )
1543 {
1544    Int        i;
1545    IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
1546    dst->types_size = src->types_size;
1547    dst->types_used = src->types_used;
1548    dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
1549    for (i = 0; i < src->types_used; i++)
1550       dst->types[i] = src->types[i];
1551    return dst;
1552 }
1553
1554 IRSB* deepCopyIRSB ( IRSB* bb )
1555 {
1556    Int      i;
1557    IRStmt** sts2;
1558    IRSB* bb2 = deepCopyIRSBExceptStmts(bb);
1559    bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
1560    sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
1561    for (i = 0; i < bb2->stmts_used; i++)
1562       sts2[i] = deepCopyIRStmt(bb->stmts[i]);
1563    bb2->stmts    = sts2;
1564    return bb2;
1565 }
1566
1567 IRSB* deepCopyIRSBExceptStmts ( IRSB* bb )
1568 {
1569    IRSB* bb2     = emptyIRSB();
1570    bb2->tyenv    = deepCopyIRTypeEnv(bb->tyenv);
1571    bb2->next     = deepCopyIRExpr(bb->next);
1572    bb2->jumpkind = bb->jumpkind;
1573    return bb2;
1574 }
1575
1576
1577 /*---------------------------------------------------------------*/
1578 /*--- Primop types                                            ---*/
1579 /*---------------------------------------------------------------*/
1580
1581 static
1582 void typeOfPrimop ( IROp op, 
1583                     /*OUTs*/
1584                     IRType* t_dst, 
1585                     IRType* t_arg1, IRType* t_arg2, 
1586                     IRType* t_arg3, IRType* t_arg4 )
1587 {
1588 #  define UNARY(_ta1,_td)                                      \
1589       *t_dst = (_td); *t_arg1 = (_ta1); break
1590 #  define BINARY(_ta1,_ta2,_td)                                \
1591      *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
1592 #  define TERNARY(_ta1,_ta2,_ta3,_td)                          \
1593      *t_dst = (_td); *t_arg1 = (_ta1);                         \
1594      *t_arg2 = (_ta2); *t_arg3 = (_ta3); break
1595 #  define QUATERNARY(_ta1,_ta2,_ta3,_ta4,_td)                  \
1596      *t_dst = (_td); *t_arg1 = (_ta1);                         \
1597      *t_arg2 = (_ta2); *t_arg3 = (_ta3);                       \
1598      *t_arg4 = (_ta4); break
1599 #  define COMPARISON(_ta)                                      \
1600      *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
1601 #  define UNARY_COMPARISON(_ta)                                \
1602      *t_dst = Ity_I1; *t_arg1 = (_ta); break;
1603
1604    /* Rounding mode values are always Ity_I32, encoded as per
1605       IRRoundingMode */
1606    const IRType ity_RMode = Ity_I32;
1607
1608    *t_dst  = Ity_INVALID;
1609    *t_arg1 = Ity_INVALID;
1610    *t_arg2 = Ity_INVALID;
1611    *t_arg3 = Ity_INVALID;
1612    *t_arg4 = Ity_INVALID;
1613    switch (op) {
1614       case Iop_Add8: case Iop_Sub8: case Iop_Mul8: 
1615       case Iop_Or8:  case Iop_And8: case Iop_Xor8:
1616          BINARY(Ity_I8,Ity_I8, Ity_I8);
1617
1618       case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
1619       case Iop_Or16:  case Iop_And16: case Iop_Xor16:
1620          BINARY(Ity_I16,Ity_I16, Ity_I16);
1621
1622       case Iop_CmpORD32U:
1623       case Iop_CmpORD32S:
1624       case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
1625       case Iop_Or32:  case Iop_And32: case Iop_Xor32:
1626       case Iop_Max32U:
1627          BINARY(Ity_I32,Ity_I32, Ity_I32);
1628
1629       case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
1630       case Iop_Or64:  case Iop_And64: case Iop_Xor64:
1631       case Iop_CmpORD64U:
1632       case Iop_CmpORD64S:
1633       case Iop_Avg8Ux8: case Iop_Avg16Ux4:
1634       case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2:
1635       case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2:
1636       case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2:
1637       case Iop_InterleaveHI8x8: case Iop_InterleaveLO8x8:
1638       case Iop_InterleaveHI16x4: case Iop_InterleaveLO16x4:
1639       case Iop_InterleaveHI32x2: case Iop_InterleaveLO32x2:
1640       case Iop_CatOddLanes16x4: case Iop_CatEvenLanes16x4:
1641       case Iop_Perm8x8:
1642       case Iop_Max8Ux8: case Iop_Max16Sx4:
1643       case Iop_Min8Ux8: case Iop_Min16Sx4:
1644       case Iop_Mul16x4: case Iop_Mul32x2:
1645       case Iop_MulHi16Sx4: case Iop_MulHi16Ux4:
1646       case Iop_QAdd8Sx8: case Iop_QAdd16Sx4:
1647       case Iop_QAdd8Ux8: case Iop_QAdd16Ux4:
1648       case Iop_QNarrow32Sx2:
1649       case Iop_QNarrow16Sx4: case Iop_QNarrow16Ux4:
1650       case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2:
1651       case Iop_QSub8Sx8: case Iop_QSub16Sx4:
1652       case Iop_QSub8Ux8: case Iop_QSub16Ux4:
1653          BINARY(Ity_I64,Ity_I64, Ity_I64);
1654
1655       case Iop_ShlN32x2: case Iop_ShlN16x4: case Iop_ShlN8x8:
1656       case Iop_ShrN32x2: case Iop_ShrN16x4:
1657       case Iop_SarN32x2: case Iop_SarN16x4: case Iop_SarN8x8:
1658          BINARY(Ity_I64,Ity_I8, Ity_I64);
1659
1660       case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
1661          BINARY(Ity_I8,Ity_I8, Ity_I8);
1662       case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
1663          BINARY(Ity_I16,Ity_I8, Ity_I16);
1664       case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
1665          BINARY(Ity_I32,Ity_I8, Ity_I32);
1666       case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
1667          BINARY(Ity_I64,Ity_I8, Ity_I64);
1668
1669       case Iop_Not8:
1670          UNARY(Ity_I8, Ity_I8);
1671       case Iop_Not16:
1672          UNARY(Ity_I16, Ity_I16);
1673       case Iop_Not32:
1674          UNARY(Ity_I32, Ity_I32);
1675
1676       case Iop_Not64:
1677       case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8:
1678          UNARY(Ity_I64, Ity_I64);
1679
1680       case Iop_CmpEQ8: case Iop_CmpNE8:
1681       case Iop_CasCmpEQ8: case Iop_CasCmpNE8:
1682          COMPARISON(Ity_I8);
1683       case Iop_CmpEQ16: case Iop_CmpNE16:
1684       case Iop_CasCmpEQ16: case Iop_CasCmpNE16:
1685          COMPARISON(Ity_I16);
1686       case Iop_CmpEQ32: case Iop_CmpNE32:
1687       case Iop_CasCmpEQ32: case Iop_CasCmpNE32:
1688       case Iop_CmpLT32S: case Iop_CmpLE32S:
1689       case Iop_CmpLT32U: case Iop_CmpLE32U:
1690          COMPARISON(Ity_I32);
1691       case Iop_CmpEQ64: case Iop_CmpNE64:
1692       case Iop_CasCmpEQ64: case Iop_CasCmpNE64:
1693       case Iop_CmpLT64S: case Iop_CmpLE64S:
1694       case Iop_CmpLT64U: case Iop_CmpLE64U:
1695          COMPARISON(Ity_I64);
1696
1697       case Iop_CmpNEZ8:  UNARY_COMPARISON(Ity_I8);
1698       case Iop_CmpNEZ16: UNARY_COMPARISON(Ity_I16);
1699       case Iop_CmpNEZ32: UNARY_COMPARISON(Ity_I32);
1700       case Iop_CmpNEZ64: UNARY_COMPARISON(Ity_I64);
1701
1702       case Iop_Left8:  UNARY(Ity_I8, Ity_I8);
1703       case Iop_Left16: UNARY(Ity_I16,Ity_I16);
1704       case Iop_CmpwNEZ32: case Iop_Left32: UNARY(Ity_I32,Ity_I32);
1705       case Iop_CmpwNEZ64: case Iop_Left64: UNARY(Ity_I64,Ity_I64);
1706
1707       case Iop_MullU8: case Iop_MullS8:
1708          BINARY(Ity_I8,Ity_I8, Ity_I16);
1709       case Iop_MullU16: case Iop_MullS16:
1710          BINARY(Ity_I16,Ity_I16, Ity_I32);
1711       case Iop_MullU32: case Iop_MullS32:
1712          BINARY(Ity_I32,Ity_I32, Ity_I64);
1713       case Iop_MullU64: case Iop_MullS64:
1714          BINARY(Ity_I64,Ity_I64, Ity_I128);
1715
1716       case Iop_Clz32: case Iop_Ctz32:
1717          UNARY(Ity_I32, Ity_I32);
1718
1719       case Iop_Clz64: case Iop_Ctz64:
1720          UNARY(Ity_I64, Ity_I64);
1721
1722       case Iop_DivU32: case Iop_DivS32:
1723          BINARY(Ity_I32,Ity_I32, Ity_I32);
1724
1725       case Iop_DivU64: case Iop_DivS64:
1726          BINARY(Ity_I64,Ity_I64, Ity_I64);
1727
1728       case Iop_DivModU64to32: case Iop_DivModS64to32:
1729          BINARY(Ity_I64,Ity_I32, Ity_I64);
1730
1731       case Iop_DivModU128to64: case Iop_DivModS128to64:
1732          BINARY(Ity_I128,Ity_I64, Ity_I128);
1733
1734       case Iop_16HIto8: case Iop_16to8:
1735          UNARY(Ity_I16, Ity_I8);
1736       case Iop_8HLto16:
1737          BINARY(Ity_I8,Ity_I8, Ity_I16);
1738
1739       case Iop_32HIto16: case Iop_32to16:
1740          UNARY(Ity_I32, Ity_I16);
1741       case Iop_16HLto32:
1742          BINARY(Ity_I16,Ity_I16, Ity_I32);
1743
1744       case Iop_64HIto32: case Iop_64to32:
1745          UNARY(Ity_I64, Ity_I32);
1746       case Iop_32HLto64:
1747          BINARY(Ity_I32,Ity_I32, Ity_I64);
1748
1749       case Iop_128HIto64: case Iop_128to64:
1750          UNARY(Ity_I128, Ity_I64);
1751       case Iop_64HLto128:
1752          BINARY(Ity_I64,Ity_I64, Ity_I128);
1753
1754       case Iop_Not1:   UNARY(Ity_I1, Ity_I1);
1755       case Iop_1Uto8:  UNARY(Ity_I1, Ity_I8);
1756       case Iop_1Sto8:  UNARY(Ity_I1, Ity_I8);
1757       case Iop_1Sto16: UNARY(Ity_I1, Ity_I16);
1758       case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I1, Ity_I32);
1759       case Iop_1Sto64: case Iop_1Uto64: UNARY(Ity_I1, Ity_I64);
1760       case Iop_32to1:  UNARY(Ity_I32, Ity_I1);
1761       case Iop_64to1:  UNARY(Ity_I64, Ity_I1);
1762
1763       case Iop_8Uto32: case Iop_8Sto32:
1764          UNARY(Ity_I8, Ity_I32);
1765
1766       case Iop_8Uto16: case Iop_8Sto16:
1767          UNARY(Ity_I8, Ity_I16);
1768
1769       case Iop_16Uto32: case Iop_16Sto32: 
1770          UNARY(Ity_I16, Ity_I32);
1771
1772       case Iop_32Sto64: case Iop_32Uto64:
1773          UNARY(Ity_I32, Ity_I64);
1774
1775       case Iop_8Uto64: case Iop_8Sto64:
1776          UNARY(Ity_I8, Ity_I64);
1777
1778       case Iop_16Uto64: case Iop_16Sto64:
1779          UNARY(Ity_I16, Ity_I64);
1780       case Iop_64to16:
1781          UNARY(Ity_I64, Ity_I16);
1782
1783       case Iop_32to8: UNARY(Ity_I32, Ity_I8);
1784       case Iop_64to8: UNARY(Ity_I64, Ity_I8);
1785
1786       case Iop_AddF64:    case Iop_SubF64: 
1787       case Iop_MulF64:    case Iop_DivF64:
1788       case Iop_AddF64r32: case Iop_SubF64r32: 
1789       case Iop_MulF64r32: case Iop_DivF64r32:
1790          TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1791
1792       case Iop_AddF32: case Iop_SubF32:
1793       case Iop_MulF32: case Iop_DivF32:
1794          TERNARY(ity_RMode,Ity_F32,Ity_F32, Ity_F32);
1795
1796       case Iop_NegF64: case Iop_AbsF64: 
1797          UNARY(Ity_F64, Ity_F64);
1798
1799       case Iop_NegF32: case Iop_AbsF32:
1800          UNARY(Ity_F32, Ity_F32);
1801
1802       case Iop_SqrtF64:
1803       case Iop_SqrtF64r32:
1804          BINARY(ity_RMode,Ity_F64, Ity_F64);
1805
1806       case Iop_SqrtF32:
1807          BINARY(ity_RMode,Ity_F32, Ity_F32);
1808
1809       case Iop_CmpF64:
1810          BINARY(Ity_F64,Ity_F64, Ity_I32);
1811
1812       case Iop_F64toI16S: BINARY(ity_RMode,Ity_F64, Ity_I16);
1813       case Iop_F64toI32S: BINARY(ity_RMode,Ity_F64, Ity_I32);
1814       case Iop_F64toI64S: BINARY(ity_RMode,Ity_F64, Ity_I64);
1815
1816       case Iop_F64toI32U: BINARY(ity_RMode,Ity_F64, Ity_I32);
1817
1818       case Iop_I16StoF64: UNARY(Ity_I16, Ity_F64);
1819       case Iop_I32StoF64: UNARY(Ity_I32, Ity_F64);
1820       case Iop_I64StoF64: BINARY(ity_RMode,Ity_I64, Ity_F64);
1821
1822       case Iop_I32UtoF64: UNARY(Ity_I32, Ity_F64);
1823
1824       case Iop_F32toF64: UNARY(Ity_F32, Ity_F64);
1825       case Iop_F64toF32: BINARY(ity_RMode,Ity_F64, Ity_F32);
1826
1827       case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64);
1828       case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64);
1829       case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32);
1830       case Iop_ReinterpF32asI32: UNARY(Ity_F32, Ity_I32);
1831
1832       case Iop_AtanF64: case Iop_Yl2xF64:  case Iop_Yl2xp1F64: 
1833       case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
1834          TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1835
1836       case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
1837          TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_I32);
1838
1839       case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: 
1840       case Iop_2xm1F64:
1841       case Iop_RoundF64toInt: BINARY(ity_RMode,Ity_F64, Ity_F64);
1842
1843       case Iop_MAddF64: case Iop_MSubF64:
1844       case Iop_MAddF64r32: case Iop_MSubF64r32:
1845          QUATERNARY(ity_RMode,Ity_F64,Ity_F64,Ity_F64, Ity_F64);
1846
1847       case Iop_Est5FRSqrt:
1848       case Iop_RoundF64toF64_NEAREST: case Iop_RoundF64toF64_NegINF:
1849       case Iop_RoundF64toF64_PosINF: case Iop_RoundF64toF64_ZERO:
1850          UNARY(Ity_F64, Ity_F64);
1851       case Iop_RoundF64toF32:
1852          BINARY(ity_RMode,Ity_F64, Ity_F64);
1853       case Iop_CalcFPRF:
1854          UNARY(Ity_F64, Ity_I32);
1855       case Iop_TruncF64asF32:
1856          UNARY(Ity_F64, Ity_F32);
1857
1858       case Iop_I32UtoFx4:
1859       case Iop_I32StoFx4:
1860       case Iop_QFtoI32Ux4_RZ:
1861       case Iop_QFtoI32Sx4_RZ:
1862       case Iop_RoundF32x4_RM:
1863       case Iop_RoundF32x4_RP:
1864       case Iop_RoundF32x4_RN:
1865       case Iop_RoundF32x4_RZ:
1866          UNARY(Ity_V128, Ity_V128);
1867
1868       case Iop_64HLtoV128: BINARY(Ity_I64,Ity_I64, Ity_V128);
1869       case Iop_V128to64: case Iop_V128HIto64: 
1870          UNARY(Ity_V128, Ity_I64);
1871
1872       case Iop_V128to32:    UNARY(Ity_V128, Ity_I32);
1873       case Iop_32UtoV128:   UNARY(Ity_I32, Ity_V128);
1874       case Iop_64UtoV128:   UNARY(Ity_I64, Ity_V128);
1875       case Iop_SetV128lo32: BINARY(Ity_V128,Ity_I32, Ity_V128);
1876       case Iop_SetV128lo64: BINARY(Ity_V128,Ity_I64, Ity_V128);
1877
1878       case Iop_Dup8x16: UNARY(Ity_I8, Ity_V128);
1879       case Iop_Dup16x8: UNARY(Ity_I16, Ity_V128);
1880       case Iop_Dup32x4: UNARY(Ity_I32, Ity_V128);
1881
1882       case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
1883       case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
1884       case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
1885       case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
1886       case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4:
1887       case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
1888       case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
1889       case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
1890       case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
1891       case Iop_Add32Fx4: case Iop_Add32F0x4:
1892       case Iop_Add64Fx2: case Iop_Add64F0x2:
1893       case Iop_Div32Fx4: case Iop_Div32F0x4:
1894       case Iop_Div64Fx2: case Iop_Div64F0x2:
1895       case Iop_Max32Fx4: case Iop_Max32F0x4:
1896       case Iop_Max64Fx2: case Iop_Max64F0x2:
1897       case Iop_Min32Fx4: case Iop_Min32F0x4:
1898       case Iop_Min64Fx2: case Iop_Min64F0x2:
1899       case Iop_Mul32Fx4: case Iop_Mul32F0x4:
1900       case Iop_Mul64Fx2: case Iop_Mul64F0x2:
1901       case Iop_Sub32Fx4: case Iop_Sub32F0x4:
1902       case Iop_Sub64Fx2: case Iop_Sub64F0x2:
1903       case Iop_AndV128: case Iop_OrV128: case Iop_XorV128:
1904       case Iop_Add8x16:   case Iop_Add16x8:   
1905       case Iop_Add32x4:   case Iop_Add64x2:
1906       case Iop_QAdd8Ux16: case Iop_QAdd16Ux8: case Iop_QAdd32Ux4:
1907       case Iop_QAdd8Sx16: case Iop_QAdd16Sx8: case Iop_QAdd32Sx4:
1908       case Iop_Sub8x16:   case Iop_Sub16x8:
1909       case Iop_Sub32x4:   case Iop_Sub64x2:
1910       case Iop_QSub8Ux16: case Iop_QSub16Ux8: case Iop_QSub32Ux4:
1911       case Iop_QSub8Sx16: case Iop_QSub16Sx8: case Iop_QSub32Sx4:
1912       case Iop_Mul16x8:
1913       case Iop_MulHi16Ux8: case Iop_MulHi32Ux4: 
1914       case Iop_MulHi16Sx8: case Iop_MulHi32Sx4: 
1915       case Iop_MullEven8Ux16: case Iop_MullEven16Ux8:
1916       case Iop_MullEven8Sx16: case Iop_MullEven16Sx8:
1917       case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4:
1918       case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4:
1919       case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4:
1920       case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4:
1921       case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4:
1922       case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4:
1923       case Iop_CmpEQ8x16:  case Iop_CmpEQ16x8:  case Iop_CmpEQ32x4:
1924       case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
1925       case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4:
1926       case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4:
1927       case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4:
1928       case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4:
1929       case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4:
1930       case Iop_QNarrow16Ux8: case Iop_QNarrow32Ux4:
1931       case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4:
1932       case Iop_Narrow16x8:   case Iop_Narrow32x4:
1933       case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
1934       case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
1935       case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8: 
1936       case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
1937       case Iop_Perm8x16:
1938          BINARY(Ity_V128,Ity_V128, Ity_V128);
1939
1940       case Iop_NotV128:
1941       case Iop_Recip32Fx4: case Iop_Recip32F0x4:
1942       case Iop_Recip64Fx2: case Iop_Recip64F0x2:
1943       case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
1944       case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
1945       case Iop_Sqrt32Fx4:  case Iop_Sqrt32F0x4:
1946       case Iop_Sqrt64Fx2:  case Iop_Sqrt64F0x2:
1947       case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8:
1948       case Iop_CmpNEZ32x4: case Iop_CmpNEZ64x2:
1949          UNARY(Ity_V128, Ity_V128);
1950
1951       case Iop_ShlV128: case Iop_ShrV128:
1952       case Iop_ShlN8x16: case Iop_ShlN16x8: 
1953       case Iop_ShlN32x4: case Iop_ShlN64x2:
1954       case Iop_ShrN8x16: case Iop_ShrN16x8: 
1955       case Iop_ShrN32x4: case Iop_ShrN64x2:
1956       case Iop_SarN8x16: case Iop_SarN16x8: case Iop_SarN32x4:
1957          BINARY(Ity_V128,Ity_I8, Ity_V128);
1958
1959       default:
1960          ppIROp(op);
1961          vpanic("typeOfPrimop");
1962    }
1963 #  undef UNARY
1964 #  undef BINARY
1965 #  undef TERNARY
1966 #  undef COMPARISON
1967 #  undef UNARY_COMPARISON
1968 }
1969
1970
1971 /*---------------------------------------------------------------*/
1972 /*--- Helper functions for the IR -- IR Basic Blocks          ---*/
1973 /*---------------------------------------------------------------*/
1974
1975 void addStmtToIRSB ( IRSB* bb, IRStmt* st )
1976 {
1977    Int i;
1978    if (bb->stmts_used == bb->stmts_size) {
1979       IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1980       for (i = 0; i < bb->stmts_size; i++)
1981          stmts2[i] = bb->stmts[i];
1982       bb->stmts = stmts2;
1983       bb->stmts_size *= 2;
1984    }
1985    vassert(bb->stmts_used < bb->stmts_size);
1986    bb->stmts[bb->stmts_used] = st;
1987    bb->stmts_used++;
1988 }
1989
1990
1991 /*---------------------------------------------------------------*/
1992 /*--- Helper functions for the IR -- IR Type Environments     ---*/
1993 /*---------------------------------------------------------------*/
1994
1995 /* Allocate a new IRTemp, given its type. */
1996
1997 IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
1998 {
1999    vassert(env);
2000    vassert(env->types_used >= 0);
2001    vassert(env->types_size >= 0);
2002    vassert(env->types_used <= env->types_size);
2003    if (env->types_used < env->types_size) {
2004       env->types[env->types_used] = ty;
2005       return env->types_used++;
2006    } else {
2007       Int i;
2008       Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
2009       IRType* new_types 
2010          = LibVEX_Alloc(new_size * sizeof(IRType));
2011       for (i = 0; i < env->types_used; i++)
2012          new_types[i] = env->types[i];
2013       env->types      = new_types;
2014       env->types_size = new_size;
2015       return newIRTemp(env, ty);
2016    }
2017 }
2018
2019
2020 /*---------------------------------------------------------------*/
2021 /*--- Helper functions for the IR -- finding types of exprs   ---*/
2022 /*---------------------------------------------------------------*/
2023
2024 inline 
2025 IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
2026 {
2027    vassert(tmp >= 0);
2028    vassert(tmp < env->types_used);
2029    return env->types[tmp];
2030 }
2031
2032
2033 IRType typeOfIRConst ( IRConst* con )
2034 {
2035    switch (con->tag) {
2036       case Ico_U1:    return Ity_I1;
2037       case Ico_U8:    return Ity_I8;
2038       case Ico_U16:   return Ity_I16;
2039       case Ico_U32:   return Ity_I32;
2040       case Ico_U64:   return Ity_I64;
2041       case Ico_F64:   return Ity_F64;
2042       case Ico_F64i:  return Ity_F64;
2043       case Ico_V128:  return Ity_V128;
2044       default: vpanic("typeOfIRConst");
2045    }
2046 }
2047
2048 IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
2049 {
2050    IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
2051  start:
2052    switch (e->tag) {
2053       case Iex_Load:
2054          return e->Iex.Load.ty;
2055       case Iex_Get:
2056          return e->Iex.Get.ty;
2057       case Iex_GetI:
2058          return e->Iex.GetI.descr->elemTy;
2059       case Iex_RdTmp:
2060          return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp);
2061       case Iex_Const:
2062          return typeOfIRConst(e->Iex.Const.con);
2063       case Iex_Qop:
2064          typeOfPrimop(e->Iex.Qop.op, 
2065                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2066          return t_dst;
2067       case Iex_Triop:
2068          typeOfPrimop(e->Iex.Triop.op, 
2069                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2070          return t_dst;
2071       case Iex_Binop:
2072          typeOfPrimop(e->Iex.Binop.op, 
2073                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2074          return t_dst;
2075       case Iex_Unop:
2076          typeOfPrimop(e->Iex.Unop.op, 
2077                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2078          return t_dst;
2079       case Iex_CCall:
2080          return e->Iex.CCall.retty;
2081       case Iex_Mux0X:
2082          e = e->Iex.Mux0X.expr0;
2083          goto start;
2084          /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
2085       case Iex_Binder:
2086          vpanic("typeOfIRExpr: Binder is not a valid expression");
2087       default:
2088          ppIRExpr(e);
2089          vpanic("typeOfIRExpr");
2090    }
2091 }
2092
2093 /* Is this any value actually in the enumeration 'IRType' ? */
2094 Bool isPlausibleIRType ( IRType ty )
2095 {
2096    switch (ty) {
2097       case Ity_INVALID: case Ity_I1:
2098       case Ity_I8: case Ity_I16: case Ity_I32: 
2099       case Ity_I64: case Ity_I128:
2100       case Ity_F32: case Ity_F64:
2101       case Ity_V128:
2102          return True;
2103       default: 
2104          return False;
2105    }
2106 }
2107
2108
2109 /*---------------------------------------------------------------*/
2110 /*--- Sanity checking -- FLATNESS                             ---*/
2111 /*---------------------------------------------------------------*/
2112
2113 /* Check that the canonical flatness constraints hold on an
2114    IRStmt. The only place where any expression is allowed to be
2115    non-atomic is the RHS of IRStmt_Tmp. */
2116
2117 /* Relies on:
2118    inline static Bool isAtom ( IRExpr* e ) {
2119       return e->tag == Iex_RdTmp || e->tag == Iex_Const;
2120    }
2121 */
2122
2123 Bool isFlatIRStmt ( IRStmt* st )
2124 {
2125    Int      i;
2126    IRExpr*  e;
2127    IRDirty* di;
2128    IRCAS*   cas;
2129
2130    switch (st->tag) {
2131       case Ist_AbiHint:
2132          return isIRAtom(st->Ist.AbiHint.base)
2133                 && isIRAtom(st->Ist.AbiHint.nia);
2134       case Ist_Put:
2135          return isIRAtom(st->Ist.Put.data);
2136       case Ist_PutI:
2137          return toBool( isIRAtom(st->Ist.PutI.ix) 
2138                         && isIRAtom(st->Ist.PutI.data) );
2139       case Ist_WrTmp:
2140          /* This is the only interesting case.  The RHS can be any
2141             expression, *but* all its subexpressions *must* be
2142             atoms. */
2143          e = st->Ist.WrTmp.data;
2144          switch (e->tag) {
2145             case Iex_Binder: return True;
2146             case Iex_Get:    return True;
2147             case Iex_GetI:   return isIRAtom(e->Iex.GetI.ix);
2148             case Iex_RdTmp:  return True;
2149             case Iex_Qop:    return toBool(
2150                                     isIRAtom(e->Iex.Qop.arg1) 
2151                                     && isIRAtom(e->Iex.Qop.arg2)
2152                                     && isIRAtom(e->Iex.Qop.arg3)
2153                                     && isIRAtom(e->Iex.Qop.arg4));
2154             case Iex_Triop:  return toBool(
2155                                     isIRAtom(e->Iex.Triop.arg1) 
2156                                     && isIRAtom(e->Iex.Triop.arg2)
2157                                     && isIRAtom(e->Iex.Triop.arg3));
2158             case Iex_Binop:  return toBool(
2159                                     isIRAtom(e->Iex.Binop.arg1) 
2160                                     && isIRAtom(e->Iex.Binop.arg2));
2161             case Iex_Unop:   return isIRAtom(e->Iex.Unop.arg);
2162             case Iex_Load:   return isIRAtom(e->Iex.Load.addr);
2163             case Iex_Const:  return True;
2164             case Iex_CCall:  for (i = 0; e->Iex.CCall.args[i]; i++)
2165                                 if (!isIRAtom(e->Iex.CCall.args[i])) 
2166                                    return False;
2167                              return True;
2168             case Iex_Mux0X:  return toBool (
2169                                     isIRAtom(e->Iex.Mux0X.cond) 
2170                                     && isIRAtom(e->Iex.Mux0X.expr0) 
2171                                     && isIRAtom(e->Iex.Mux0X.exprX));
2172             default:         vpanic("isFlatIRStmt(e)");
2173          }
2174          /*notreached*/
2175          vassert(0);
2176       case Ist_Store:
2177          return toBool( isIRAtom(st->Ist.Store.addr) 
2178                         && isIRAtom(st->Ist.Store.data) );
2179       case Ist_CAS:
2180          cas = st->Ist.CAS.details;
2181          return toBool( isIRAtom(cas->addr)
2182                         && (cas->expdHi ? isIRAtom(cas->expdHi) : True)
2183                         && isIRAtom(cas->expdLo)
2184                         && (cas->dataHi ? isIRAtom(cas->dataHi) : True)
2185                         && isIRAtom(cas->dataLo) );
2186       case Ist_LLSC:
2187          return toBool( isIRAtom(st->Ist.LLSC.addr)
2188                         && (st->Ist.LLSC.storedata
2189                                ? isIRAtom(st->Ist.LLSC.storedata) : True) );
2190       case Ist_Dirty:
2191          di = st->Ist.Dirty.details;
2192          if (!isIRAtom(di->guard)) 
2193             return False;
2194          for (i = 0; di->args[i]; i++)
2195             if (!isIRAtom(di->args[i])) 
2196                return False;
2197          if (di->mAddr && !isIRAtom(di->mAddr)) 
2198             return False;
2199          return True;
2200       case Ist_NoOp:
2201       case Ist_IMark:
2202       case Ist_MBE:
2203          return True;
2204       case Ist_Exit:
2205          return isIRAtom(st->Ist.Exit.guard);
2206       default: 
2207          vpanic("isFlatIRStmt(st)");
2208    }
2209 }
2210
2211
2212 /*---------------------------------------------------------------*/
2213 /*--- Sanity checking                                         ---*/
2214 /*---------------------------------------------------------------*/
2215
2216 /* Checks:
2217
2218    Everything is type-consistent.  No ill-typed anything.
2219    The target address at the end of the BB is a 32- or 64-
2220    bit expression, depending on the guest's word size.
2221
2222    Each temp is assigned only once, before its uses.
2223 */
2224
2225 static inline Int countArgs ( IRExpr** args )
2226 {
2227    Int i;
2228    for (i = 0; args[i]; i++)
2229       ;
2230    return i;
2231 }
2232
2233 static
2234 __attribute((noreturn))
2235 void sanityCheckFail ( IRSB* bb, IRStmt* stmt, HChar* what )
2236 {
2237    vex_printf("\nIR SANITY CHECK FAILURE\n\n");
2238    ppIRSB(bb);
2239    if (stmt) {
2240       vex_printf("\nIN STATEMENT:\n\n");
2241       ppIRStmt(stmt);
2242    }
2243    vex_printf("\n\nERROR = %s\n\n", what );
2244    vpanic("sanityCheckFail: exiting due to bad IR");
2245 }
2246
2247 static Bool saneIRRegArray ( IRRegArray* arr )
2248 {
2249    if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
2250       return False;
2251    if (arr->elemTy == Ity_I1)
2252       return False;
2253    if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
2254       return False;
2255    return True;
2256 }
2257
2258 static Bool saneIRCallee ( IRCallee* cee )
2259 {
2260    if (cee->name == NULL)
2261       return False;
2262    if (cee->addr == 0)
2263       return False;
2264    if (cee->regparms < 0 || cee->regparms > 3)
2265       return False;
2266    return True;
2267 }
2268
2269 static Bool saneIRConst ( IRConst* con )
2270 {
2271    switch (con->tag) {
2272       case Ico_U1: 
2273          return toBool( con->Ico.U1 == True || con->Ico.U1 == False );
2274       default: 
2275          /* Is there anything we can meaningfully check?  I don't
2276             think so. */
2277          return True;
2278    }
2279 }
2280
2281 /* Traverse a Stmt/Expr, inspecting IRTemp uses.  Report any out of
2282    range ones.  Report any which are read and for which the current
2283    def_count is zero. */
2284
2285 static
2286 void useBeforeDef_Temp ( IRSB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
2287 {
2288    if (tmp < 0 || tmp >= bb->tyenv->types_used)
2289       sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
2290    if (def_counts[tmp] < 1)
2291       sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
2292 }
2293
2294 static
2295 void useBeforeDef_Expr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
2296 {
2297    Int i;
2298    switch (expr->tag) {
2299       case Iex_Get: 
2300          break;
2301       case Iex_GetI:
2302          useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
2303          break;
2304       case Iex_RdTmp:
2305          useBeforeDef_Temp(bb,stmt,expr->Iex.RdTmp.tmp,def_counts);
2306          break;
2307       case Iex_Qop:
2308          useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg1,def_counts);
2309          useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg2,def_counts);
2310          useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg3,def_counts);
2311          useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg4,def_counts);
2312          break;
2313       case Iex_Triop:
2314          useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg1,def_counts);
2315          useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg2,def_counts);
2316          useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg3,def_counts);
2317          break;
2318       case Iex_Binop:
2319          useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
2320          useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
2321          break;
2322       case Iex_Unop:
2323          useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
2324          break;
2325       case Iex_Load:
2326          useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
2327          break;
2328       case Iex_Const:
2329          break;
2330       case Iex_CCall:
2331          for (i = 0; expr->Iex.CCall.args[i]; i++)
2332             useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
2333          break;
2334       case Iex_Mux0X:
2335          useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
2336          useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
2337          useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
2338          break;
2339       default:
2340          vpanic("useBeforeDef_Expr");
2341    }
2342 }
2343
2344 static
2345 void useBeforeDef_Stmt ( IRSB* bb, IRStmt* stmt, Int* def_counts )
2346 {
2347    Int      i;
2348    IRDirty* d;
2349    IRCAS*   cas;
2350    switch (stmt->tag) {
2351       case Ist_IMark:
2352          break;
2353       case Ist_AbiHint:
2354          useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
2355          useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.nia,def_counts);
2356          break;
2357       case Ist_Put:
2358          useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
2359          break;
2360       case Ist_PutI:
2361          useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
2362          useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
2363          break;
2364       case Ist_WrTmp:
2365          useBeforeDef_Expr(bb,stmt,stmt->Ist.WrTmp.data,def_counts);
2366          break;
2367       case Ist_Store:
2368          useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
2369          useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
2370          break;
2371       case Ist_CAS:
2372          cas = stmt->Ist.CAS.details;
2373          useBeforeDef_Expr(bb,stmt,cas->addr,def_counts);
2374          if (cas->expdHi)
2375             useBeforeDef_Expr(bb,stmt,cas->expdHi,def_counts);
2376          useBeforeDef_Expr(bb,stmt,cas->expdLo,def_counts);
2377          if (cas->dataHi)
2378             useBeforeDef_Expr(bb,stmt,cas->dataHi,def_counts);
2379          useBeforeDef_Expr(bb,stmt,cas->dataLo,def_counts);
2380          break;
2381       case Ist_LLSC:
2382          useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.addr,def_counts);
2383          if (stmt->Ist.LLSC.storedata != NULL)
2384             useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.storedata,def_counts);
2385          break;
2386       case Ist_Dirty:
2387          d = stmt->Ist.Dirty.details;
2388          for (i = 0; d->args[i] != NULL; i++)
2389             useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
2390          if (d->mFx != Ifx_None)
2391             useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
2392          break;
2393       case Ist_NoOp:
2394       case Ist_MBE:
2395          break;
2396       case Ist_Exit:
2397          useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
2398          break;
2399       default: 
2400          vpanic("useBeforeDef_Stmt");
2401    }
2402 }
2403
2404 static
2405 void tcExpr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
2406 {
2407    Int        i;
2408    IRType     t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
2409    IRTypeEnv* tyenv = bb->tyenv;
2410    switch (expr->tag) {
2411       case Iex_Get:
2412       case Iex_RdTmp:
2413          break;
2414       case Iex_GetI:
2415          tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
2416          if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
2417             sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
2418          if (!saneIRRegArray(expr->Iex.GetI.descr))
2419             sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
2420          break;
2421       case Iex_Qop: {
2422          IRType ttarg1, ttarg2, ttarg3, ttarg4;
2423          tcExpr(bb,stmt, expr->Iex.Qop.arg1, gWordTy );
2424          tcExpr(bb,stmt, expr->Iex.Qop.arg2, gWordTy );
2425          tcExpr(bb,stmt, expr->Iex.Qop.arg3, gWordTy );
2426          tcExpr(bb,stmt, expr->Iex.Qop.arg4, gWordTy );
2427          typeOfPrimop(expr->Iex.Qop.op, 
2428                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2429          if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 
2430              || t_arg3 == Ity_INVALID || t_arg4 == Ity_INVALID) {
2431             vex_printf(" op name: " );
2432             ppIROp(expr->Iex.Qop.op);
2433             vex_printf("\n");
2434             sanityCheckFail(bb,stmt,
2435                "Iex.Qop: wrong arity op\n"
2436                "... name of op precedes BB printout\n");
2437          }
2438          ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg1);
2439          ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg2);
2440          ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg3);
2441          ttarg4 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg4);
2442          if (t_arg1 != ttarg1 || t_arg2 != ttarg2 
2443              || t_arg3 != ttarg3 || t_arg4 != ttarg4) {
2444             vex_printf(" op name: ");
2445             ppIROp(expr->Iex.Qop.op);
2446             vex_printf("\n");
2447             vex_printf(" op type is (");
2448             ppIRType(t_arg1);
2449             vex_printf(",");
2450             ppIRType(t_arg2);
2451             vex_printf(",");
2452             ppIRType(t_arg3);
2453             vex_printf(",");
2454             ppIRType(t_arg4);
2455             vex_printf(") -> ");
2456             ppIRType (t_dst);
2457             vex_printf("\narg tys are (");
2458             ppIRType(ttarg1);
2459             vex_printf(",");
2460             ppIRType(ttarg2);
2461             vex_printf(",");
2462             ppIRType(ttarg3);
2463             vex_printf(",");
2464             ppIRType(ttarg4);
2465             vex_printf(")\n");
2466             sanityCheckFail(bb,stmt,
2467                "Iex.Qop: arg tys don't match op tys\n"
2468                "... additional details precede BB printout\n");
2469          }
2470          break;
2471       }
2472       case Iex_Triop: {
2473          IRType ttarg1, ttarg2, ttarg3;
2474          tcExpr(bb,stmt, expr->Iex.Triop.arg1, gWordTy );
2475          tcExpr(bb,stmt, expr->Iex.Triop.arg2, gWordTy );
2476          tcExpr(bb,stmt, expr->Iex.Triop.arg3, gWordTy );
2477          typeOfPrimop(expr->Iex.Triop.op, 
2478                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2479          if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 
2480              || t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) {
2481             vex_printf(" op name: " );
2482             ppIROp(expr->Iex.Triop.op);
2483             vex_printf("\n");
2484             sanityCheckFail(bb,stmt,
2485                "Iex.Triop: wrong arity op\n"
2486                "... name of op precedes BB printout\n");
2487          }
2488          ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg1);
2489          ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg2);
2490          ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg3);
2491          if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
2492             vex_printf(" op name: ");
2493             ppIROp(expr->Iex.Triop.op);
2494             vex_printf("\n");
2495             vex_printf(" op type is (");
2496             ppIRType(t_arg1);
2497             vex_printf(",");
2498             ppIRType(t_arg2);
2499             vex_printf(",");
2500             ppIRType(t_arg3);
2501             vex_printf(") -> ");
2502             ppIRType (t_dst);
2503             vex_printf("\narg tys are (");
2504             ppIRType(ttarg1);
2505             vex_printf(",");
2506             ppIRType(ttarg2);
2507             vex_printf(",");
2508             ppIRType(ttarg3);
2509             vex_printf(")\n");
2510             sanityCheckFail(bb,stmt,
2511                "Iex.Triop: arg tys don't match op tys\n"
2512                "... additional details precede BB printout\n");
2513          }
2514          break;
2515       }
2516       case Iex_Binop: {
2517          IRType ttarg1, ttarg2;
2518          tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
2519          tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
2520          typeOfPrimop(expr->Iex.Binop.op, 
2521                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2522          if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 
2523              || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) {
2524             vex_printf(" op name: " );
2525             ppIROp(expr->Iex.Binop.op);
2526             vex_printf("\n");
2527             sanityCheckFail(bb,stmt,
2528                "Iex.Binop: wrong arity op\n"
2529                "... name of op precedes BB printout\n");
2530          }
2531          ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
2532          ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
2533          if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
2534             vex_printf(" op name: ");
2535             ppIROp(expr->Iex.Binop.op);
2536             vex_printf("\n");
2537             vex_printf(" op type is (");
2538             ppIRType(t_arg1);
2539             vex_printf(",");
2540             ppIRType(t_arg2);
2541             vex_printf(") -> ");
2542             ppIRType (t_dst);
2543             vex_printf("\narg tys are (");
2544             ppIRType(ttarg1);
2545             vex_printf(",");
2546             ppIRType(ttarg2);
2547             vex_printf(")\n");
2548             sanityCheckFail(bb,stmt,
2549                "Iex.Binop: arg tys don't match op tys\n"
2550                "... additional details precede BB printout\n");
2551          }
2552          break;
2553       }
2554       case Iex_Unop:
2555          tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
2556          typeOfPrimop(expr->Iex.Binop.op, 
2557                       &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2558          if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
2559              || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
2560             sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
2561          if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
2562             sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
2563          break;
2564       case Iex_Load:
2565          tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
2566          if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
2567             sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
2568          if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
2569             sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
2570          break;
2571       case Iex_CCall:
2572          if (!saneIRCallee(expr->Iex.CCall.cee))
2573             sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
2574          if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args)) 
2575             sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
2576          for (i = 0; expr->Iex.CCall.args[i]; i++) {
2577             if (i >= 32)
2578                sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
2579             tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
2580          }
2581          if (expr->Iex.CCall.retty == Ity_I1)
2582             sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
2583          for (i = 0; expr->Iex.CCall.args[i]; i++)
2584             if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
2585                sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
2586          break;
2587       case Iex_Const:
2588          if (!saneIRConst(expr->Iex.Const.con))
2589             sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
2590          break;
2591       case Iex_Mux0X:
2592          tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
2593          tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
2594          tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
2595          if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
2596             sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
2597          if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
2598              != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
2599             sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
2600          break;
2601        default: 
2602          vpanic("tcExpr");
2603    }
2604 }
2605
2606
2607 static
2608 void tcStmt ( IRSB* bb, IRStmt* stmt, IRType gWordTy )
2609 {
2610    Int        i;
2611    IRDirty*   d;
2612    IRCAS*     cas;
2613    IRType     tyExpd, tyData;
2614    IRTypeEnv* tyenv = bb->tyenv;
2615    switch (stmt->tag) {
2616       case Ist_IMark:
2617          /* Somewhat heuristic, but rule out totally implausible
2618             instruction sizes. */
2619          if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20)
2620             sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible");
2621          break;
2622       case Ist_AbiHint:
2623          if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
2624             sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
2625                                     "not :: guest word type");
2626          if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy)
2627             sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: "
2628                                     "not :: guest word type");
2629          break;
2630       case Ist_Put:
2631          tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
2632          if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
2633             sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
2634          break;
2635       case Ist_PutI:
2636          tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
2637          tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
2638          if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
2639             sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
2640          if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) 
2641              != stmt->Ist.PutI.descr->elemTy)
2642             sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
2643          if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
2644             sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
2645          if (!saneIRRegArray(stmt->Ist.PutI.descr))
2646             sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
2647          break;
2648       case Ist_WrTmp:
2649          tcExpr( bb, stmt, stmt->Ist.WrTmp.data, gWordTy );
2650          if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
2651              != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
2652             sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
2653          break;
2654       case Ist_Store:
2655          tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
2656          tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
2657          if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
2658             sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type");
2659          if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
2660             sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1");
2661          if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
2662             sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness");
2663          break;
2664       case Ist_CAS:
2665          cas = stmt->Ist.CAS.details;
2666          /* make sure it's definitely either a CAS or a DCAS */
2667          if (cas->oldHi == IRTemp_INVALID 
2668              && cas->expdHi == NULL && cas->dataHi == NULL) {
2669             /* fine; it's a single cas */
2670          }
2671          else
2672          if (cas->oldHi != IRTemp_INVALID 
2673              && cas->expdHi != NULL && cas->dataHi != NULL) {
2674             /* fine; it's a double cas */
2675          }
2676          else {
2677             /* it's some el-mutanto hybrid */
2678             goto bad_cas;
2679          }
2680          /* check the address type */
2681          tcExpr( bb, stmt, cas->addr, gWordTy );
2682          if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
2683          /* check types on the {old,expd,data}Lo components agree */
2684          tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
2685          tyData = typeOfIRExpr(tyenv, cas->dataLo);
2686          if (tyExpd != tyData) goto bad_cas;
2687          if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo))
2688             goto bad_cas;
2689          /* check the base element type is sane */
2690          if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32
2691              || (gWordTy == Ity_I64 && tyExpd == Ity_I64)) {
2692             /* fine */
2693          } else {
2694             goto bad_cas;
2695          }
2696          /* If it's a DCAS, check types on the {old,expd,data}Hi
2697             components too */
2698          if (cas->oldHi != IRTemp_INVALID) {
2699             tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
2700             tyData = typeOfIRExpr(tyenv, cas->dataHi);
2701             if (tyExpd != tyData) goto bad_cas;
2702             if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi))
2703                goto bad_cas;
2704             /* and finally check that oldLo and oldHi have the same
2705                type.  This forces equivalence amongst all 6 types. */
2706             if (typeOfIRTemp(tyenv, cas->oldHi)
2707                 != typeOfIRTemp(tyenv, cas->oldLo))
2708                goto bad_cas;
2709          }
2710          break;
2711          bad_cas:
2712          sanityCheckFail(bb,stmt,"IRStmt.CAS: ill-formed");
2713          break;
2714       case Ist_LLSC: {
2715          IRType tyRes;
2716          if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy)
2717             sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type");
2718          if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE)
2719             sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness");
2720          tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result);
2721          if (stmt->Ist.LLSC.storedata == NULL) {
2722             /* it's a LL */
2723             if (tyRes != Ity_I64 && tyRes != Ity_I32 && tyRes != Ity_I8)
2724                sanityCheckFail(bb,stmt,"Ist.LLSC(LL).result :: bogus");
2725          } else {
2726             /* it's a SC */
2727             if (tyRes != Ity_I1)
2728                sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1");
2729             tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata);
2730             if (tyData != Ity_I64 && tyData != Ity_I32 && tyData != Ity_I8)
2731                sanityCheckFail(bb,stmt,
2732                                "Ist.LLSC(SC).result :: storedata bogus");
2733          }
2734          break;
2735       }
2736       case Ist_Dirty:
2737          /* Mostly check for various kinds of ill-formed dirty calls. */
2738          d = stmt->Ist.Dirty.details;
2739          if (d->cee == NULL) goto bad_dirty;
2740          if (!saneIRCallee(d->cee)) goto bad_dirty;
2741          if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
2742          if (d->mFx == Ifx_None) {
2743             if (d->mAddr != NULL || d->mSize != 0)
2744                goto bad_dirty;
2745          } else {
2746             if (d->mAddr == NULL || d->mSize == 0)
2747                goto bad_dirty;
2748          }
2749          if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
2750             goto bad_dirty;
2751          if (d->nFxState == 0 && d->needsBBP)
2752             goto bad_dirty;
2753          for (i = 0; i < d->nFxState; i++) {
2754             if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
2755             if (d->fxState[i].size <= 0) goto bad_dirty;
2756          }
2757          /* check types, minimally */
2758          if (d->guard == NULL) goto bad_dirty;
2759          tcExpr( bb, stmt, d->guard, gWordTy );
2760          if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
2761             sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
2762          if (d->tmp != IRTemp_INVALID
2763              && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
2764             sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
2765          for (i = 0; d->args[i] != NULL; i++) {
2766             if (i >= 32)
2767                sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
2768             if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
2769                sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
2770          }
2771          break;
2772          bad_dirty:
2773          sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
2774          break;
2775       case Ist_NoOp:
2776          break;
2777       case Ist_MBE:
2778          switch (stmt->Ist.MBE.event) {
2779             case Imbe_Fence:
2780                break;
2781             default: sanityCheckFail(bb,stmt,"IRStmt.MBE.event: unknown");
2782                break;
2783          }
2784          break;
2785       case Ist_Exit:
2786          tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
2787          if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
2788             sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
2789          if (!saneIRConst(stmt->Ist.Exit.dst))
2790             sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
2791          if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
2792             sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
2793          break;
2794       default:
2795          vpanic("tcStmt");
2796    }
2797 }
2798
2799 void sanityCheckIRSB ( IRSB* bb,          HChar* caller,
2800                        Bool require_flat, IRType guest_word_size )
2801 {
2802    Int     i;
2803    IRStmt* stmt;
2804    Int     n_temps    = bb->tyenv->types_used;
2805    Int*    def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
2806
2807    if (0)
2808       vex_printf("sanityCheck: %s\n", caller);
2809
2810    vassert(guest_word_size == Ity_I32
2811            || guest_word_size == Ity_I64);
2812
2813    if (bb->stmts_used < 0 || bb->stmts_size < 8
2814        || bb->stmts_used > bb->stmts_size)
2815       /* this BB is so strange we can't even print it */
2816       vpanic("sanityCheckIRSB: stmts array limits wierd");
2817
2818    /* Ensure each temp has a plausible type. */
2819    for (i = 0; i < n_temps; i++) {
2820       IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
2821       if (!isPlausibleIRType(ty)) {
2822          vex_printf("Temp t%d declared with implausible type 0x%x\n",
2823                     i, (UInt)ty);
2824          sanityCheckFail(bb,NULL,"Temp declared with implausible type");
2825       }
2826    }
2827
2828    /* Check for flatness, if required. */
2829    if (require_flat) {
2830       for (i = 0; i < bb->stmts_used; i++) {
2831          stmt = bb->stmts[i];
2832          if (!stmt)
2833             sanityCheckFail(bb, stmt, "IRStmt: is NULL");
2834          if (!isFlatIRStmt(stmt))
2835             sanityCheckFail(bb, stmt, "IRStmt: is not flat");
2836       }
2837       if (!isIRAtom(bb->next))
2838          sanityCheckFail(bb, NULL, "bb->next is not an atom");
2839    }
2840
2841    /* Count the defs of each temp.  Only one def is allowed.
2842       Also, check that each used temp has already been defd. */
2843
2844    for (i = 0; i < n_temps; i++)
2845       def_counts[i] = 0;
2846
2847    for (i = 0; i < bb->stmts_used; i++) {
2848       IRDirty* d;
2849       IRCAS*   cas;
2850       stmt = bb->stmts[i];
2851       /* Check any temps used by this statement. */
2852       useBeforeDef_Stmt(bb,stmt,def_counts);
2853
2854       /* Now make note of any temps defd by this statement. */
2855       switch (stmt->tag) {
2856       case Ist_WrTmp:
2857          if (stmt->Ist.WrTmp.tmp < 0 || stmt->Ist.WrTmp.tmp >= n_temps)
2858             sanityCheckFail(bb, stmt, 
2859                "IRStmt.Tmp: destination tmp is out of range");
2860          def_counts[stmt->Ist.WrTmp.tmp]++;
2861          if (def_counts[stmt->Ist.WrTmp.tmp] > 1)
2862             sanityCheckFail(bb, stmt, 
2863                "IRStmt.Tmp: destination tmp is assigned more than once");
2864          break;
2865       case Ist_Store:
2866          break;
2867       case Ist_Dirty:
2868          if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
2869             d = stmt->Ist.Dirty.details;
2870             if (d->tmp < 0 || d->tmp >= n_temps)
2871                sanityCheckFail(bb, stmt, 
2872                   "IRStmt.Dirty: destination tmp is out of range");
2873             def_counts[d->tmp]++;
2874             if (def_counts[d->tmp] > 1)
2875                sanityCheckFail(bb, stmt, 
2876                   "IRStmt.Dirty: destination tmp is assigned more than once");
2877          }
2878          break;
2879       case Ist_CAS:
2880          cas = stmt->Ist.CAS.details;
2881          if (cas->oldHi != IRTemp_INVALID) {
2882             if (cas->oldHi < 0 || cas->oldHi >= n_temps)
2883                 sanityCheckFail(bb, stmt, 
2884                    "IRStmt.CAS: destination tmpHi is out of range");
2885              def_counts[cas->oldHi]++;
2886              if (def_counts[cas->oldHi] > 1)
2887                 sanityCheckFail(bb, stmt, 
2888                    "IRStmt.CAS: destination tmpHi is assigned more than once");
2889          }
2890          if (cas->oldLo < 0 || cas->oldLo >= n_temps)
2891             sanityCheckFail(bb, stmt, 
2892                "IRStmt.CAS: destination tmpLo is out of range");
2893          def_counts[cas->oldLo]++;
2894          if (def_counts[cas->oldLo] > 1)
2895             sanityCheckFail(bb, stmt, 
2896                "IRStmt.CAS: destination tmpLo is assigned more than once");
2897          break;
2898       case Ist_LLSC:
2899          if (stmt->Ist.LLSC.result < 0 || stmt->Ist.LLSC.result >= n_temps)
2900             sanityCheckFail(bb, stmt,
2901                "IRStmt.LLSC: destination tmp is out of range");
2902          def_counts[stmt->Ist.LLSC.result]++;
2903          if (def_counts[stmt->Ist.LLSC.result] > 1)
2904             sanityCheckFail(bb, stmt,
2905                "IRStmt.LLSC: destination tmp is assigned more than once");
2906          break;
2907       default:
2908          /* explicitly handle the rest, so as to keep gcc quiet */
2909          break;
2910       }
2911    }
2912
2913    /* Typecheck everything. */
2914    for (i = 0; i < bb->stmts_used; i++)
2915       if (bb->stmts[i])
2916          tcStmt( bb, bb->stmts[i], guest_word_size );
2917    if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
2918       sanityCheckFail(bb, NULL, "bb->next field has wrong type");
2919 }
2920
2921 /*---------------------------------------------------------------*/
2922 /*--- Misc helper functions                                   ---*/
2923 /*---------------------------------------------------------------*/
2924
2925 Bool eqIRConst ( IRConst* c1, IRConst* c2 )
2926 {
2927    if (c1->tag != c2->tag)
2928       return False;
2929
2930    switch (c1->tag) {
2931       case Ico_U1:  return toBool( (1 & c1->Ico.U1) == (1 & c2->Ico.U1) );
2932       case Ico_U8:  return toBool( c1->Ico.U8  == c2->Ico.U8 );
2933       case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 );
2934       case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 );
2935       case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 );
2936       case Ico_F64: return toBool( c1->Ico.F64 == c2->Ico.F64 );
2937       case Ico_F64i: return toBool( c1->Ico.F64i == c2->Ico.F64i );
2938       case Ico_V128: return toBool( c1->Ico.V128 == c2->Ico.V128 );
2939       default: vpanic("eqIRConst");
2940    }
2941 }
2942
2943 Bool eqIRRegArray ( IRRegArray* descr1, IRRegArray* descr2 )
2944 {
2945    return toBool( descr1->base == descr2->base 
2946                   && descr1->elemTy == descr2->elemTy
2947                   && descr1->nElems == descr2->nElems );
2948 }
2949
2950 Int sizeofIRType ( IRType ty )
2951 {
2952    switch (ty) {
2953       case Ity_I8:   return 1;
2954       case Ity_I16:  return 2;
2955       case Ity_I32:  return 4;
2956       case Ity_I64:  return 8;
2957       case Ity_F32:  return 4;
2958       case Ity_F64:  return 8;
2959       case Ity_V128: return 16;
2960       default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
2961                vpanic("sizeofIRType");
2962    }
2963 }
2964
2965 IRExpr* mkIRExpr_HWord ( HWord hw )
2966 {
2967    vassert(sizeof(void*) == sizeof(HWord));
2968    if (sizeof(HWord) == 4)
2969       return IRExpr_Const(IRConst_U32((UInt)hw));
2970    if (sizeof(HWord) == 8)
2971       return IRExpr_Const(IRConst_U64((ULong)hw));
2972    vpanic("mkIRExpr_HWord");
2973 }
2974
2975 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr, 
2976                              IRExpr** args ) 
2977 {
2978    IRDirty* d = emptyIRDirty();
2979    d->cee   = mkIRCallee ( regparms, name, addr );
2980    d->guard = IRExpr_Const(IRConst_U1(True));
2981    d->args  = args;
2982    return d;
2983 }
2984
2985 IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 
2986                              Int regparms, HChar* name, void* addr, 
2987                              IRExpr** args ) 
2988 {
2989    IRDirty* d = emptyIRDirty();
2990    d->cee   = mkIRCallee ( regparms, name, addr );
2991    d->guard = IRExpr_Const(IRConst_U1(True));
2992    d->args  = args;
2993    d->tmp   = dst;
2994    return d;
2995 }
2996
2997 IRExpr* mkIRExprCCall ( IRType retty,
2998                         Int regparms, HChar* name, void* addr, 
2999                         IRExpr** args )
3000 {
3001    return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ), 
3002                          retty, args );
3003 }
3004
3005 Bool eqIRAtom ( IRExpr* a1, IRExpr* a2 )
3006 {
3007    vassert(isIRAtom(a1));
3008    vassert(isIRAtom(a2));
3009    if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp)
3010       return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp);
3011    if (a1->tag == Iex_Const && a2->tag == Iex_Const)
3012       return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
3013    return False;
3014 }
3015
3016 /*---------------------------------------------------------------*/
3017 /*--- end                                           ir_defs.c ---*/
3018 /*---------------------------------------------------------------*/