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