2 /*---------------------------------------------------------------*/
3 /*--- begin ir_defs.c ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2004-2010 OpenWorks LLP
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
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.
36 #include "libvex_basictypes.h"
37 #include "libvex_ir.h"
40 #include "main_util.h"
43 /*---------------------------------------------------------------*/
44 /*--- Printing the IR ---*/
45 /*---------------------------------------------------------------*/
47 void ppIRType ( IRType ty )
50 case Ity_INVALID: vex_printf("Ity_INVALID"); break;
51 case Ity_I1: vex_printf( "I1"); break;
52 case Ity_I8: vex_printf( "I8"); break;
53 case Ity_I16: vex_printf( "I16"); break;
54 case Ity_I32: vex_printf( "I32"); break;
55 case Ity_I64: vex_printf( "I64"); break;
56 case Ity_I128: vex_printf( "I128"); break;
57 case Ity_F32: vex_printf( "F32"); break;
58 case Ity_F64: vex_printf( "F64"); break;
59 case Ity_V128: vex_printf( "V128"); break;
60 default: vex_printf("ty = 0x%x\n", (Int)ty);
65 void ppIRConst ( IRConst* con )
67 union { ULong i64; Double f64; } u;
68 vassert(sizeof(ULong) == sizeof(Double));
70 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break;
71 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break;
72 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break;
73 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break;
74 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break;
75 case Ico_F64: u.f64 = con->Ico.F64;
76 vex_printf( "F64{0x%llx}", u.i64);
78 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
79 case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break;
80 default: vpanic("ppIRConst");
84 void ppIRCallee ( IRCallee* ce )
86 vex_printf("%s", ce->name);
88 vex_printf("[rp=%d]", ce->regparms);
90 vex_printf("[mcx=0x%x]", ce->mcx_mask);
91 vex_printf("{%p}", (void*)ce->addr);
94 void ppIRRegArray ( IRRegArray* arr )
96 vex_printf("(%d:%dx", arr->base, arr->nElems);
97 ppIRType(arr->elemTy);
101 void ppIRTemp ( IRTemp tmp )
103 if (tmp == IRTemp_INVALID)
104 vex_printf("IRTemp_INVALID");
106 vex_printf( "t%d", (Int)tmp);
109 void ppIROp ( IROp op )
114 case Iop_Add8 ... Iop_Add64:
115 str = "Add"; base = Iop_Add8; break;
116 case Iop_Sub8 ... Iop_Sub64:
117 str = "Sub"; base = Iop_Sub8; break;
118 case Iop_Mul8 ... Iop_Mul64:
119 str = "Mul"; base = Iop_Mul8; break;
120 case Iop_Or8 ... Iop_Or64:
121 str = "Or"; base = Iop_Or8; break;
122 case Iop_And8 ... Iop_And64:
123 str = "And"; base = Iop_And8; break;
124 case Iop_Xor8 ... Iop_Xor64:
125 str = "Xor"; base = Iop_Xor8; break;
126 case Iop_Shl8 ... Iop_Shl64:
127 str = "Shl"; base = Iop_Shl8; break;
128 case Iop_Shr8 ... Iop_Shr64:
129 str = "Shr"; base = Iop_Shr8; break;
130 case Iop_Sar8 ... Iop_Sar64:
131 str = "Sar"; base = Iop_Sar8; break;
132 case Iop_CmpEQ8 ... Iop_CmpEQ64:
133 str = "CmpEQ"; base = Iop_CmpEQ8; break;
134 case Iop_CmpNE8 ... Iop_CmpNE64:
135 str = "CmpNE"; base = Iop_CmpNE8; break;
136 case Iop_CasCmpEQ8 ... Iop_CasCmpEQ64:
137 str = "CasCmpEQ"; base = Iop_CasCmpEQ8; break;
138 case Iop_CasCmpNE8 ... Iop_CasCmpNE64:
139 str = "CasCmpNE"; base = Iop_CasCmpNE8; break;
140 case Iop_Not8 ... Iop_Not64:
141 str = "Not"; base = Iop_Not8; break;
142 /* other cases must explicitly "return;" */
143 case Iop_8Uto16: vex_printf("8Uto16"); return;
144 case Iop_8Uto32: vex_printf("8Uto32"); return;
145 case Iop_16Uto32: vex_printf("16Uto32"); return;
146 case Iop_8Sto16: vex_printf("8Sto16"); return;
147 case Iop_8Sto32: vex_printf("8Sto32"); return;
148 case Iop_16Sto32: vex_printf("16Sto32"); return;
149 case Iop_32Sto64: vex_printf("32Sto64"); return;
150 case Iop_32Uto64: vex_printf("32Uto64"); return;
151 case Iop_32to8: vex_printf("32to8"); return;
152 case Iop_16Uto64: vex_printf("16Uto64"); return;
153 case Iop_16Sto64: vex_printf("16Sto64"); return;
154 case Iop_8Uto64: vex_printf("8Uto64"); return;
155 case Iop_8Sto64: vex_printf("8Sto64"); return;
156 case Iop_64to16: vex_printf("64to16"); return;
157 case Iop_64to8: vex_printf("64to8"); return;
159 case Iop_Not1: vex_printf("Not1"); return;
160 case Iop_32to1: vex_printf("32to1"); return;
161 case Iop_64to1: vex_printf("64to1"); return;
162 case Iop_1Uto8: vex_printf("1Uto8"); return;
163 case Iop_1Uto32: vex_printf("1Uto32"); return;
164 case Iop_1Uto64: vex_printf("1Uto64"); return;
165 case Iop_1Sto8: vex_printf("1Sto8"); return;
166 case Iop_1Sto16: vex_printf("1Sto16"); return;
167 case Iop_1Sto32: vex_printf("1Sto32"); return;
168 case Iop_1Sto64: vex_printf("1Sto64"); return;
170 case Iop_MullS8: vex_printf("MullS8"); return;
171 case Iop_MullS16: vex_printf("MullS16"); return;
172 case Iop_MullS32: vex_printf("MullS32"); return;
173 case Iop_MullS64: vex_printf("MullS64"); return;
174 case Iop_MullU8: vex_printf("MullU8"); return;
175 case Iop_MullU16: vex_printf("MullU16"); return;
176 case Iop_MullU32: vex_printf("MullU32"); return;
177 case Iop_MullU64: vex_printf("MullU64"); return;
179 case Iop_Clz64: vex_printf("Clz64"); return;
180 case Iop_Clz32: vex_printf("Clz32"); return;
181 case Iop_Ctz64: vex_printf("Ctz64"); return;
182 case Iop_Ctz32: vex_printf("Ctz32"); return;
184 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
185 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
186 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
187 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
189 case Iop_CmpLT64S: vex_printf("CmpLT64S"); return;
190 case Iop_CmpLE64S: vex_printf("CmpLE64S"); return;
191 case Iop_CmpLT64U: vex_printf("CmpLT64U"); return;
192 case Iop_CmpLE64U: vex_printf("CmpLE64U"); return;
194 case Iop_CmpNEZ8: vex_printf("CmpNEZ8"); return;
195 case Iop_CmpNEZ16: vex_printf("CmpNEZ16"); return;
196 case Iop_CmpNEZ32: vex_printf("CmpNEZ32"); return;
197 case Iop_CmpNEZ64: vex_printf("CmpNEZ64"); return;
199 case Iop_CmpwNEZ32: vex_printf("CmpwNEZ32"); return;
200 case Iop_CmpwNEZ64: vex_printf("CmpwNEZ64"); return;
202 case Iop_Left8: vex_printf("Left8"); return;
203 case Iop_Left16: vex_printf("Left16"); return;
204 case Iop_Left32: vex_printf("Left32"); return;
205 case Iop_Left64: vex_printf("Left64"); return;
206 case Iop_Max32U: vex_printf("Max32U"); return;
208 case Iop_CmpORD32U: vex_printf("CmpORD32U"); return;
209 case Iop_CmpORD32S: vex_printf("CmpORD32S"); return;
211 case Iop_CmpORD64U: vex_printf("CmpORD64U"); return;
212 case Iop_CmpORD64S: vex_printf("CmpORD64S"); return;
214 case Iop_DivU32: vex_printf("DivU32"); return;
215 case Iop_DivS32: vex_printf("DivS32"); return;
216 case Iop_DivU64: vex_printf("DivU64"); return;
217 case Iop_DivS64: vex_printf("DivS64"); return;
219 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
220 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
222 case Iop_DivModU128to64: vex_printf("DivModU128to64"); return;
223 case Iop_DivModS128to64: vex_printf("DivModS128to64"); return;
225 case Iop_16HIto8: vex_printf("16HIto8"); return;
226 case Iop_16to8: vex_printf("16to8"); return;
227 case Iop_8HLto16: vex_printf("8HLto16"); return;
229 case Iop_32HIto16: vex_printf("32HIto16"); return;
230 case Iop_32to16: vex_printf("32to16"); return;
231 case Iop_16HLto32: vex_printf("16HLto32"); return;
233 case Iop_64HIto32: vex_printf("64HIto32"); return;
234 case Iop_64to32: vex_printf("64to32"); return;
235 case Iop_32HLto64: vex_printf("32HLto64"); return;
237 case Iop_128HIto64: vex_printf("128HIto64"); return;
238 case Iop_128to64: vex_printf("128to64"); return;
239 case Iop_64HLto128: vex_printf("64HLto128"); return;
241 case Iop_AddF64: vex_printf("AddF64"); return;
242 case Iop_SubF64: vex_printf("SubF64"); return;
243 case Iop_MulF64: vex_printf("MulF64"); return;
244 case Iop_DivF64: vex_printf("DivF64"); return;
245 case Iop_AddF64r32: vex_printf("AddF64r32"); return;
246 case Iop_SubF64r32: vex_printf("SubF64r32"); return;
247 case Iop_MulF64r32: vex_printf("MulF64r32"); return;
248 case Iop_DivF64r32: vex_printf("DivF64r32"); return;
249 case Iop_AddF32: vex_printf("AddF32"); return;
250 case Iop_SubF32: vex_printf("SubF32"); return;
251 case Iop_MulF32: vex_printf("MulF32"); return;
252 case Iop_DivF32: vex_printf("DivF32"); return;
254 case Iop_ScaleF64: vex_printf("ScaleF64"); return;
255 case Iop_AtanF64: vex_printf("AtanF64"); return;
256 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return;
257 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return;
258 case Iop_PRemF64: vex_printf("PRemF64"); return;
259 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return;
260 case Iop_PRem1F64: vex_printf("PRem1F64"); return;
261 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
262 case Iop_NegF64: vex_printf("NegF64"); return;
263 case Iop_AbsF64: vex_printf("AbsF64"); return;
264 case Iop_NegF32: vex_printf("NegF32"); return;
265 case Iop_AbsF32: vex_printf("AbsF32"); return;
266 case Iop_SqrtF64: vex_printf("SqrtF64"); return;
267 case Iop_SqrtF32: vex_printf("SqrtF32"); return;
268 case Iop_SinF64: vex_printf("SinF64"); return;
269 case Iop_CosF64: vex_printf("CosF64"); return;
270 case Iop_TanF64: vex_printf("TanF64"); return;
271 case Iop_2xm1F64: vex_printf("2xm1F64"); return;
273 case Iop_MAddF64: vex_printf("MAddF64"); return;
274 case Iop_MSubF64: vex_printf("MSubF64"); return;
275 case Iop_MAddF64r32: vex_printf("MAddF64r32"); return;
276 case Iop_MSubF64r32: vex_printf("MSubF64r32"); return;
278 case Iop_Est5FRSqrt: vex_printf("Est5FRSqrt"); return;
279 case Iop_RoundF64toF64_NEAREST: vex_printf("RoundF64toF64_NEAREST"); return;
280 case Iop_RoundF64toF64_NegINF: vex_printf("RoundF64toF64_NegINF"); return;
281 case Iop_RoundF64toF64_PosINF: vex_printf("RoundF64toF64_PosINF"); return;
282 case Iop_RoundF64toF64_ZERO: vex_printf("RoundF64toF64_ZERO"); return;
284 case Iop_TruncF64asF32: vex_printf("TruncF64asF32"); return;
285 case Iop_CalcFPRF: vex_printf("CalcFPRF"); return;
287 case Iop_CmpF64: vex_printf("CmpF64"); return;
289 case Iop_F64toI16S: vex_printf("F64toI16S"); return;
290 case Iop_F64toI32S: vex_printf("F64toI32S"); return;
291 case Iop_F64toI64S: vex_printf("F64toI64S"); return;
293 case Iop_F64toI32U: vex_printf("F64toI32U"); return;
295 case Iop_I16StoF64: vex_printf("I16StoF64"); return;
296 case Iop_I32StoF64: vex_printf("I32StoF64"); return;
297 case Iop_I64StoF64: vex_printf("I64StoF64"); return;
299 case Iop_I32UtoF64: vex_printf("I32UtoF64"); return;
301 case Iop_F32toF64: vex_printf("F32toF64"); return;
302 case Iop_F64toF32: vex_printf("F64toF32"); return;
304 case Iop_RoundF64toInt: vex_printf("RoundF64toInt"); return;
305 case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return;
307 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
308 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
309 case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return;
310 case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
312 case Iop_I32UtoFx4: vex_printf("I32UtoFx4"); return;
313 case Iop_I32StoFx4: vex_printf("I32StoFx4"); return;
315 case Iop_QFtoI32Ux4_RZ: vex_printf("QFtoI32Ux4_RZ"); return;
316 case Iop_QFtoI32Sx4_RZ: vex_printf("QFtoI32Sx4_RZ"); return;
318 case Iop_RoundF32x4_RM: vex_printf("RoundF32x4_RM"); return;
319 case Iop_RoundF32x4_RP: vex_printf("RoundF32x4_RP"); return;
320 case Iop_RoundF32x4_RN: vex_printf("RoundF32x4_RN"); return;
321 case Iop_RoundF32x4_RZ: vex_printf("RoundF32x4_RZ"); return;
323 case Iop_Add8x8: vex_printf("Add8x8"); return;
324 case Iop_Add16x4: vex_printf("Add16x4"); return;
325 case Iop_Add32x2: vex_printf("Add32x2"); return;
326 case Iop_QAdd8Ux8: vex_printf("QAdd8Ux8"); return;
327 case Iop_QAdd16Ux4: vex_printf("QAdd16Ux4"); return;
328 case Iop_QAdd8Sx8: vex_printf("QAdd8Sx8"); return;
329 case Iop_QAdd16Sx4: vex_printf("QAdd16Sx4"); return;
330 case Iop_Sub8x8: vex_printf("Sub8x8"); return;
331 case Iop_Sub16x4: vex_printf("Sub16x4"); return;
332 case Iop_Sub32x2: vex_printf("Sub32x2"); return;
333 case Iop_QSub8Ux8: vex_printf("QSub8Ux8"); return;
334 case Iop_QSub16Ux4: vex_printf("QSub16Ux4"); return;
335 case Iop_QSub8Sx8: vex_printf("QSub8Sx8"); return;
336 case Iop_QSub16Sx4: vex_printf("QSub16Sx4"); return;
337 case Iop_Mul16x4: vex_printf("Mul16x4"); return;
338 case Iop_Mul32x2: vex_printf("Mul32x2"); return;
339 case Iop_MulHi16Ux4: vex_printf("MulHi16Ux4"); return;
340 case Iop_MulHi16Sx4: vex_printf("MulHi16Sx4"); return;
341 case Iop_Avg8Ux8: vex_printf("Avg8Ux8"); return;
342 case Iop_Avg16Ux4: vex_printf("Avg16Ux4"); return;
343 case Iop_Max16Sx4: vex_printf("Max16Sx4"); return;
344 case Iop_Max8Ux8: vex_printf("Max8Ux8"); return;
345 case Iop_Min16Sx4: vex_printf("Min16Sx4"); return;
346 case Iop_Min8Ux8: vex_printf("Min8Ux8"); return;
347 case Iop_CmpEQ8x8: vex_printf("CmpEQ8x8"); return;
348 case Iop_CmpEQ16x4: vex_printf("CmpEQ16x4"); return;
349 case Iop_CmpEQ32x2: vex_printf("CmpEQ32x2"); return;
350 case Iop_CmpGT8Sx8: vex_printf("CmpGT8Sx8"); return;
351 case Iop_CmpGT16Sx4: vex_printf("CmpGT16Sx4"); return;
352 case Iop_CmpGT32Sx2: vex_printf("CmpGT32Sx2"); return;
353 case Iop_ShlN8x8: vex_printf("ShlN8x8"); return;
354 case Iop_ShlN16x4: vex_printf("ShlN16x4"); return;
355 case Iop_ShlN32x2: vex_printf("ShlN32x2"); return;
356 case Iop_ShrN16x4: vex_printf("ShrN16x4"); return;
357 case Iop_ShrN32x2: vex_printf("ShrN32x2"); return;
358 case Iop_SarN8x8: vex_printf("SarN8x8"); return;
359 case Iop_SarN16x4: vex_printf("SarN16x4"); return;
360 case Iop_SarN32x2: vex_printf("SarN32x2"); return;
361 case Iop_QNarrow16Ux4: vex_printf("QNarrow16Ux4"); return;
362 case Iop_QNarrow16Sx4: vex_printf("QNarrow16Sx4"); return;
363 case Iop_QNarrow32Sx2: vex_printf("QNarrow32Sx2"); return;
364 case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return;
365 case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return;
366 case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return;
367 case Iop_InterleaveLO8x8: vex_printf("InterleaveLO8x8"); return;
368 case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return;
369 case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return;
370 case Iop_CatOddLanes16x4: vex_printf("CatOddLanes16x4"); return;
371 case Iop_CatEvenLanes16x4: vex_printf("CatEvenLanes16x4"); return;
372 case Iop_Perm8x8: vex_printf("Perm8x8"); return;
374 case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return;
375 case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return;
376 case Iop_CmpNEZ8x8: vex_printf("CmpNEZ8x8"); return;
378 case Iop_Add32Fx4: vex_printf("Add32Fx4"); return;
379 case Iop_Add32F0x4: vex_printf("Add32F0x4"); return;
380 case Iop_Add64Fx2: vex_printf("Add64Fx2"); return;
381 case Iop_Add64F0x2: vex_printf("Add64F0x2"); return;
383 case Iop_Div32Fx4: vex_printf("Div32Fx4"); return;
384 case Iop_Div32F0x4: vex_printf("Div32F0x4"); return;
385 case Iop_Div64Fx2: vex_printf("Div64Fx2"); return;
386 case Iop_Div64F0x2: vex_printf("Div64F0x2"); return;
388 case Iop_Max32Fx4: vex_printf("Max32Fx4"); return;
389 case Iop_Max32F0x4: vex_printf("Max32F0x4"); return;
390 case Iop_Max64Fx2: vex_printf("Max64Fx2"); return;
391 case Iop_Max64F0x2: vex_printf("Max64F0x2"); return;
393 case Iop_Min32Fx4: vex_printf("Min32Fx4"); return;
394 case Iop_Min32F0x4: vex_printf("Min32F0x4"); return;
395 case Iop_Min64Fx2: vex_printf("Min64Fx2"); return;
396 case Iop_Min64F0x2: vex_printf("Min64F0x2"); return;
398 case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return;
399 case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return;
400 case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return;
401 case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return;
403 case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return;
404 case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return;
405 case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return;
406 case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return;
408 case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return;
409 case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return;
410 case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return;
411 case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return;
413 case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return;
414 case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return;
415 case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return;
416 case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return;
418 case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return;
419 case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return;
420 case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return;
421 case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return;
423 case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return;
424 case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return;
425 case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return;
426 case Iop_CmpGT32Fx4: vex_printf("CmpGT32Fx4"); return;
427 case Iop_CmpGE32Fx4: vex_printf("CmpGE32Fx4"); return;
428 case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return;
429 case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return;
430 case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return;
431 case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return;
432 case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return;
434 case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return;
435 case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return;
436 case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return;
437 case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return;
438 case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return;
439 case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return;
440 case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return;
441 case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return;
443 case Iop_V128to64: vex_printf("V128to64"); return;
444 case Iop_V128HIto64: vex_printf("V128HIto64"); return;
445 case Iop_64HLtoV128: vex_printf("64HLtoV128"); return;
447 case Iop_64UtoV128: vex_printf("64UtoV128"); return;
448 case Iop_SetV128lo64: vex_printf("SetV128lo64"); return;
450 case Iop_32UtoV128: vex_printf("32UtoV128"); return;
451 case Iop_V128to32: vex_printf("V128to32"); return;
452 case Iop_SetV128lo32: vex_printf("SetV128lo32"); return;
454 case Iop_Dup8x16: vex_printf("Dup8x16"); return;
455 case Iop_Dup16x8: vex_printf("Dup16x8"); return;
456 case Iop_Dup32x4: vex_printf("Dup32x4"); return;
458 case Iop_NotV128: vex_printf("NotV128"); return;
459 case Iop_AndV128: vex_printf("AndV128"); return;
460 case Iop_OrV128: vex_printf("OrV128"); return;
461 case Iop_XorV128: vex_printf("XorV128"); return;
463 case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return;
464 case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return;
465 case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
466 case Iop_CmpNEZ64x2: vex_printf("CmpNEZ64x2"); return;
468 case Iop_Add8x16: vex_printf("Add8x16"); return;
469 case Iop_Add16x8: vex_printf("Add16x8"); return;
470 case Iop_Add32x4: vex_printf("Add32x4"); return;
471 case Iop_Add64x2: vex_printf("Add64x2"); return;
472 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
473 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
474 case Iop_QAdd32Ux4: vex_printf("QAdd32Ux4"); return;
475 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
476 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
477 case Iop_QAdd32Sx4: vex_printf("QAdd32Sx4"); return;
479 case Iop_Sub8x16: vex_printf("Sub8x16"); return;
480 case Iop_Sub16x8: vex_printf("Sub16x8"); return;
481 case Iop_Sub32x4: vex_printf("Sub32x4"); return;
482 case Iop_Sub64x2: vex_printf("Sub64x2"); return;
483 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
484 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
485 case Iop_QSub32Ux4: vex_printf("QSub32Ux4"); return;
486 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
487 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
488 case Iop_QSub32Sx4: vex_printf("QSub32Sx4"); return;
490 case Iop_Mul16x8: vex_printf("Mul16x8"); return;
491 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
492 case Iop_MulHi32Ux4: vex_printf("MulHi32Ux4"); return;
493 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
494 case Iop_MulHi32Sx4: vex_printf("MulHi32Sx4"); return;
496 case Iop_MullEven8Ux16: vex_printf("MullEven8Ux16"); return;
497 case Iop_MullEven16Ux8: vex_printf("MullEven16Ux8"); return;
498 case Iop_MullEven8Sx16: vex_printf("MullEven8Sx16"); return;
499 case Iop_MullEven16Sx8: vex_printf("MullEven16Sx8"); return;
501 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
502 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
503 case Iop_Avg32Ux4: vex_printf("Avg32Ux4"); return;
504 case Iop_Avg8Sx16: vex_printf("Avg8Sx16"); return;
505 case Iop_Avg16Sx8: vex_printf("Avg16Sx8"); return;
506 case Iop_Avg32Sx4: vex_printf("Avg32Sx4"); return;
508 case Iop_Max8Sx16: vex_printf("Max8Sx16"); return;
509 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
510 case Iop_Max32Sx4: vex_printf("Max32Sx4"); return;
511 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
512 case Iop_Max16Ux8: vex_printf("Max16Ux8"); return;
513 case Iop_Max32Ux4: vex_printf("Max32Ux4"); return;
515 case Iop_Min8Sx16: vex_printf("Min8Sx16"); return;
516 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
517 case Iop_Min32Sx4: vex_printf("Min32Sx4"); return;
518 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
519 case Iop_Min16Ux8: vex_printf("Min16Ux8"); return;
520 case Iop_Min32Ux4: vex_printf("Min32Ux4"); return;
522 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return;
523 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return;
524 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return;
525 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
526 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
527 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
528 case Iop_CmpGT8Ux16: vex_printf("CmpGT8Ux16"); return;
529 case Iop_CmpGT16Ux8: vex_printf("CmpGT16Ux8"); return;
530 case Iop_CmpGT32Ux4: vex_printf("CmpGT32Ux4"); return;
532 case Iop_ShlV128: vex_printf("ShlV128"); return;
533 case Iop_ShrV128: vex_printf("ShrV128"); return;
535 case Iop_ShlN8x16: vex_printf("ShlN8x16"); return;
536 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
537 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
538 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
539 case Iop_ShrN8x16: vex_printf("ShrN8x16"); return;
540 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
541 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
542 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
543 case Iop_SarN8x16: vex_printf("SarN8x16"); return;
544 case Iop_SarN16x8: vex_printf("SarN16x8"); return;
545 case Iop_SarN32x4: vex_printf("SarN32x4"); return;
547 case Iop_Shl8x16: vex_printf("Shl8x16"); return;
548 case Iop_Shl16x8: vex_printf("Shl16x8"); return;
549 case Iop_Shl32x4: vex_printf("Shl32x4"); return;
550 case Iop_Shr8x16: vex_printf("Shr8x16"); return;
551 case Iop_Shr16x8: vex_printf("Shr16x8"); return;
552 case Iop_Shr32x4: vex_printf("Shr32x4"); return;
553 case Iop_Sar8x16: vex_printf("Sar8x16"); return;
554 case Iop_Sar16x8: vex_printf("Sar16x8"); return;
555 case Iop_Sar32x4: vex_printf("Sar32x4"); return;
556 case Iop_Rol8x16: vex_printf("Rol8x16"); return;
557 case Iop_Rol16x8: vex_printf("Rol16x8"); return;
558 case Iop_Rol32x4: vex_printf("Rol32x4"); return;
560 case Iop_Narrow16x8: vex_printf("Narrow16x8"); return;
561 case Iop_Narrow32x4: vex_printf("Narrow32x4"); return;
562 case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return;
563 case Iop_QNarrow32Ux4: vex_printf("QNarrow32Ux4"); return;
564 case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return;
565 case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return;
567 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
568 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
569 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
570 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
571 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
572 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
573 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
574 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
576 case Iop_Perm8x16: vex_printf("Perm8x16"); return;
578 default: vpanic("ppIROp(1)");
583 case 0: vex_printf("%s",str); vex_printf("8"); break;
584 case 1: vex_printf("%s",str); vex_printf("16"); break;
585 case 2: vex_printf("%s",str); vex_printf("32"); break;
586 case 3: vex_printf("%s",str); vex_printf("64"); break;
587 default: vpanic("ppIROp(2)");
591 void ppIRExpr ( IRExpr* e )
596 vex_printf("BIND-%d", e->Iex.Binder.binder);
599 vex_printf( "GET:" );
600 ppIRType(e->Iex.Get.ty);
601 vex_printf("(%d)", e->Iex.Get.offset);
604 vex_printf( "GETI" );
605 ppIRRegArray(e->Iex.GetI.descr);
607 ppIRExpr(e->Iex.GetI.ix);
608 vex_printf(",%d]", e->Iex.GetI.bias);
611 ppIRTemp(e->Iex.RdTmp.tmp);
614 ppIROp(e->Iex.Qop.op);
616 ppIRExpr(e->Iex.Qop.arg1);
618 ppIRExpr(e->Iex.Qop.arg2);
620 ppIRExpr(e->Iex.Qop.arg3);
622 ppIRExpr(e->Iex.Qop.arg4);
626 ppIROp(e->Iex.Triop.op);
628 ppIRExpr(e->Iex.Triop.arg1);
630 ppIRExpr(e->Iex.Triop.arg2);
632 ppIRExpr(e->Iex.Triop.arg3);
636 ppIROp(e->Iex.Binop.op);
638 ppIRExpr(e->Iex.Binop.arg1);
640 ppIRExpr(e->Iex.Binop.arg2);
644 ppIROp(e->Iex.Unop.op);
646 ppIRExpr(e->Iex.Unop.arg);
650 vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" );
651 ppIRType(e->Iex.Load.ty);
653 ppIRExpr(e->Iex.Load.addr);
657 ppIRConst(e->Iex.Const.con);
660 ppIRCallee(e->Iex.CCall.cee);
662 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
663 ppIRExpr(e->Iex.CCall.args[i]);
664 if (e->Iex.CCall.args[i+1] != NULL)
668 ppIRType(e->Iex.CCall.retty);
671 vex_printf("Mux0X(");
672 ppIRExpr(e->Iex.Mux0X.cond);
674 ppIRExpr(e->Iex.Mux0X.expr0);
676 ppIRExpr(e->Iex.Mux0X.exprX);
684 void ppIREffect ( IREffect fx )
687 case Ifx_None: vex_printf("noFX"); return;
688 case Ifx_Read: vex_printf("RdFX"); return;
689 case Ifx_Write: vex_printf("WrFX"); return;
690 case Ifx_Modify: vex_printf("MoFX"); return;
691 default: vpanic("ppIREffect");
695 void ppIRDirty ( IRDirty* d )
698 if (d->tmp != IRTemp_INVALID) {
702 vex_printf("DIRTY ");
705 vex_printf(" NeedsBBP");
706 if (d->mFx != Ifx_None) {
711 vex_printf(",%d)", d->mSize);
713 for (i = 0; i < d->nFxState; i++) {
715 ppIREffect(d->fxState[i].fx);
716 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
721 for (i = 0; d->args[i] != NULL; i++) {
722 ppIRExpr(d->args[i]);
723 if (d->args[i+1] != NULL) {
730 void ppIRCAS ( IRCAS* cas )
732 /* Print even structurally invalid constructions, as an aid to
734 if (cas->oldHi != IRTemp_INVALID) {
735 ppIRTemp(cas->oldHi);
738 ppIRTemp(cas->oldLo);
739 vex_printf(" = CAS%s(", cas->end==Iend_LE ? "le" : "be" );
743 ppIRExpr(cas->expdHi);
746 ppIRExpr(cas->expdLo);
749 ppIRExpr(cas->dataHi);
752 ppIRExpr(cas->dataLo);
756 void ppIRJumpKind ( IRJumpKind kind )
759 case Ijk_Boring: vex_printf("Boring"); break;
760 case Ijk_Call: vex_printf("Call"); break;
761 case Ijk_Ret: vex_printf("Return"); break;
762 case Ijk_ClientReq: vex_printf("ClientReq"); break;
763 case Ijk_Yield: vex_printf("Yield"); break;
764 case Ijk_EmWarn: vex_printf("EmWarn"); break;
765 case Ijk_EmFail: vex_printf("EmFail"); break;
766 case Ijk_NoDecode: vex_printf("NoDecode"); break;
767 case Ijk_MapFail: vex_printf("MapFail"); break;
768 case Ijk_TInval: vex_printf("Invalidate"); break;
769 case Ijk_NoRedir: vex_printf("NoRedir"); break;
770 case Ijk_SigTRAP: vex_printf("SigTRAP"); break;
771 case Ijk_SigSEGV: vex_printf("SigSEGV"); break;
772 case Ijk_SigBUS: vex_printf("SigBUS"); break;
773 case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
774 case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
775 case Ijk_Sys_int48: vex_printf("Sys_int48"); break;
776 case Ijk_Sys_int50: vex_printf("Sys_int50"); break;
777 case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
778 case Ijk_Sys_int129: vex_printf("Sys_int129"); break;
779 case Ijk_Sys_int130: vex_printf("Sys_int130"); break;
780 case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break;
781 case Ijk_l4_utcb_eax: vex_printf("l4_utcb_eax"); break;
782 case Ijk_l4_utcb_ebx: vex_printf("l4_utcb_ebx"); break;
783 case Ijk_l4_utcb_ecx: vex_printf("l4_utcb_ecx"); break;
784 case Ijk_l4_utcb_edx: vex_printf("l4_utcb_edx"); break;
785 case Ijk_l4_utcb_edi: vex_printf("l4_utcb_edi"); break;
786 case Ijk_l4_utcb_esi: vex_printf("l4_utcb_esi"); break;
787 case Ijk_l4_ud2: vex_printf("l4_ud2"); break;
788 case Ijk_l4_artificial: vex_printf("l4_artificial_trap"); break;
789 default: vpanic("ppIRJumpKind");
793 void ppIRMBusEvent ( IRMBusEvent event )
796 case Imbe_Fence: vex_printf("Fence"); break;
797 default: vpanic("ppIRMBusEvent");
801 void ppIRStmt ( IRStmt* s )
804 vex_printf("!!! IRStmt* which is NULL !!!");
809 vex_printf("IR-NoOp");
812 vex_printf( "------ IMark(0x%llx, %d) ------",
813 s->Ist.IMark.addr, s->Ist.IMark.len);
816 vex_printf("====== AbiHint(");
817 ppIRExpr(s->Ist.AbiHint.base);
818 vex_printf(", %d, ", s->Ist.AbiHint.len);
819 ppIRExpr(s->Ist.AbiHint.nia);
820 vex_printf(") ======");
823 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
824 ppIRExpr(s->Ist.Put.data);
827 vex_printf( "PUTI" );
828 ppIRRegArray(s->Ist.PutI.descr);
830 ppIRExpr(s->Ist.PutI.ix);
831 vex_printf(",%d] = ", s->Ist.PutI.bias);
832 ppIRExpr(s->Ist.PutI.data);
835 ppIRTemp(s->Ist.WrTmp.tmp);
837 ppIRExpr(s->Ist.WrTmp.data);
840 vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" );
841 ppIRExpr(s->Ist.Store.addr);
843 ppIRExpr(s->Ist.Store.data);
846 ppIRCAS(s->Ist.CAS.details);
849 if (s->Ist.LLSC.storedata == NULL) {
850 ppIRTemp(s->Ist.LLSC.result);
851 vex_printf(" = LD%s-Linked(",
852 s->Ist.LLSC.end==Iend_LE ? "le" : "be");
853 ppIRExpr(s->Ist.LLSC.addr);
856 ppIRTemp(s->Ist.LLSC.result);
857 vex_printf(" = ( ST%s-Cond(",
858 s->Ist.LLSC.end==Iend_LE ? "le" : "be");
859 ppIRExpr(s->Ist.LLSC.addr);
861 ppIRExpr(s->Ist.LLSC.storedata);
866 ppIRDirty(s->Ist.Dirty.details);
870 ppIRMBusEvent(s->Ist.MBE.event);
873 vex_printf( "if (" );
874 ppIRExpr(s->Ist.Exit.guard);
875 vex_printf( ") goto {");
876 ppIRJumpKind(s->Ist.Exit.jk);
878 ppIRConst(s->Ist.Exit.dst);
885 void ppIRTypeEnv ( IRTypeEnv* env ) {
887 for (i = 0; i < env->types_used; i++) {
892 ppIRType(env->types[i]);
898 if (env->types_used > 0 && env->types_used % 8 != 7)
902 void ppIRSB ( IRSB* bb )
905 vex_printf("IRSB {\n");
906 ppIRTypeEnv(bb->tyenv);
908 for (i = 0; i < bb->stmts_used; i++) {
910 ppIRStmt(bb->stmts[i]);
913 vex_printf( " goto {");
914 ppIRJumpKind(bb->jumpkind);
916 ppIRExpr( bb->next );
917 vex_printf( "\n}\n");
921 /*---------------------------------------------------------------*/
922 /*--- Constructors ---*/
923 /*---------------------------------------------------------------*/
926 /* Constructors -- IRConst */
928 IRConst* IRConst_U1 ( Bool bit )
930 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
933 /* call me paranoid; I don't care :-) */
934 vassert(bit == False || bit == True);
937 IRConst* IRConst_U8 ( UChar u8 )
939 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
944 IRConst* IRConst_U16 ( UShort u16 )
946 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
951 IRConst* IRConst_U32 ( UInt u32 )
953 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
958 IRConst* IRConst_U64 ( ULong u64 )
960 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
965 IRConst* IRConst_F64 ( Double f64 )
967 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
972 IRConst* IRConst_F64i ( ULong f64i )
974 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
979 IRConst* IRConst_V128 ( UShort con )
981 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
987 /* Constructors -- IRCallee */
989 IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr )
991 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
992 ce->regparms = regparms;
996 vassert(regparms >= 0 && regparms <= 3);
997 vassert(name != NULL);
1003 /* Constructors -- IRRegArray */
1005 IRRegArray* mkIRRegArray ( Int base, IRType elemTy, Int nElems )
1007 IRRegArray* arr = LibVEX_Alloc(sizeof(IRRegArray));
1009 arr->elemTy = elemTy;
1010 arr->nElems = nElems;
1011 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
1012 vassert(!(arr->elemTy == Ity_I1));
1013 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
1018 /* Constructors -- IRExpr */
1020 IRExpr* IRExpr_Binder ( Int binder ) {
1021 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1022 e->tag = Iex_Binder;
1023 e->Iex.Binder.binder = binder;
1026 IRExpr* IRExpr_Get ( Int off, IRType ty ) {
1027 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1029 e->Iex.Get.offset = off;
1033 IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ) {
1034 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1036 e->Iex.GetI.descr = descr;
1037 e->Iex.GetI.ix = ix;
1038 e->Iex.GetI.bias = bias;
1041 IRExpr* IRExpr_RdTmp ( IRTemp tmp ) {
1042 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1044 e->Iex.RdTmp.tmp = tmp;
1047 IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1048 IRExpr* arg3, IRExpr* arg4 ) {
1049 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1052 e->Iex.Qop.arg1 = arg1;
1053 e->Iex.Qop.arg2 = arg2;
1054 e->Iex.Qop.arg3 = arg3;
1055 e->Iex.Qop.arg4 = arg4;
1058 IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1059 IRExpr* arg2, IRExpr* arg3 ) {
1060 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1062 e->Iex.Triop.op = op;
1063 e->Iex.Triop.arg1 = arg1;
1064 e->Iex.Triop.arg2 = arg2;
1065 e->Iex.Triop.arg3 = arg3;
1068 IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
1069 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1071 e->Iex.Binop.op = op;
1072 e->Iex.Binop.arg1 = arg1;
1073 e->Iex.Binop.arg2 = arg2;
1076 IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
1077 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1079 e->Iex.Unop.op = op;
1080 e->Iex.Unop.arg = arg;
1083 IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) {
1084 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1086 e->Iex.Load.end = end;
1087 e->Iex.Load.ty = ty;
1088 e->Iex.Load.addr = addr;
1089 vassert(end == Iend_LE || end == Iend_BE);
1092 IRExpr* IRExpr_Const ( IRConst* con ) {
1093 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1095 e->Iex.Const.con = con;
1098 IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
1099 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1101 e->Iex.CCall.cee = cee;
1102 e->Iex.CCall.retty = retty;
1103 e->Iex.CCall.args = args;
1106 IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
1107 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1109 e->Iex.Mux0X.cond = cond;
1110 e->Iex.Mux0X.expr0 = expr0;
1111 e->Iex.Mux0X.exprX = exprX;
1116 /* Constructors for NULL-terminated IRExpr expression vectors,
1117 suitable for use as arg lists in clean/dirty helper calls. */
1119 IRExpr** mkIRExprVec_0 ( void ) {
1120 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
1124 IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
1125 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
1130 IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
1131 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
1137 IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
1138 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
1145 IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1147 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
1155 IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1156 IRExpr* arg4, IRExpr* arg5 ) {
1157 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
1166 IRExpr** mkIRExprVec_6 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1167 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6 ) {
1168 IRExpr** vec = LibVEX_Alloc(7 * sizeof(IRExpr*));
1178 IRExpr** mkIRExprVec_7 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3,
1179 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6,
1181 IRExpr** vec = LibVEX_Alloc(8 * sizeof(IRExpr*));
1194 /* Constructors -- IRDirty */
1196 IRDirty* emptyIRDirty ( void ) {
1197 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
1201 d->tmp = IRTemp_INVALID;
1205 d->needsBBP = False;
1211 /* Constructors -- IRCAS */
1213 IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1214 IREndness end, IRExpr* addr,
1215 IRExpr* expdHi, IRExpr* expdLo,
1216 IRExpr* dataHi, IRExpr* dataLo ) {
1217 IRCAS* cas = LibVEX_Alloc(sizeof(IRCAS));
1222 cas->expdHi = expdHi;
1223 cas->expdLo = expdLo;
1224 cas->dataHi = dataHi;
1225 cas->dataLo = dataLo;
1230 /* Constructors -- IRStmt */
1232 IRStmt* IRStmt_NoOp ( void )
1234 /* Just use a single static closure. */
1235 static IRStmt static_closure;
1236 static_closure.tag = Ist_NoOp;
1237 return &static_closure;
1239 IRStmt* IRStmt_IMark ( Addr64 addr, Int len ) {
1240 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1242 s->Ist.IMark.addr = addr;
1243 s->Ist.IMark.len = len;
1246 IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ) {
1247 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1248 s->tag = Ist_AbiHint;
1249 s->Ist.AbiHint.base = base;
1250 s->Ist.AbiHint.len = len;
1251 s->Ist.AbiHint.nia = nia;
1254 IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
1255 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1257 s->Ist.Put.offset = off;
1258 s->Ist.Put.data = data;
1261 IRStmt* IRStmt_PutI ( IRRegArray* descr, IRExpr* ix,
1262 Int bias, IRExpr* data ) {
1263 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1265 s->Ist.PutI.descr = descr;
1266 s->Ist.PutI.ix = ix;
1267 s->Ist.PutI.bias = bias;
1268 s->Ist.PutI.data = data;
1271 IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ) {
1272 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1274 s->Ist.WrTmp.tmp = tmp;
1275 s->Ist.WrTmp.data = data;
1278 IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) {
1279 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1281 s->Ist.Store.end = end;
1282 s->Ist.Store.addr = addr;
1283 s->Ist.Store.data = data;
1284 vassert(end == Iend_LE || end == Iend_BE);
1287 IRStmt* IRStmt_CAS ( IRCAS* cas ) {
1288 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1290 s->Ist.CAS.details = cas;
1293 IRStmt* IRStmt_LLSC ( IREndness end,
1294 IRTemp result, IRExpr* addr, IRExpr* storedata ) {
1295 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1297 s->Ist.LLSC.end = end;
1298 s->Ist.LLSC.result = result;
1299 s->Ist.LLSC.addr = addr;
1300 s->Ist.LLSC.storedata = storedata;
1303 IRStmt* IRStmt_Dirty ( IRDirty* d )
1305 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1307 s->Ist.Dirty.details = d;
1310 IRStmt* IRStmt_MBE ( IRMBusEvent event )
1312 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1314 s->Ist.MBE.event = event;
1317 IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
1318 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1320 s->Ist.Exit.guard = guard;
1321 s->Ist.Exit.jk = jk;
1322 s->Ist.Exit.dst = dst;
1327 /* Constructors -- IRTypeEnv */
1329 IRTypeEnv* emptyIRTypeEnv ( void )
1331 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
1332 env->types = LibVEX_Alloc(8 * sizeof(IRType));
1333 env->types_size = 8;
1334 env->types_used = 0;
1339 /* Constructors -- IRSB */
1341 IRSB* emptyIRSB ( void )
1343 IRSB* bb = LibVEX_Alloc(sizeof(IRSB));
1344 bb->tyenv = emptyIRTypeEnv();
1347 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
1349 bb->jumpkind = Ijk_Boring;
1354 /*---------------------------------------------------------------*/
1355 /*--- (Deep) copy constructors. These make complete copies ---*/
1356 /*--- the original, which can be modified without affecting ---*/
1357 /*--- the original. ---*/
1358 /*---------------------------------------------------------------*/
1360 /* Copying IR Expr vectors (for call args). */
1362 /* Shallow copy of an IRExpr vector */
1364 IRExpr** shallowCopyIRExprVec ( IRExpr** vec )
1368 for (i = 0; vec[i]; i++)
1370 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
1371 for (i = 0; vec[i]; i++)
1377 /* Deep copy of an IRExpr vector */
1379 IRExpr** deepCopyIRExprVec ( IRExpr** vec )
1382 IRExpr** newvec = shallowCopyIRExprVec( vec );
1383 for (i = 0; newvec[i]; i++)
1384 newvec[i] = deepCopyIRExpr(newvec[i]);
1388 /* Deep copy constructors for all heap-allocated IR types follow. */
1390 IRConst* deepCopyIRConst ( IRConst* c )
1393 case Ico_U1: return IRConst_U1(c->Ico.U1);
1394 case Ico_U8: return IRConst_U8(c->Ico.U8);
1395 case Ico_U16: return IRConst_U16(c->Ico.U16);
1396 case Ico_U32: return IRConst_U32(c->Ico.U32);
1397 case Ico_U64: return IRConst_U64(c->Ico.U64);
1398 case Ico_F64: return IRConst_F64(c->Ico.F64);
1399 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
1400 case Ico_V128: return IRConst_V128(c->Ico.V128);
1401 default: vpanic("deepCopyIRConst");
1405 IRCallee* deepCopyIRCallee ( IRCallee* ce )
1407 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
1408 ce2->mcx_mask = ce->mcx_mask;
1412 IRRegArray* deepCopyIRRegArray ( IRRegArray* d )
1414 return mkIRRegArray(d->base, d->elemTy, d->nElems);
1417 IRExpr* deepCopyIRExpr ( IRExpr* e )
1421 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
1423 return IRExpr_GetI(deepCopyIRRegArray(e->Iex.GetI.descr),
1424 deepCopyIRExpr(e->Iex.GetI.ix),
1427 return IRExpr_RdTmp(e->Iex.RdTmp.tmp);
1429 return IRExpr_Qop(e->Iex.Qop.op,
1430 deepCopyIRExpr(e->Iex.Qop.arg1),
1431 deepCopyIRExpr(e->Iex.Qop.arg2),
1432 deepCopyIRExpr(e->Iex.Qop.arg3),
1433 deepCopyIRExpr(e->Iex.Qop.arg4));
1435 return IRExpr_Triop(e->Iex.Triop.op,
1436 deepCopyIRExpr(e->Iex.Triop.arg1),
1437 deepCopyIRExpr(e->Iex.Triop.arg2),
1438 deepCopyIRExpr(e->Iex.Triop.arg3));
1440 return IRExpr_Binop(e->Iex.Binop.op,
1441 deepCopyIRExpr(e->Iex.Binop.arg1),
1442 deepCopyIRExpr(e->Iex.Binop.arg2));
1444 return IRExpr_Unop(e->Iex.Unop.op,
1445 deepCopyIRExpr(e->Iex.Unop.arg));
1447 return IRExpr_Load(e->Iex.Load.end,
1449 deepCopyIRExpr(e->Iex.Load.addr));
1451 return IRExpr_Const(deepCopyIRConst(e->Iex.Const.con));
1453 return IRExpr_CCall(deepCopyIRCallee(e->Iex.CCall.cee),
1455 deepCopyIRExprVec(e->Iex.CCall.args));
1458 return IRExpr_Mux0X(deepCopyIRExpr(e->Iex.Mux0X.cond),
1459 deepCopyIRExpr(e->Iex.Mux0X.expr0),
1460 deepCopyIRExpr(e->Iex.Mux0X.exprX));
1462 vpanic("deepCopyIRExpr");
1466 IRDirty* deepCopyIRDirty ( IRDirty* d )
1469 IRDirty* d2 = emptyIRDirty();
1470 d2->cee = deepCopyIRCallee(d->cee);
1471 d2->guard = deepCopyIRExpr(d->guard);
1472 d2->args = deepCopyIRExprVec(d->args);
1475 d2->mAddr = d->mAddr==NULL ? NULL : deepCopyIRExpr(d->mAddr);
1476 d2->mSize = d->mSize;
1477 d2->needsBBP = d->needsBBP;
1478 d2->nFxState = d->nFxState;
1479 for (i = 0; i < d2->nFxState; i++)
1480 d2->fxState[i] = d->fxState[i];
1484 IRCAS* deepCopyIRCAS ( IRCAS* cas )
1486 return mkIRCAS( cas->oldHi, cas->oldLo, cas->end,
1487 deepCopyIRExpr(cas->addr),
1488 cas->expdHi==NULL ? NULL : deepCopyIRExpr(cas->expdHi),
1489 deepCopyIRExpr(cas->expdLo),
1490 cas->dataHi==NULL ? NULL : deepCopyIRExpr(cas->dataHi),
1491 deepCopyIRExpr(cas->dataLo) );
1494 IRStmt* deepCopyIRStmt ( IRStmt* s )
1498 return IRStmt_NoOp();
1500 return IRStmt_AbiHint(deepCopyIRExpr(s->Ist.AbiHint.base),
1502 deepCopyIRExpr(s->Ist.AbiHint.nia));
1504 return IRStmt_IMark(s->Ist.IMark.addr, s->Ist.IMark.len);
1506 return IRStmt_Put(s->Ist.Put.offset,
1507 deepCopyIRExpr(s->Ist.Put.data));
1509 return IRStmt_PutI(deepCopyIRRegArray(s->Ist.PutI.descr),
1510 deepCopyIRExpr(s->Ist.PutI.ix),
1512 deepCopyIRExpr(s->Ist.PutI.data));
1514 return IRStmt_WrTmp(s->Ist.WrTmp.tmp,
1515 deepCopyIRExpr(s->Ist.WrTmp.data));
1517 return IRStmt_Store(s->Ist.Store.end,
1518 deepCopyIRExpr(s->Ist.Store.addr),
1519 deepCopyIRExpr(s->Ist.Store.data));
1521 return IRStmt_CAS(deepCopyIRCAS(s->Ist.CAS.details));
1523 return IRStmt_LLSC(s->Ist.LLSC.end,
1525 deepCopyIRExpr(s->Ist.LLSC.addr),
1526 s->Ist.LLSC.storedata
1527 ? deepCopyIRExpr(s->Ist.LLSC.storedata)
1530 return IRStmt_Dirty(deepCopyIRDirty(s->Ist.Dirty.details));
1532 return IRStmt_MBE(s->Ist.MBE.event);
1534 return IRStmt_Exit(deepCopyIRExpr(s->Ist.Exit.guard),
1536 deepCopyIRConst(s->Ist.Exit.dst));
1538 vpanic("deepCopyIRStmt");
1542 IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* src )
1545 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
1546 dst->types_size = src->types_size;
1547 dst->types_used = src->types_used;
1548 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
1549 for (i = 0; i < src->types_used; i++)
1550 dst->types[i] = src->types[i];
1554 IRSB* deepCopyIRSB ( IRSB* bb )
1558 IRSB* bb2 = deepCopyIRSBExceptStmts(bb);
1559 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
1560 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
1561 for (i = 0; i < bb2->stmts_used; i++)
1562 sts2[i] = deepCopyIRStmt(bb->stmts[i]);
1567 IRSB* deepCopyIRSBExceptStmts ( IRSB* bb )
1569 IRSB* bb2 = emptyIRSB();
1570 bb2->tyenv = deepCopyIRTypeEnv(bb->tyenv);
1571 bb2->next = deepCopyIRExpr(bb->next);
1572 bb2->jumpkind = bb->jumpkind;
1577 /*---------------------------------------------------------------*/
1578 /*--- Primop types ---*/
1579 /*---------------------------------------------------------------*/
1582 void typeOfPrimop ( IROp op,
1585 IRType* t_arg1, IRType* t_arg2,
1586 IRType* t_arg3, IRType* t_arg4 )
1588 # define UNARY(_ta1,_td) \
1589 *t_dst = (_td); *t_arg1 = (_ta1); break
1590 # define BINARY(_ta1,_ta2,_td) \
1591 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
1592 # define TERNARY(_ta1,_ta2,_ta3,_td) \
1593 *t_dst = (_td); *t_arg1 = (_ta1); \
1594 *t_arg2 = (_ta2); *t_arg3 = (_ta3); break
1595 # define QUATERNARY(_ta1,_ta2,_ta3,_ta4,_td) \
1596 *t_dst = (_td); *t_arg1 = (_ta1); \
1597 *t_arg2 = (_ta2); *t_arg3 = (_ta3); \
1598 *t_arg4 = (_ta4); break
1599 # define COMPARISON(_ta) \
1600 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
1601 # define UNARY_COMPARISON(_ta) \
1602 *t_dst = Ity_I1; *t_arg1 = (_ta); break;
1604 /* Rounding mode values are always Ity_I32, encoded as per
1606 const IRType ity_RMode = Ity_I32;
1608 *t_dst = Ity_INVALID;
1609 *t_arg1 = Ity_INVALID;
1610 *t_arg2 = Ity_INVALID;
1611 *t_arg3 = Ity_INVALID;
1612 *t_arg4 = Ity_INVALID;
1614 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
1615 case Iop_Or8: case Iop_And8: case Iop_Xor8:
1616 BINARY(Ity_I8,Ity_I8, Ity_I8);
1618 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
1619 case Iop_Or16: case Iop_And16: case Iop_Xor16:
1620 BINARY(Ity_I16,Ity_I16, Ity_I16);
1624 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
1625 case Iop_Or32: case Iop_And32: case Iop_Xor32:
1627 BINARY(Ity_I32,Ity_I32, Ity_I32);
1629 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
1630 case Iop_Or64: case Iop_And64: case Iop_Xor64:
1633 case Iop_Avg8Ux8: case Iop_Avg16Ux4:
1634 case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2:
1635 case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2:
1636 case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2:
1637 case Iop_InterleaveHI8x8: case Iop_InterleaveLO8x8:
1638 case Iop_InterleaveHI16x4: case Iop_InterleaveLO16x4:
1639 case Iop_InterleaveHI32x2: case Iop_InterleaveLO32x2:
1640 case Iop_CatOddLanes16x4: case Iop_CatEvenLanes16x4:
1642 case Iop_Max8Ux8: case Iop_Max16Sx4:
1643 case Iop_Min8Ux8: case Iop_Min16Sx4:
1644 case Iop_Mul16x4: case Iop_Mul32x2:
1645 case Iop_MulHi16Sx4: case Iop_MulHi16Ux4:
1646 case Iop_QAdd8Sx8: case Iop_QAdd16Sx4:
1647 case Iop_QAdd8Ux8: case Iop_QAdd16Ux4:
1648 case Iop_QNarrow32Sx2:
1649 case Iop_QNarrow16Sx4: case Iop_QNarrow16Ux4:
1650 case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2:
1651 case Iop_QSub8Sx8: case Iop_QSub16Sx4:
1652 case Iop_QSub8Ux8: case Iop_QSub16Ux4:
1653 BINARY(Ity_I64,Ity_I64, Ity_I64);
1655 case Iop_ShlN32x2: case Iop_ShlN16x4: case Iop_ShlN8x8:
1656 case Iop_ShrN32x2: case Iop_ShrN16x4:
1657 case Iop_SarN32x2: case Iop_SarN16x4: case Iop_SarN8x8:
1658 BINARY(Ity_I64,Ity_I8, Ity_I64);
1660 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
1661 BINARY(Ity_I8,Ity_I8, Ity_I8);
1662 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
1663 BINARY(Ity_I16,Ity_I8, Ity_I16);
1664 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
1665 BINARY(Ity_I32,Ity_I8, Ity_I32);
1666 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
1667 BINARY(Ity_I64,Ity_I8, Ity_I64);
1670 UNARY(Ity_I8, Ity_I8);
1672 UNARY(Ity_I16, Ity_I16);
1674 UNARY(Ity_I32, Ity_I32);
1677 case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8:
1678 UNARY(Ity_I64, Ity_I64);
1680 case Iop_CmpEQ8: case Iop_CmpNE8:
1681 case Iop_CasCmpEQ8: case Iop_CasCmpNE8:
1683 case Iop_CmpEQ16: case Iop_CmpNE16:
1684 case Iop_CasCmpEQ16: case Iop_CasCmpNE16:
1685 COMPARISON(Ity_I16);
1686 case Iop_CmpEQ32: case Iop_CmpNE32:
1687 case Iop_CasCmpEQ32: case Iop_CasCmpNE32:
1688 case Iop_CmpLT32S: case Iop_CmpLE32S:
1689 case Iop_CmpLT32U: case Iop_CmpLE32U:
1690 COMPARISON(Ity_I32);
1691 case Iop_CmpEQ64: case Iop_CmpNE64:
1692 case Iop_CasCmpEQ64: case Iop_CasCmpNE64:
1693 case Iop_CmpLT64S: case Iop_CmpLE64S:
1694 case Iop_CmpLT64U: case Iop_CmpLE64U:
1695 COMPARISON(Ity_I64);
1697 case Iop_CmpNEZ8: UNARY_COMPARISON(Ity_I8);
1698 case Iop_CmpNEZ16: UNARY_COMPARISON(Ity_I16);
1699 case Iop_CmpNEZ32: UNARY_COMPARISON(Ity_I32);
1700 case Iop_CmpNEZ64: UNARY_COMPARISON(Ity_I64);
1702 case Iop_Left8: UNARY(Ity_I8, Ity_I8);
1703 case Iop_Left16: UNARY(Ity_I16,Ity_I16);
1704 case Iop_CmpwNEZ32: case Iop_Left32: UNARY(Ity_I32,Ity_I32);
1705 case Iop_CmpwNEZ64: case Iop_Left64: UNARY(Ity_I64,Ity_I64);
1707 case Iop_MullU8: case Iop_MullS8:
1708 BINARY(Ity_I8,Ity_I8, Ity_I16);
1709 case Iop_MullU16: case Iop_MullS16:
1710 BINARY(Ity_I16,Ity_I16, Ity_I32);
1711 case Iop_MullU32: case Iop_MullS32:
1712 BINARY(Ity_I32,Ity_I32, Ity_I64);
1713 case Iop_MullU64: case Iop_MullS64:
1714 BINARY(Ity_I64,Ity_I64, Ity_I128);
1716 case Iop_Clz32: case Iop_Ctz32:
1717 UNARY(Ity_I32, Ity_I32);
1719 case Iop_Clz64: case Iop_Ctz64:
1720 UNARY(Ity_I64, Ity_I64);
1722 case Iop_DivU32: case Iop_DivS32:
1723 BINARY(Ity_I32,Ity_I32, Ity_I32);
1725 case Iop_DivU64: case Iop_DivS64:
1726 BINARY(Ity_I64,Ity_I64, Ity_I64);
1728 case Iop_DivModU64to32: case Iop_DivModS64to32:
1729 BINARY(Ity_I64,Ity_I32, Ity_I64);
1731 case Iop_DivModU128to64: case Iop_DivModS128to64:
1732 BINARY(Ity_I128,Ity_I64, Ity_I128);
1734 case Iop_16HIto8: case Iop_16to8:
1735 UNARY(Ity_I16, Ity_I8);
1737 BINARY(Ity_I8,Ity_I8, Ity_I16);
1739 case Iop_32HIto16: case Iop_32to16:
1740 UNARY(Ity_I32, Ity_I16);
1742 BINARY(Ity_I16,Ity_I16, Ity_I32);
1744 case Iop_64HIto32: case Iop_64to32:
1745 UNARY(Ity_I64, Ity_I32);
1747 BINARY(Ity_I32,Ity_I32, Ity_I64);
1749 case Iop_128HIto64: case Iop_128to64:
1750 UNARY(Ity_I128, Ity_I64);
1752 BINARY(Ity_I64,Ity_I64, Ity_I128);
1754 case Iop_Not1: UNARY(Ity_I1, Ity_I1);
1755 case Iop_1Uto8: UNARY(Ity_I1, Ity_I8);
1756 case Iop_1Sto8: UNARY(Ity_I1, Ity_I8);
1757 case Iop_1Sto16: UNARY(Ity_I1, Ity_I16);
1758 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I1, Ity_I32);
1759 case Iop_1Sto64: case Iop_1Uto64: UNARY(Ity_I1, Ity_I64);
1760 case Iop_32to1: UNARY(Ity_I32, Ity_I1);
1761 case Iop_64to1: UNARY(Ity_I64, Ity_I1);
1763 case Iop_8Uto32: case Iop_8Sto32:
1764 UNARY(Ity_I8, Ity_I32);
1766 case Iop_8Uto16: case Iop_8Sto16:
1767 UNARY(Ity_I8, Ity_I16);
1769 case Iop_16Uto32: case Iop_16Sto32:
1770 UNARY(Ity_I16, Ity_I32);
1772 case Iop_32Sto64: case Iop_32Uto64:
1773 UNARY(Ity_I32, Ity_I64);
1775 case Iop_8Uto64: case Iop_8Sto64:
1776 UNARY(Ity_I8, Ity_I64);
1778 case Iop_16Uto64: case Iop_16Sto64:
1779 UNARY(Ity_I16, Ity_I64);
1781 UNARY(Ity_I64, Ity_I16);
1783 case Iop_32to8: UNARY(Ity_I32, Ity_I8);
1784 case Iop_64to8: UNARY(Ity_I64, Ity_I8);
1786 case Iop_AddF64: case Iop_SubF64:
1787 case Iop_MulF64: case Iop_DivF64:
1788 case Iop_AddF64r32: case Iop_SubF64r32:
1789 case Iop_MulF64r32: case Iop_DivF64r32:
1790 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1792 case Iop_AddF32: case Iop_SubF32:
1793 case Iop_MulF32: case Iop_DivF32:
1794 TERNARY(ity_RMode,Ity_F32,Ity_F32, Ity_F32);
1796 case Iop_NegF64: case Iop_AbsF64:
1797 UNARY(Ity_F64, Ity_F64);
1799 case Iop_NegF32: case Iop_AbsF32:
1800 UNARY(Ity_F32, Ity_F32);
1803 case Iop_SqrtF64r32:
1804 BINARY(ity_RMode,Ity_F64, Ity_F64);
1807 BINARY(ity_RMode,Ity_F32, Ity_F32);
1810 BINARY(Ity_F64,Ity_F64, Ity_I32);
1812 case Iop_F64toI16S: BINARY(ity_RMode,Ity_F64, Ity_I16);
1813 case Iop_F64toI32S: BINARY(ity_RMode,Ity_F64, Ity_I32);
1814 case Iop_F64toI64S: BINARY(ity_RMode,Ity_F64, Ity_I64);
1816 case Iop_F64toI32U: BINARY(ity_RMode,Ity_F64, Ity_I32);
1818 case Iop_I16StoF64: UNARY(Ity_I16, Ity_F64);
1819 case Iop_I32StoF64: UNARY(Ity_I32, Ity_F64);
1820 case Iop_I64StoF64: BINARY(ity_RMode,Ity_I64, Ity_F64);
1822 case Iop_I32UtoF64: UNARY(Ity_I32, Ity_F64);
1824 case Iop_F32toF64: UNARY(Ity_F32, Ity_F64);
1825 case Iop_F64toF32: BINARY(ity_RMode,Ity_F64, Ity_F32);
1827 case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64);
1828 case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64);
1829 case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32);
1830 case Iop_ReinterpF32asI32: UNARY(Ity_F32, Ity_I32);
1832 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
1833 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
1834 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1836 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
1837 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_I32);
1839 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64:
1841 case Iop_RoundF64toInt: BINARY(ity_RMode,Ity_F64, Ity_F64);
1843 case Iop_MAddF64: case Iop_MSubF64:
1844 case Iop_MAddF64r32: case Iop_MSubF64r32:
1845 QUATERNARY(ity_RMode,Ity_F64,Ity_F64,Ity_F64, Ity_F64);
1847 case Iop_Est5FRSqrt:
1848 case Iop_RoundF64toF64_NEAREST: case Iop_RoundF64toF64_NegINF:
1849 case Iop_RoundF64toF64_PosINF: case Iop_RoundF64toF64_ZERO:
1850 UNARY(Ity_F64, Ity_F64);
1851 case Iop_RoundF64toF32:
1852 BINARY(ity_RMode,Ity_F64, Ity_F64);
1854 UNARY(Ity_F64, Ity_I32);
1855 case Iop_TruncF64asF32:
1856 UNARY(Ity_F64, Ity_F32);
1860 case Iop_QFtoI32Ux4_RZ:
1861 case Iop_QFtoI32Sx4_RZ:
1862 case Iop_RoundF32x4_RM:
1863 case Iop_RoundF32x4_RP:
1864 case Iop_RoundF32x4_RN:
1865 case Iop_RoundF32x4_RZ:
1866 UNARY(Ity_V128, Ity_V128);
1868 case Iop_64HLtoV128: BINARY(Ity_I64,Ity_I64, Ity_V128);
1869 case Iop_V128to64: case Iop_V128HIto64:
1870 UNARY(Ity_V128, Ity_I64);
1872 case Iop_V128to32: UNARY(Ity_V128, Ity_I32);
1873 case Iop_32UtoV128: UNARY(Ity_I32, Ity_V128);
1874 case Iop_64UtoV128: UNARY(Ity_I64, Ity_V128);
1875 case Iop_SetV128lo32: BINARY(Ity_V128,Ity_I32, Ity_V128);
1876 case Iop_SetV128lo64: BINARY(Ity_V128,Ity_I64, Ity_V128);
1878 case Iop_Dup8x16: UNARY(Ity_I8, Ity_V128);
1879 case Iop_Dup16x8: UNARY(Ity_I16, Ity_V128);
1880 case Iop_Dup32x4: UNARY(Ity_I32, Ity_V128);
1882 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
1883 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
1884 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
1885 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
1886 case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4:
1887 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
1888 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
1889 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
1890 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
1891 case Iop_Add32Fx4: case Iop_Add32F0x4:
1892 case Iop_Add64Fx2: case Iop_Add64F0x2:
1893 case Iop_Div32Fx4: case Iop_Div32F0x4:
1894 case Iop_Div64Fx2: case Iop_Div64F0x2:
1895 case Iop_Max32Fx4: case Iop_Max32F0x4:
1896 case Iop_Max64Fx2: case Iop_Max64F0x2:
1897 case Iop_Min32Fx4: case Iop_Min32F0x4:
1898 case Iop_Min64Fx2: case Iop_Min64F0x2:
1899 case Iop_Mul32Fx4: case Iop_Mul32F0x4:
1900 case Iop_Mul64Fx2: case Iop_Mul64F0x2:
1901 case Iop_Sub32Fx4: case Iop_Sub32F0x4:
1902 case Iop_Sub64Fx2: case Iop_Sub64F0x2:
1903 case Iop_AndV128: case Iop_OrV128: case Iop_XorV128:
1904 case Iop_Add8x16: case Iop_Add16x8:
1905 case Iop_Add32x4: case Iop_Add64x2:
1906 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8: case Iop_QAdd32Ux4:
1907 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8: case Iop_QAdd32Sx4:
1908 case Iop_Sub8x16: case Iop_Sub16x8:
1909 case Iop_Sub32x4: case Iop_Sub64x2:
1910 case Iop_QSub8Ux16: case Iop_QSub16Ux8: case Iop_QSub32Ux4:
1911 case Iop_QSub8Sx16: case Iop_QSub16Sx8: case Iop_QSub32Sx4:
1913 case Iop_MulHi16Ux8: case Iop_MulHi32Ux4:
1914 case Iop_MulHi16Sx8: case Iop_MulHi32Sx4:
1915 case Iop_MullEven8Ux16: case Iop_MullEven16Ux8:
1916 case Iop_MullEven8Sx16: case Iop_MullEven16Sx8:
1917 case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4:
1918 case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4:
1919 case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4:
1920 case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4:
1921 case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4:
1922 case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4:
1923 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
1924 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
1925 case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4:
1926 case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4:
1927 case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4:
1928 case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4:
1929 case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4:
1930 case Iop_QNarrow16Ux8: case Iop_QNarrow32Ux4:
1931 case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4:
1932 case Iop_Narrow16x8: case Iop_Narrow32x4:
1933 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
1934 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
1935 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
1936 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
1938 BINARY(Ity_V128,Ity_V128, Ity_V128);
1941 case Iop_Recip32Fx4: case Iop_Recip32F0x4:
1942 case Iop_Recip64Fx2: case Iop_Recip64F0x2:
1943 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
1944 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
1945 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4:
1946 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2:
1947 case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8:
1948 case Iop_CmpNEZ32x4: case Iop_CmpNEZ64x2:
1949 UNARY(Ity_V128, Ity_V128);
1951 case Iop_ShlV128: case Iop_ShrV128:
1952 case Iop_ShlN8x16: case Iop_ShlN16x8:
1953 case Iop_ShlN32x4: case Iop_ShlN64x2:
1954 case Iop_ShrN8x16: case Iop_ShrN16x8:
1955 case Iop_ShrN32x4: case Iop_ShrN64x2:
1956 case Iop_SarN8x16: case Iop_SarN16x8: case Iop_SarN32x4:
1957 BINARY(Ity_V128,Ity_I8, Ity_V128);
1961 vpanic("typeOfPrimop");
1967 # undef UNARY_COMPARISON
1971 /*---------------------------------------------------------------*/
1972 /*--- Helper functions for the IR -- IR Basic Blocks ---*/
1973 /*---------------------------------------------------------------*/
1975 void addStmtToIRSB ( IRSB* bb, IRStmt* st )
1978 if (bb->stmts_used == bb->stmts_size) {
1979 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1980 for (i = 0; i < bb->stmts_size; i++)
1981 stmts2[i] = bb->stmts[i];
1983 bb->stmts_size *= 2;
1985 vassert(bb->stmts_used < bb->stmts_size);
1986 bb->stmts[bb->stmts_used] = st;
1991 /*---------------------------------------------------------------*/
1992 /*--- Helper functions for the IR -- IR Type Environments ---*/
1993 /*---------------------------------------------------------------*/
1995 /* Allocate a new IRTemp, given its type. */
1997 IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
2000 vassert(env->types_used >= 0);
2001 vassert(env->types_size >= 0);
2002 vassert(env->types_used <= env->types_size);
2003 if (env->types_used < env->types_size) {
2004 env->types[env->types_used] = ty;
2005 return env->types_used++;
2008 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
2010 = LibVEX_Alloc(new_size * sizeof(IRType));
2011 for (i = 0; i < env->types_used; i++)
2012 new_types[i] = env->types[i];
2013 env->types = new_types;
2014 env->types_size = new_size;
2015 return newIRTemp(env, ty);
2020 /*---------------------------------------------------------------*/
2021 /*--- Helper functions for the IR -- finding types of exprs ---*/
2022 /*---------------------------------------------------------------*/
2025 IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
2028 vassert(tmp < env->types_used);
2029 return env->types[tmp];
2033 IRType typeOfIRConst ( IRConst* con )
2036 case Ico_U1: return Ity_I1;
2037 case Ico_U8: return Ity_I8;
2038 case Ico_U16: return Ity_I16;
2039 case Ico_U32: return Ity_I32;
2040 case Ico_U64: return Ity_I64;
2041 case Ico_F64: return Ity_F64;
2042 case Ico_F64i: return Ity_F64;
2043 case Ico_V128: return Ity_V128;
2044 default: vpanic("typeOfIRConst");
2048 IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
2050 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
2054 return e->Iex.Load.ty;
2056 return e->Iex.Get.ty;
2058 return e->Iex.GetI.descr->elemTy;
2060 return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp);
2062 return typeOfIRConst(e->Iex.Const.con);
2064 typeOfPrimop(e->Iex.Qop.op,
2065 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2068 typeOfPrimop(e->Iex.Triop.op,
2069 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2072 typeOfPrimop(e->Iex.Binop.op,
2073 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2076 typeOfPrimop(e->Iex.Unop.op,
2077 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2080 return e->Iex.CCall.retty;
2082 e = e->Iex.Mux0X.expr0;
2084 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
2086 vpanic("typeOfIRExpr: Binder is not a valid expression");
2089 vpanic("typeOfIRExpr");
2093 /* Is this any value actually in the enumeration 'IRType' ? */
2094 Bool isPlausibleIRType ( IRType ty )
2097 case Ity_INVALID: case Ity_I1:
2098 case Ity_I8: case Ity_I16: case Ity_I32:
2099 case Ity_I64: case Ity_I128:
2100 case Ity_F32: case Ity_F64:
2109 /*---------------------------------------------------------------*/
2110 /*--- Sanity checking -- FLATNESS ---*/
2111 /*---------------------------------------------------------------*/
2113 /* Check that the canonical flatness constraints hold on an
2114 IRStmt. The only place where any expression is allowed to be
2115 non-atomic is the RHS of IRStmt_Tmp. */
2118 inline static Bool isAtom ( IRExpr* e ) {
2119 return e->tag == Iex_RdTmp || e->tag == Iex_Const;
2123 Bool isFlatIRStmt ( IRStmt* st )
2132 return isIRAtom(st->Ist.AbiHint.base)
2133 && isIRAtom(st->Ist.AbiHint.nia);
2135 return isIRAtom(st->Ist.Put.data);
2137 return toBool( isIRAtom(st->Ist.PutI.ix)
2138 && isIRAtom(st->Ist.PutI.data) );
2140 /* This is the only interesting case. The RHS can be any
2141 expression, *but* all its subexpressions *must* be
2143 e = st->Ist.WrTmp.data;
2145 case Iex_Binder: return True;
2146 case Iex_Get: return True;
2147 case Iex_GetI: return isIRAtom(e->Iex.GetI.ix);
2148 case Iex_RdTmp: return True;
2149 case Iex_Qop: return toBool(
2150 isIRAtom(e->Iex.Qop.arg1)
2151 && isIRAtom(e->Iex.Qop.arg2)
2152 && isIRAtom(e->Iex.Qop.arg3)
2153 && isIRAtom(e->Iex.Qop.arg4));
2154 case Iex_Triop: return toBool(
2155 isIRAtom(e->Iex.Triop.arg1)
2156 && isIRAtom(e->Iex.Triop.arg2)
2157 && isIRAtom(e->Iex.Triop.arg3));
2158 case Iex_Binop: return toBool(
2159 isIRAtom(e->Iex.Binop.arg1)
2160 && isIRAtom(e->Iex.Binop.arg2));
2161 case Iex_Unop: return isIRAtom(e->Iex.Unop.arg);
2162 case Iex_Load: return isIRAtom(e->Iex.Load.addr);
2163 case Iex_Const: return True;
2164 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
2165 if (!isIRAtom(e->Iex.CCall.args[i]))
2168 case Iex_Mux0X: return toBool (
2169 isIRAtom(e->Iex.Mux0X.cond)
2170 && isIRAtom(e->Iex.Mux0X.expr0)
2171 && isIRAtom(e->Iex.Mux0X.exprX));
2172 default: vpanic("isFlatIRStmt(e)");
2177 return toBool( isIRAtom(st->Ist.Store.addr)
2178 && isIRAtom(st->Ist.Store.data) );
2180 cas = st->Ist.CAS.details;
2181 return toBool( isIRAtom(cas->addr)
2182 && (cas->expdHi ? isIRAtom(cas->expdHi) : True)
2183 && isIRAtom(cas->expdLo)
2184 && (cas->dataHi ? isIRAtom(cas->dataHi) : True)
2185 && isIRAtom(cas->dataLo) );
2187 return toBool( isIRAtom(st->Ist.LLSC.addr)
2188 && (st->Ist.LLSC.storedata
2189 ? isIRAtom(st->Ist.LLSC.storedata) : True) );
2191 di = st->Ist.Dirty.details;
2192 if (!isIRAtom(di->guard))
2194 for (i = 0; di->args[i]; i++)
2195 if (!isIRAtom(di->args[i]))
2197 if (di->mAddr && !isIRAtom(di->mAddr))
2205 return isIRAtom(st->Ist.Exit.guard);
2207 vpanic("isFlatIRStmt(st)");
2212 /*---------------------------------------------------------------*/
2213 /*--- Sanity checking ---*/
2214 /*---------------------------------------------------------------*/
2218 Everything is type-consistent. No ill-typed anything.
2219 The target address at the end of the BB is a 32- or 64-
2220 bit expression, depending on the guest's word size.
2222 Each temp is assigned only once, before its uses.
2225 static inline Int countArgs ( IRExpr** args )
2228 for (i = 0; args[i]; i++)
2234 __attribute((noreturn))
2235 void sanityCheckFail ( IRSB* bb, IRStmt* stmt, HChar* what )
2237 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
2240 vex_printf("\nIN STATEMENT:\n\n");
2243 vex_printf("\n\nERROR = %s\n\n", what );
2244 vpanic("sanityCheckFail: exiting due to bad IR");
2247 static Bool saneIRRegArray ( IRRegArray* arr )
2249 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
2251 if (arr->elemTy == Ity_I1)
2253 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
2258 static Bool saneIRCallee ( IRCallee* cee )
2260 if (cee->name == NULL)
2264 if (cee->regparms < 0 || cee->regparms > 3)
2269 static Bool saneIRConst ( IRConst* con )
2273 return toBool( con->Ico.U1 == True || con->Ico.U1 == False );
2275 /* Is there anything we can meaningfully check? I don't
2281 /* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
2282 range ones. Report any which are read and for which the current
2283 def_count is zero. */
2286 void useBeforeDef_Temp ( IRSB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
2288 if (tmp < 0 || tmp >= bb->tyenv->types_used)
2289 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
2290 if (def_counts[tmp] < 1)
2291 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
2295 void useBeforeDef_Expr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
2298 switch (expr->tag) {
2302 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
2305 useBeforeDef_Temp(bb,stmt,expr->Iex.RdTmp.tmp,def_counts);
2308 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg1,def_counts);
2309 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg2,def_counts);
2310 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg3,def_counts);
2311 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg4,def_counts);
2314 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg1,def_counts);
2315 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg2,def_counts);
2316 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg3,def_counts);
2319 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
2320 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
2323 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
2326 useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
2331 for (i = 0; expr->Iex.CCall.args[i]; i++)
2332 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
2335 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
2336 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
2337 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
2340 vpanic("useBeforeDef_Expr");
2345 void useBeforeDef_Stmt ( IRSB* bb, IRStmt* stmt, Int* def_counts )
2350 switch (stmt->tag) {
2354 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
2355 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.nia,def_counts);
2358 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
2361 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
2362 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
2365 useBeforeDef_Expr(bb,stmt,stmt->Ist.WrTmp.data,def_counts);
2368 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
2369 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
2372 cas = stmt->Ist.CAS.details;
2373 useBeforeDef_Expr(bb,stmt,cas->addr,def_counts);
2375 useBeforeDef_Expr(bb,stmt,cas->expdHi,def_counts);
2376 useBeforeDef_Expr(bb,stmt,cas->expdLo,def_counts);
2378 useBeforeDef_Expr(bb,stmt,cas->dataHi,def_counts);
2379 useBeforeDef_Expr(bb,stmt,cas->dataLo,def_counts);
2382 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.addr,def_counts);
2383 if (stmt->Ist.LLSC.storedata != NULL)
2384 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.storedata,def_counts);
2387 d = stmt->Ist.Dirty.details;
2388 for (i = 0; d->args[i] != NULL; i++)
2389 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
2390 if (d->mFx != Ifx_None)
2391 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
2397 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
2400 vpanic("useBeforeDef_Stmt");
2405 void tcExpr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
2408 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
2409 IRTypeEnv* tyenv = bb->tyenv;
2410 switch (expr->tag) {
2415 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
2416 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
2417 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
2418 if (!saneIRRegArray(expr->Iex.GetI.descr))
2419 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
2422 IRType ttarg1, ttarg2, ttarg3, ttarg4;
2423 tcExpr(bb,stmt, expr->Iex.Qop.arg1, gWordTy );
2424 tcExpr(bb,stmt, expr->Iex.Qop.arg2, gWordTy );
2425 tcExpr(bb,stmt, expr->Iex.Qop.arg3, gWordTy );
2426 tcExpr(bb,stmt, expr->Iex.Qop.arg4, gWordTy );
2427 typeOfPrimop(expr->Iex.Qop.op,
2428 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2429 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
2430 || t_arg3 == Ity_INVALID || t_arg4 == Ity_INVALID) {
2431 vex_printf(" op name: " );
2432 ppIROp(expr->Iex.Qop.op);
2434 sanityCheckFail(bb,stmt,
2435 "Iex.Qop: wrong arity op\n"
2436 "... name of op precedes BB printout\n");
2438 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg1);
2439 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg2);
2440 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg3);
2441 ttarg4 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg4);
2442 if (t_arg1 != ttarg1 || t_arg2 != ttarg2
2443 || t_arg3 != ttarg3 || t_arg4 != ttarg4) {
2444 vex_printf(" op name: ");
2445 ppIROp(expr->Iex.Qop.op);
2447 vex_printf(" op type is (");
2455 vex_printf(") -> ");
2457 vex_printf("\narg tys are (");
2466 sanityCheckFail(bb,stmt,
2467 "Iex.Qop: arg tys don't match op tys\n"
2468 "... additional details precede BB printout\n");
2473 IRType ttarg1, ttarg2, ttarg3;
2474 tcExpr(bb,stmt, expr->Iex.Triop.arg1, gWordTy );
2475 tcExpr(bb,stmt, expr->Iex.Triop.arg2, gWordTy );
2476 tcExpr(bb,stmt, expr->Iex.Triop.arg3, gWordTy );
2477 typeOfPrimop(expr->Iex.Triop.op,
2478 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2479 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
2480 || t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) {
2481 vex_printf(" op name: " );
2482 ppIROp(expr->Iex.Triop.op);
2484 sanityCheckFail(bb,stmt,
2485 "Iex.Triop: wrong arity op\n"
2486 "... name of op precedes BB printout\n");
2488 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg1);
2489 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg2);
2490 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg3);
2491 if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
2492 vex_printf(" op name: ");
2493 ppIROp(expr->Iex.Triop.op);
2495 vex_printf(" op type is (");
2501 vex_printf(") -> ");
2503 vex_printf("\narg tys are (");
2510 sanityCheckFail(bb,stmt,
2511 "Iex.Triop: arg tys don't match op tys\n"
2512 "... additional details precede BB printout\n");
2517 IRType ttarg1, ttarg2;
2518 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
2519 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
2520 typeOfPrimop(expr->Iex.Binop.op,
2521 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2522 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
2523 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) {
2524 vex_printf(" op name: " );
2525 ppIROp(expr->Iex.Binop.op);
2527 sanityCheckFail(bb,stmt,
2528 "Iex.Binop: wrong arity op\n"
2529 "... name of op precedes BB printout\n");
2531 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
2532 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
2533 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
2534 vex_printf(" op name: ");
2535 ppIROp(expr->Iex.Binop.op);
2537 vex_printf(" op type is (");
2541 vex_printf(") -> ");
2543 vex_printf("\narg tys are (");
2548 sanityCheckFail(bb,stmt,
2549 "Iex.Binop: arg tys don't match op tys\n"
2550 "... additional details precede BB printout\n");
2555 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
2556 typeOfPrimop(expr->Iex.Binop.op,
2557 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2558 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
2559 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
2560 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
2561 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
2562 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
2565 tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
2566 if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
2567 sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
2568 if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
2569 sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
2572 if (!saneIRCallee(expr->Iex.CCall.cee))
2573 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
2574 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
2575 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
2576 for (i = 0; expr->Iex.CCall.args[i]; i++) {
2578 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
2579 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
2581 if (expr->Iex.CCall.retty == Ity_I1)
2582 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
2583 for (i = 0; expr->Iex.CCall.args[i]; i++)
2584 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
2585 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
2588 if (!saneIRConst(expr->Iex.Const.con))
2589 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
2592 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
2593 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
2594 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
2595 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
2596 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
2597 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
2598 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
2599 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
2608 void tcStmt ( IRSB* bb, IRStmt* stmt, IRType gWordTy )
2613 IRType tyExpd, tyData;
2614 IRTypeEnv* tyenv = bb->tyenv;
2615 switch (stmt->tag) {
2617 /* Somewhat heuristic, but rule out totally implausible
2618 instruction sizes. */
2619 if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20)
2620 sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible");
2623 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
2624 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
2625 "not :: guest word type");
2626 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy)
2627 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: "
2628 "not :: guest word type");
2631 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
2632 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
2633 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
2636 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
2637 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
2638 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
2639 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
2640 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data)
2641 != stmt->Ist.PutI.descr->elemTy)
2642 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
2643 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
2644 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
2645 if (!saneIRRegArray(stmt->Ist.PutI.descr))
2646 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
2649 tcExpr( bb, stmt, stmt->Ist.WrTmp.data, gWordTy );
2650 if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
2651 != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
2652 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
2655 tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
2656 tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
2657 if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
2658 sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type");
2659 if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
2660 sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1");
2661 if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
2662 sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness");
2665 cas = stmt->Ist.CAS.details;
2666 /* make sure it's definitely either a CAS or a DCAS */
2667 if (cas->oldHi == IRTemp_INVALID
2668 && cas->expdHi == NULL && cas->dataHi == NULL) {
2669 /* fine; it's a single cas */
2672 if (cas->oldHi != IRTemp_INVALID
2673 && cas->expdHi != NULL && cas->dataHi != NULL) {
2674 /* fine; it's a double cas */
2677 /* it's some el-mutanto hybrid */
2680 /* check the address type */
2681 tcExpr( bb, stmt, cas->addr, gWordTy );
2682 if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
2683 /* check types on the {old,expd,data}Lo components agree */
2684 tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
2685 tyData = typeOfIRExpr(tyenv, cas->dataLo);
2686 if (tyExpd != tyData) goto bad_cas;
2687 if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo))
2689 /* check the base element type is sane */
2690 if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32
2691 || (gWordTy == Ity_I64 && tyExpd == Ity_I64)) {
2696 /* If it's a DCAS, check types on the {old,expd,data}Hi
2698 if (cas->oldHi != IRTemp_INVALID) {
2699 tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
2700 tyData = typeOfIRExpr(tyenv, cas->dataHi);
2701 if (tyExpd != tyData) goto bad_cas;
2702 if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi))
2704 /* and finally check that oldLo and oldHi have the same
2705 type. This forces equivalence amongst all 6 types. */
2706 if (typeOfIRTemp(tyenv, cas->oldHi)
2707 != typeOfIRTemp(tyenv, cas->oldLo))
2712 sanityCheckFail(bb,stmt,"IRStmt.CAS: ill-formed");
2716 if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy)
2717 sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type");
2718 if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE)
2719 sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness");
2720 tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result);
2721 if (stmt->Ist.LLSC.storedata == NULL) {
2723 if (tyRes != Ity_I64 && tyRes != Ity_I32 && tyRes != Ity_I8)
2724 sanityCheckFail(bb,stmt,"Ist.LLSC(LL).result :: bogus");
2727 if (tyRes != Ity_I1)
2728 sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1");
2729 tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata);
2730 if (tyData != Ity_I64 && tyData != Ity_I32 && tyData != Ity_I8)
2731 sanityCheckFail(bb,stmt,
2732 "Ist.LLSC(SC).result :: storedata bogus");
2737 /* Mostly check for various kinds of ill-formed dirty calls. */
2738 d = stmt->Ist.Dirty.details;
2739 if (d->cee == NULL) goto bad_dirty;
2740 if (!saneIRCallee(d->cee)) goto bad_dirty;
2741 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
2742 if (d->mFx == Ifx_None) {
2743 if (d->mAddr != NULL || d->mSize != 0)
2746 if (d->mAddr == NULL || d->mSize == 0)
2749 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
2751 if (d->nFxState == 0 && d->needsBBP)
2753 for (i = 0; i < d->nFxState; i++) {
2754 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
2755 if (d->fxState[i].size <= 0) goto bad_dirty;
2757 /* check types, minimally */
2758 if (d->guard == NULL) goto bad_dirty;
2759 tcExpr( bb, stmt, d->guard, gWordTy );
2760 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
2761 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
2762 if (d->tmp != IRTemp_INVALID
2763 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
2764 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
2765 for (i = 0; d->args[i] != NULL; i++) {
2767 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
2768 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
2769 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
2773 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
2778 switch (stmt->Ist.MBE.event) {
2781 default: sanityCheckFail(bb,stmt,"IRStmt.MBE.event: unknown");
2786 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
2787 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
2788 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
2789 if (!saneIRConst(stmt->Ist.Exit.dst))
2790 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
2791 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
2792 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
2799 void sanityCheckIRSB ( IRSB* bb, HChar* caller,
2800 Bool require_flat, IRType guest_word_size )
2804 Int n_temps = bb->tyenv->types_used;
2805 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
2808 vex_printf("sanityCheck: %s\n", caller);
2810 vassert(guest_word_size == Ity_I32
2811 || guest_word_size == Ity_I64);
2813 if (bb->stmts_used < 0 || bb->stmts_size < 8
2814 || bb->stmts_used > bb->stmts_size)
2815 /* this BB is so strange we can't even print it */
2816 vpanic("sanityCheckIRSB: stmts array limits wierd");
2818 /* Ensure each temp has a plausible type. */
2819 for (i = 0; i < n_temps; i++) {
2820 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
2821 if (!isPlausibleIRType(ty)) {
2822 vex_printf("Temp t%d declared with implausible type 0x%x\n",
2824 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
2828 /* Check for flatness, if required. */
2830 for (i = 0; i < bb->stmts_used; i++) {
2831 stmt = bb->stmts[i];
2833 sanityCheckFail(bb, stmt, "IRStmt: is NULL");
2834 if (!isFlatIRStmt(stmt))
2835 sanityCheckFail(bb, stmt, "IRStmt: is not flat");
2837 if (!isIRAtom(bb->next))
2838 sanityCheckFail(bb, NULL, "bb->next is not an atom");
2841 /* Count the defs of each temp. Only one def is allowed.
2842 Also, check that each used temp has already been defd. */
2844 for (i = 0; i < n_temps; i++)
2847 for (i = 0; i < bb->stmts_used; i++) {
2850 stmt = bb->stmts[i];
2851 /* Check any temps used by this statement. */
2852 useBeforeDef_Stmt(bb,stmt,def_counts);
2854 /* Now make note of any temps defd by this statement. */
2855 switch (stmt->tag) {
2857 if (stmt->Ist.WrTmp.tmp < 0 || stmt->Ist.WrTmp.tmp >= n_temps)
2858 sanityCheckFail(bb, stmt,
2859 "IRStmt.Tmp: destination tmp is out of range");
2860 def_counts[stmt->Ist.WrTmp.tmp]++;
2861 if (def_counts[stmt->Ist.WrTmp.tmp] > 1)
2862 sanityCheckFail(bb, stmt,
2863 "IRStmt.Tmp: destination tmp is assigned more than once");
2868 if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
2869 d = stmt->Ist.Dirty.details;
2870 if (d->tmp < 0 || d->tmp >= n_temps)
2871 sanityCheckFail(bb, stmt,
2872 "IRStmt.Dirty: destination tmp is out of range");
2873 def_counts[d->tmp]++;
2874 if (def_counts[d->tmp] > 1)
2875 sanityCheckFail(bb, stmt,
2876 "IRStmt.Dirty: destination tmp is assigned more than once");
2880 cas = stmt->Ist.CAS.details;
2881 if (cas->oldHi != IRTemp_INVALID) {
2882 if (cas->oldHi < 0 || cas->oldHi >= n_temps)
2883 sanityCheckFail(bb, stmt,
2884 "IRStmt.CAS: destination tmpHi is out of range");
2885 def_counts[cas->oldHi]++;
2886 if (def_counts[cas->oldHi] > 1)
2887 sanityCheckFail(bb, stmt,
2888 "IRStmt.CAS: destination tmpHi is assigned more than once");
2890 if (cas->oldLo < 0 || cas->oldLo >= n_temps)
2891 sanityCheckFail(bb, stmt,
2892 "IRStmt.CAS: destination tmpLo is out of range");
2893 def_counts[cas->oldLo]++;
2894 if (def_counts[cas->oldLo] > 1)
2895 sanityCheckFail(bb, stmt,
2896 "IRStmt.CAS: destination tmpLo is assigned more than once");
2899 if (stmt->Ist.LLSC.result < 0 || stmt->Ist.LLSC.result >= n_temps)
2900 sanityCheckFail(bb, stmt,
2901 "IRStmt.LLSC: destination tmp is out of range");
2902 def_counts[stmt->Ist.LLSC.result]++;
2903 if (def_counts[stmt->Ist.LLSC.result] > 1)
2904 sanityCheckFail(bb, stmt,
2905 "IRStmt.LLSC: destination tmp is assigned more than once");
2908 /* explicitly handle the rest, so as to keep gcc quiet */
2913 /* Typecheck everything. */
2914 for (i = 0; i < bb->stmts_used; i++)
2916 tcStmt( bb, bb->stmts[i], guest_word_size );
2917 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
2918 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
2921 /*---------------------------------------------------------------*/
2922 /*--- Misc helper functions ---*/
2923 /*---------------------------------------------------------------*/
2925 Bool eqIRConst ( IRConst* c1, IRConst* c2 )
2927 if (c1->tag != c2->tag)
2931 case Ico_U1: return toBool( (1 & c1->Ico.U1) == (1 & c2->Ico.U1) );
2932 case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 );
2933 case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 );
2934 case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 );
2935 case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 );
2936 case Ico_F64: return toBool( c1->Ico.F64 == c2->Ico.F64 );
2937 case Ico_F64i: return toBool( c1->Ico.F64i == c2->Ico.F64i );
2938 case Ico_V128: return toBool( c1->Ico.V128 == c2->Ico.V128 );
2939 default: vpanic("eqIRConst");
2943 Bool eqIRRegArray ( IRRegArray* descr1, IRRegArray* descr2 )
2945 return toBool( descr1->base == descr2->base
2946 && descr1->elemTy == descr2->elemTy
2947 && descr1->nElems == descr2->nElems );
2950 Int sizeofIRType ( IRType ty )
2953 case Ity_I8: return 1;
2954 case Ity_I16: return 2;
2955 case Ity_I32: return 4;
2956 case Ity_I64: return 8;
2957 case Ity_F32: return 4;
2958 case Ity_F64: return 8;
2959 case Ity_V128: return 16;
2960 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
2961 vpanic("sizeofIRType");
2965 IRExpr* mkIRExpr_HWord ( HWord hw )
2967 vassert(sizeof(void*) == sizeof(HWord));
2968 if (sizeof(HWord) == 4)
2969 return IRExpr_Const(IRConst_U32((UInt)hw));
2970 if (sizeof(HWord) == 8)
2971 return IRExpr_Const(IRConst_U64((ULong)hw));
2972 vpanic("mkIRExpr_HWord");
2975 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
2978 IRDirty* d = emptyIRDirty();
2979 d->cee = mkIRCallee ( regparms, name, addr );
2980 d->guard = IRExpr_Const(IRConst_U1(True));
2985 IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
2986 Int regparms, HChar* name, void* addr,
2989 IRDirty* d = emptyIRDirty();
2990 d->cee = mkIRCallee ( regparms, name, addr );
2991 d->guard = IRExpr_Const(IRConst_U1(True));
2997 IRExpr* mkIRExprCCall ( IRType retty,
2998 Int regparms, HChar* name, void* addr,
3001 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
3005 Bool eqIRAtom ( IRExpr* a1, IRExpr* a2 )
3007 vassert(isIRAtom(a1));
3008 vassert(isIRAtom(a2));
3009 if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp)
3010 return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp);
3011 if (a1->tag == Iex_Const && a2->tag == Iex_Const)
3012 return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
3016 /*---------------------------------------------------------------*/
3017 /*--- end ir_defs.c ---*/
3018 /*---------------------------------------------------------------*/