blob: 088fe2abb45dce9a14d240cd681a1b5b46d76608 [file] [log] [blame]
sewardjec6ad592004-06-20 12:26:53 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardjc0ee2ed2004-07-27 10:29:41 +00004/*--- This file (ir/irdefs.c) is ---*/
sewardjdbcfae72005-08-02 11:14:04 +00005/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/
sewardjec6ad592004-06-20 12:26:53 +00006/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjf8ed9d82004-11-12 17:40:23 +00009/*
10 This file is part of LibVEX, a library for dynamic binary
11 instrumentation and translation.
12
sewardj7bd6ffe2005-08-03 16:07:36 +000013 Copyright (C) 2004-2005 OpenWorks LLP. All rights reserved.
sewardjf8ed9d82004-11-12 17:40:23 +000014
sewardj7bd6ffe2005-08-03 16:07:36 +000015 This library is made available under a dual licensing scheme.
sewardjf8ed9d82004-11-12 17:40:23 +000016
sewardj7bd6ffe2005-08-03 16:07:36 +000017 If you link LibVEX against other code all of which is itself
18 licensed under the GNU General Public License, version 2 dated June
19 1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
20 v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL
21 is missing, you can obtain a copy of the GPL v2 from the Free
22 Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 02110-1301, USA.
24
25 For any other uses of LibVEX, you must first obtain a commercial
26 license from OpenWorks LLP. Please contact info@open-works.co.uk
27 for information about commercial licensing.
28
29 This software is provided by OpenWorks LLP "as is" and any express
30 or implied warranties, including, but not limited to, the implied
31 warranties of merchantability and fitness for a particular purpose
32 are disclaimed. In no event shall OpenWorks LLP be liable for any
33 direct, indirect, incidental, special, exemplary, or consequential
34 damages (including, but not limited to, procurement of substitute
35 goods or services; loss of use, data, or profits; or business
36 interruption) however caused and on any theory of liability,
37 whether in contract, strict liability, or tort (including
38 negligence or otherwise) arising in any way out of the use of this
39 software, even if advised of the possibility of such damage.
sewardjf8ed9d82004-11-12 17:40:23 +000040
41 Neither the names of the U.S. Department of Energy nor the
42 University of California nor the names of its contributors may be
43 used to endorse or promote products derived from this software
44 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000045*/
46
sewardj887a11a2004-07-05 17:26:47 +000047#include "libvex_basictypes.h"
48#include "libvex_ir.h"
49#include "libvex.h"
sewardjec6ad592004-06-20 12:26:53 +000050
sewardjc0ee2ed2004-07-27 10:29:41 +000051#include "main/vex_util.h"
52
sewardjec6ad592004-06-20 12:26:53 +000053
54/*---------------------------------------------------------------*/
55/*--- Printing the IR ---*/
56/*---------------------------------------------------------------*/
57
sewardj35421a32004-07-05 13:12:34 +000058void ppIRType ( IRType ty )
sewardjec6ad592004-06-20 12:26:53 +000059{
sewardj3e838932005-01-07 12:09:15 +000060 switch (ty) {
61 case Ity_INVALID: vex_printf("Ity_INVALID"); break;
sewardj9b967672005-02-08 11:13:09 +000062 case Ity_I1: vex_printf( "I1"); break;
63 case Ity_I8: vex_printf( "I8"); break;
64 case Ity_I16: vex_printf( "I16"); break;
65 case Ity_I32: vex_printf( "I32"); break;
66 case Ity_I64: vex_printf( "I64"); break;
67 case Ity_I128: vex_printf( "I128"); break;
68 case Ity_F32: vex_printf( "F32"); break;
69 case Ity_F64: vex_printf( "F64"); break;
sewardj3e838932005-01-07 12:09:15 +000070 case Ity_V128: vex_printf( "V128"); break;
71 default: vex_printf("ty = 0x%x\n", (Int)ty);
72 vpanic("ppIRType");
73 }
sewardjec6ad592004-06-20 12:26:53 +000074}
75
sewardj35421a32004-07-05 13:12:34 +000076void ppIRConst ( IRConst* con )
sewardjec6ad592004-06-20 12:26:53 +000077{
sewardja162c2c2005-12-18 03:07:11 +000078 union { ULong i64; Double f64; } u;
sewardj63327402006-01-25 03:26:27 +000079 vassert(sizeof(ULong) == sizeof(Double));
sewardj2d3f77c2004-09-22 23:49:09 +000080 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +000081 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break;
sewardj2d3f77c2004-09-22 23:49:09 +000082 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break;
83 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break;
84 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break;
85 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break;
sewardja162c2c2005-12-18 03:07:11 +000086 case Ico_F64: u.f64 = con->Ico.F64;
87 vex_printf( "F64{0x%llx}", u.i64);
sewardj695cff92004-10-13 14:50:14 +000088 break;
sewardj2d3f77c2004-09-22 23:49:09 +000089 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
sewardj1e6ad742004-12-02 16:16:11 +000090 case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break;
sewardj2d3f77c2004-09-22 23:49:09 +000091 default: vpanic("ppIRConst");
92 }
93}
94
sewardj8ea867b2004-10-30 19:03:02 +000095void ppIRCallee ( IRCallee* ce )
96{
97 vex_printf("%s", ce->name);
sewardj77352542004-10-30 20:39:01 +000098 if (ce->regparms > 0)
sewardj43c56462004-11-06 12:17:57 +000099 vex_printf("[rp=%d]", ce->regparms);
100 if (ce->mcx_mask > 0)
101 vex_printf("[mcx=0x%x]", ce->mcx_mask);
sewardj8ea867b2004-10-30 19:03:02 +0000102 vex_printf("{%p}", (void*)ce->addr);
103}
104
sewardj2d3f77c2004-09-22 23:49:09 +0000105void ppIRArray ( IRArray* arr )
106{
sewardj0bfea7f2004-10-04 07:15:48 +0000107 vex_printf("(%d:%dx", arr->base, arr->nElems);
sewardj2d3f77c2004-09-22 23:49:09 +0000108 ppIRType(arr->elemTy);
sewardj0bfea7f2004-10-04 07:15:48 +0000109 vex_printf(")");
sewardje3d0d2e2004-06-27 10:42:44 +0000110}
111
sewardj35421a32004-07-05 13:12:34 +0000112void ppIRTemp ( IRTemp tmp )
sewardje3d0d2e2004-06-27 10:42:44 +0000113{
sewardj92d168d2004-11-15 14:22:12 +0000114 if (tmp == IRTemp_INVALID)
115 vex_printf("IRTemp_INVALID");
sewardjfbcaf332004-07-08 01:46:01 +0000116 else
sewardj41f43bc2004-07-08 14:23:22 +0000117 vex_printf( "t%d", (Int)tmp);
sewardje3d0d2e2004-06-27 10:42:44 +0000118}
119
sewardj35421a32004-07-05 13:12:34 +0000120void ppIROp ( IROp op )
sewardje3d0d2e2004-06-27 10:42:44 +0000121{
sewardja98bf492005-02-07 01:39:17 +0000122 HChar* str;
123 IROp base;
sewardj41f43bc2004-07-08 14:23:22 +0000124 switch (op) {
125 case Iop_Add8 ... Iop_Add64:
126 str = "Add"; base = Iop_Add8; break;
127 case Iop_Sub8 ... Iop_Sub64:
128 str = "Sub"; base = Iop_Sub8; break;
129 case Iop_Mul8 ... Iop_Mul64:
130 str = "Mul"; base = Iop_Mul8; break;
131 case Iop_Or8 ... Iop_Or64:
132 str = "Or"; base = Iop_Or8; break;
133 case Iop_And8 ... Iop_And64:
134 str = "And"; base = Iop_And8; break;
135 case Iop_Xor8 ... Iop_Xor64:
136 str = "Xor"; base = Iop_Xor8; break;
137 case Iop_Shl8 ... Iop_Shl64:
138 str = "Shl"; base = Iop_Shl8; break;
139 case Iop_Shr8 ... Iop_Shr64:
140 str = "Shr"; base = Iop_Shr8; break;
141 case Iop_Sar8 ... Iop_Sar64:
142 str = "Sar"; base = Iop_Sar8; break;
sewardje90ad6a2004-07-10 19:02:10 +0000143 case Iop_CmpEQ8 ... Iop_CmpEQ64:
144 str = "CmpEQ"; base = Iop_CmpEQ8; break;
145 case Iop_CmpNE8 ... Iop_CmpNE64:
146 str = "CmpNE"; base = Iop_CmpNE8; break;
sewardj41f43bc2004-07-08 14:23:22 +0000147 case Iop_Not8 ... Iop_Not64:
148 str = "Not"; base = Iop_Not8; break;
149 /* other cases must explicitly "return;" */
sewardj9690d922004-07-14 01:39:17 +0000150 case Iop_8Uto16: vex_printf("8Uto16"); return;
151 case Iop_8Uto32: vex_printf("8Uto32"); return;
152 case Iop_16Uto32: vex_printf("16Uto32"); return;
153 case Iop_8Sto16: vex_printf("8Sto16"); return;
154 case Iop_8Sto32: vex_printf("8Sto32"); return;
155 case Iop_16Sto32: vex_printf("16Sto32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000156 case Iop_32Sto64: vex_printf("32Sto64"); return;
sewardje5427e82004-09-11 19:43:51 +0000157 case Iop_32Uto64: vex_printf("32Uto64"); return;
sewardja2384712004-07-29 14:36:40 +0000158 case Iop_32to8: vex_printf("32to8"); return;
sewardj291a7e82005-04-27 11:42:44 +0000159 case Iop_16Uto64: vex_printf("16Uto64"); return;
160 case Iop_16Sto64: vex_printf("16Sto64"); return;
161 case Iop_8Uto64: vex_printf("8Uto64"); return;
162 case Iop_8Sto64: vex_printf("8Sto64"); return;
163 case Iop_64to16: vex_printf("64to16"); return;
164 case Iop_64to8: vex_printf("64to8"); return;
sewardj6e797c52004-10-13 15:20:17 +0000165
166 case Iop_Not1: vex_printf("Not1"); return;
sewardj9690d922004-07-14 01:39:17 +0000167 case Iop_32to1: vex_printf("32to1"); return;
sewardj291a7e82005-04-27 11:42:44 +0000168 case Iop_64to1: vex_printf("64to1"); return;
sewardj9690d922004-07-14 01:39:17 +0000169 case Iop_1Uto8: vex_printf("1Uto8"); return;
sewardj84ff0652004-08-23 16:16:08 +0000170 case Iop_1Uto32: vex_printf("1Uto32"); return;
sewardj291a7e82005-04-27 11:42:44 +0000171 case Iop_1Uto64: vex_printf("1Uto64"); return;
sewardjfd332772004-11-09 16:01:40 +0000172 case Iop_1Sto8: vex_printf("1Sto8"); return;
sewardj8eda6302004-11-05 01:55:46 +0000173 case Iop_1Sto16: vex_printf("1Sto16"); return;
sewardj415d9352004-11-04 15:20:15 +0000174 case Iop_1Sto32: vex_printf("1Sto32"); return;
sewardjb5874aa2004-11-04 16:57:50 +0000175 case Iop_1Sto64: vex_printf("1Sto64"); return;
sewardj9690d922004-07-14 01:39:17 +0000176
177 case Iop_MullS8: vex_printf("MullS8"); return;
178 case Iop_MullS16: vex_printf("MullS16"); return;
179 case Iop_MullS32: vex_printf("MullS32"); return;
sewardj9b967672005-02-08 11:13:09 +0000180 case Iop_MullS64: vex_printf("MullS64"); return;
sewardj9690d922004-07-14 01:39:17 +0000181 case Iop_MullU8: vex_printf("MullU8"); return;
182 case Iop_MullU16: vex_printf("MullU16"); return;
183 case Iop_MullU32: vex_printf("MullU32"); return;
sewardj9b967672005-02-08 11:13:09 +0000184 case Iop_MullU64: vex_printf("MullU64"); return;
sewardj9690d922004-07-14 01:39:17 +0000185
sewardjf53b7352005-04-06 20:01:56 +0000186 case Iop_Clz64: vex_printf("Clz64"); return;
sewardjce646f22004-08-31 23:55:54 +0000187 case Iop_Clz32: vex_printf("Clz32"); return;
sewardjf53b7352005-04-06 20:01:56 +0000188 case Iop_Ctz64: vex_printf("Ctz64"); return;
sewardjce646f22004-08-31 23:55:54 +0000189 case Iop_Ctz32: vex_printf("Ctz32"); return;
190
sewardj84ff0652004-08-23 16:16:08 +0000191 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
192 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
193 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
194 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
195
sewardj98540072005-04-26 01:52:01 +0000196 case Iop_CmpLT64S: vex_printf("CmpLT64S"); return;
197 case Iop_CmpLE64S: vex_printf("CmpLE64S"); return;
198 case Iop_CmpLT64U: vex_printf("CmpLT64U"); return;
199 case Iop_CmpLE64U: vex_printf("CmpLE64U"); return;
200
sewardj0033ddc2005-04-26 23:34:34 +0000201 case Iop_CmpNEZ8: vex_printf("CmpNEZ8"); return;
202 case Iop_CmpNEZ16: vex_printf("CmpNEZ16"); return;
203 case Iop_CmpNEZ32: vex_printf("CmpNEZ32"); return;
204 case Iop_CmpNEZ64: vex_printf("CmpNEZ64"); return;
205
sewardjb51f0f42005-07-18 11:38:02 +0000206 case Iop_CmpORD32U: vex_printf("CmpORD32U"); return;
207 case Iop_CmpORD32S: vex_printf("CmpORD32S"); return;
208
cerion2831b002005-11-30 19:55:22 +0000209 case Iop_CmpORD64U: vex_printf("CmpORD64U"); return;
210 case Iop_CmpORD64S: vex_printf("CmpORD64S"); return;
211
sewardj0033ddc2005-04-26 23:34:34 +0000212 case Iop_Neg8: vex_printf("Neg8"); return;
213 case Iop_Neg16: vex_printf("Neg16"); return;
214 case Iop_Neg32: vex_printf("Neg32"); return;
215 case Iop_Neg64: vex_printf("Neg64"); return;
216
cerion5c8a0cb2005-02-03 13:59:46 +0000217 case Iop_DivU32: vex_printf("DivU32"); return;
218 case Iop_DivS32: vex_printf("DivS32"); return;
cerionf0de28c2005-12-13 20:21:11 +0000219 case Iop_DivU64: vex_printf("DivU64"); return;
220 case Iop_DivS64: vex_printf("DivS64"); return;
cerion5c8a0cb2005-02-03 13:59:46 +0000221
sewardj9690d922004-07-14 01:39:17 +0000222 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
223 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
224
sewardj343b9d02005-01-31 18:08:45 +0000225 case Iop_DivModU128to64: vex_printf("DivModU128to64"); return;
226 case Iop_DivModS128to64: vex_printf("DivModS128to64"); return;
227
sewardjb81f8b32004-07-30 10:17:50 +0000228 case Iop_16HIto8: vex_printf("16HIto8"); return;
229 case Iop_16to8: vex_printf("16to8"); return;
230 case Iop_8HLto16: vex_printf("8HLto16"); return;
231
sewardj8c7f1ab2004-07-29 20:31:09 +0000232 case Iop_32HIto16: vex_printf("32HIto16"); return;
233 case Iop_32to16: vex_printf("32to16"); return;
234 case Iop_16HLto32: vex_printf("16HLto32"); return;
235
sewardj9690d922004-07-14 01:39:17 +0000236 case Iop_64HIto32: vex_printf("64HIto32"); return;
sewardj8c7f1ab2004-07-29 20:31:09 +0000237 case Iop_64to32: vex_printf("64to32"); return;
sewardj9690d922004-07-14 01:39:17 +0000238 case Iop_32HLto64: vex_printf("32HLto64"); return;
239
sewardj9b967672005-02-08 11:13:09 +0000240 case Iop_128HIto64: vex_printf("128HIto64"); return;
241 case Iop_128to64: vex_printf("128to64"); return;
242 case Iop_64HLto128: vex_printf("64HLto128"); return;
243
sewardjcfded9a2004-09-09 11:44:16 +0000244 case Iop_AddF64: vex_printf("AddF64"); return;
245 case Iop_SubF64: vex_printf("SubF64"); return;
246 case Iop_MulF64: vex_printf("MulF64"); return;
247 case Iop_DivF64: vex_printf("DivF64"); return;
sewardjb183b852006-02-03 16:08:03 +0000248 case Iop_AddF64r32: vex_printf("AddF64r32"); return;
249 case Iop_SubF64r32: vex_printf("SubF64r32"); return;
250 case Iop_MulF64r32: vex_printf("MulF64r32"); return;
251 case Iop_DivF64r32: vex_printf("DivF64r32"); return;
sewardj46de4072004-09-11 19:23:24 +0000252
sewardj442d0be2004-10-15 22:57:13 +0000253 case Iop_ScaleF64: vex_printf("ScaleF64"); return;
254 case Iop_AtanF64: vex_printf("AtanF64"); return;
255 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return;
256 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return;
257 case Iop_PRemF64: vex_printf("PRemF64"); return;
258 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return;
259 case Iop_PRem1F64: vex_printf("PRem1F64"); return;
260 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
261 case Iop_NegF64: vex_printf("NegF64"); return;
262 case Iop_SqrtF64: vex_printf("SqrtF64"); return;
sewardj46de4072004-09-11 19:23:24 +0000263
sewardj883b00b2004-09-11 09:30:24 +0000264 case Iop_AbsF64: vex_printf("AbsF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000265 case Iop_SinF64: vex_printf("SinF64"); return;
266 case Iop_CosF64: vex_printf("CosF64"); return;
sewardj99016a72004-10-15 22:09:17 +0000267 case Iop_TanF64: vex_printf("TanF64"); return;
sewardj06c32a02004-09-12 12:07:34 +0000268 case Iop_2xm1F64: vex_printf("2xm1F64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000269
sewardj40c80262006-02-08 19:30:46 +0000270 case Iop_MAddF64: vex_printf("MAddF64"); return;
271 case Iop_MSubF64: vex_printf("MSubF64"); return;
272 case Iop_MAddF64r32: vex_printf("MAddF64r32"); return;
273 case Iop_MSubF64r32: vex_printf("MSubF64r32"); return;
274
275 case Iop_Est5FRSqrt: vex_printf("Est5FRSqrt"); return;
sewardjb183b852006-02-03 16:08:03 +0000276 case Iop_TruncF64asF32: vex_printf("TruncF64asF32"); return;
sewardj40c80262006-02-08 19:30:46 +0000277 case Iop_CalcFPRF: vex_printf("CalcFPRF");
sewardjbaf971a2006-01-27 15:09:35 +0000278
sewardj46de4072004-09-11 19:23:24 +0000279 case Iop_CmpF64: vex_printf("CmpF64"); return;
280
sewardj3bca9062004-12-04 14:36:09 +0000281 case Iop_F64toI16: vex_printf("F64toI16"); return;
282 case Iop_F64toI32: vex_printf("F64toI32"); return;
283 case Iop_F64toI64: vex_printf("F64toI64"); return;
284
285 case Iop_I16toF64: vex_printf("I16toF64"); return;
sewardj89cd0932004-09-08 18:23:25 +0000286 case Iop_I32toF64: vex_printf("I32toF64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000287 case Iop_I64toF64: vex_printf("I64toF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000288
sewardj89cd0932004-09-08 18:23:25 +0000289 case Iop_F32toF64: vex_printf("F32toF64"); return;
290 case Iop_F64toF32: vex_printf("F64toF32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000291
sewardjb183b852006-02-03 16:08:03 +0000292 case Iop_RoundF64toInt: vex_printf("RoundF64toInt"); return;
293 case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return;
sewardj3bca9062004-12-04 14:36:09 +0000294
sewardj17442fe2004-09-20 14:54:28 +0000295 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
296 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
sewardjfd226452004-12-07 19:02:18 +0000297 case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
sewardj17442fe2004-09-20 14:54:28 +0000298
cerionf294eb32005-11-16 17:21:10 +0000299 case Iop_I32UtoFx4: vex_printf("Iop_I32UtoFx4"); return;
300 case Iop_I32StoFx4: vex_printf("Iop_I32StoFx4"); return;
301
302 case Iop_QFtoI32Ux4_RZ: vex_printf("Iop_QFtoI32Ux4_RZ"); return;
303 case Iop_QFtoI32Sx4_RZ: vex_printf("Iop_QFtoI32Sx4_RZ"); return;
304
305 case Iop_RoundF32x4_RM: vex_printf("Iop_RoundF32x4_RM"); return;
306 case Iop_RoundF32x4_RP: vex_printf("Iop_RoundF32x4_RP"); return;
307 case Iop_RoundF32x4_RN: vex_printf("Iop_RoundF32x4_RN"); return;
308 case Iop_RoundF32x4_RZ: vex_printf("Iop_RoundF32x4_RZ"); return;
309
sewardj38a3f862005-01-13 15:06:51 +0000310 case Iop_Add8x8: vex_printf("Add8x8"); return;
311 case Iop_Add16x4: vex_printf("Add16x4"); return;
312 case Iop_Add32x2: vex_printf("Add32x2"); return;
313 case Iop_QAdd8Ux8: vex_printf("QAdd8Ux8"); return;
314 case Iop_QAdd16Ux4: vex_printf("QAdd16Ux4"); return;
315 case Iop_QAdd8Sx8: vex_printf("QAdd8Sx8"); return;
316 case Iop_QAdd16Sx4: vex_printf("QAdd16Sx4"); return;
317 case Iop_Sub8x8: vex_printf("Sub8x8"); return;
318 case Iop_Sub16x4: vex_printf("Sub16x4"); return;
319 case Iop_Sub32x2: vex_printf("Sub32x2"); return;
320 case Iop_QSub8Ux8: vex_printf("QSub8Ux8"); return;
321 case Iop_QSub16Ux4: vex_printf("QSub16Ux4"); return;
322 case Iop_QSub8Sx8: vex_printf("QSub8Sx8"); return;
323 case Iop_QSub16Sx4: vex_printf("QSub16Sx4"); return;
324 case Iop_Mul16x4: vex_printf("Mul16x4"); return;
325 case Iop_MulHi16Ux4: vex_printf("MulHi16Ux4"); return;
326 case Iop_MulHi16Sx4: vex_printf("MulHi16Sx4"); return;
327 case Iop_Avg8Ux8: vex_printf("Avg8Ux8"); return;
328 case Iop_Avg16Ux4: vex_printf("Avg16Ux4"); return;
329 case Iop_Max16Sx4: vex_printf("Max16Sx4"); return;
330 case Iop_Max8Ux8: vex_printf("Max8Ux8"); return;
331 case Iop_Min16Sx4: vex_printf("Min16Sx4"); return;
332 case Iop_Min8Ux8: vex_printf("Min8Ux8"); return;
333 case Iop_CmpEQ8x8: vex_printf("CmpEQ8x8"); return;
334 case Iop_CmpEQ16x4: vex_printf("CmpEQ16x4"); return;
335 case Iop_CmpEQ32x2: vex_printf("CmpEQ32x2"); return;
336 case Iop_CmpGT8Sx8: vex_printf("CmpGT8Sx8"); return;
337 case Iop_CmpGT16Sx4: vex_printf("CmpGT16Sx4"); return;
338 case Iop_CmpGT32Sx2: vex_printf("CmpGT32Sx2"); return;
339 case Iop_ShlN16x4: vex_printf("ShlN16x4"); return;
340 case Iop_ShlN32x2: vex_printf("ShlN32x2"); return;
341 case Iop_ShrN16x4: vex_printf("ShrN16x4"); return;
342 case Iop_ShrN32x2: vex_printf("ShrN32x2"); return;
343 case Iop_SarN16x4: vex_printf("SarN16x4"); return;
344 case Iop_SarN32x2: vex_printf("SarN32x2"); return;
345 case Iop_QNarrow16Ux4: vex_printf("QNarrow16Ux4"); return;
346 case Iop_QNarrow16Sx4: vex_printf("QNarrow16Sx4"); return;
347 case Iop_QNarrow32Sx2: vex_printf("QNarrow32Sx2"); return;
348 case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return;
349 case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return;
350 case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return;
351 case Iop_InterleaveLO8x8: vex_printf("InterleaveLO8x8"); return;
352 case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return;
353 case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return;
354
sewardj18069182005-01-13 19:16:04 +0000355 case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return;
356 case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return;
357 case Iop_CmpNEZ8x8: vex_printf("CmpNEZ8x8"); return;
358
sewardj1e6ad742004-12-02 16:16:11 +0000359 case Iop_Add32Fx4: vex_printf("Add32Fx4"); return;
360 case Iop_Add32F0x4: vex_printf("Add32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000361 case Iop_Add64Fx2: vex_printf("Add64Fx2"); return;
362 case Iop_Add64F0x2: vex_printf("Add64F0x2"); return;
sewardj1e6ad742004-12-02 16:16:11 +0000363
sewardj176a59c2004-12-03 20:08:31 +0000364 case Iop_Div32Fx4: vex_printf("Div32Fx4"); return;
365 case Iop_Div32F0x4: vex_printf("Div32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000366 case Iop_Div64Fx2: vex_printf("Div64Fx2"); return;
367 case Iop_Div64F0x2: vex_printf("Div64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000368
369 case Iop_Max32Fx4: vex_printf("Max32Fx4"); return;
370 case Iop_Max32F0x4: vex_printf("Max32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000371 case Iop_Max64Fx2: vex_printf("Max64Fx2"); return;
372 case Iop_Max64F0x2: vex_printf("Max64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000373
374 case Iop_Min32Fx4: vex_printf("Min32Fx4"); return;
375 case Iop_Min32F0x4: vex_printf("Min32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000376 case Iop_Min64Fx2: vex_printf("Min64Fx2"); return;
377 case Iop_Min64F0x2: vex_printf("Min64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000378
sewardj9636b442004-12-04 01:38:37 +0000379 case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return;
380 case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000381 case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return;
382 case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return;
sewardj9636b442004-12-04 01:38:37 +0000383
sewardj0bd7ce62004-12-05 02:47:40 +0000384 case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return;
385 case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000386 case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return;
387 case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return;
sewardj0bd7ce62004-12-05 02:47:40 +0000388
sewardjc1e7dfc2004-12-05 19:29:45 +0000389 case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return;
390 case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000391 case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return;
392 case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000393
sewardj636ad762004-12-07 11:16:04 +0000394 case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return;
395 case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return;
396 case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return;
397 case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000398
399 case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return;
400 case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000401 case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return;
402 case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000403
sewardj1e6ad742004-12-02 16:16:11 +0000404 case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return;
405 case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return;
406 case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return;
cerion206c3642005-11-14 00:35:59 +0000407 case Iop_CmpGT32Fx4: vex_printf("CmpGT32Fx4"); return;
408 case Iop_CmpGE32Fx4: vex_printf("CmpGE32Fx4"); return;
sewardj1e6ad742004-12-02 16:16:11 +0000409 case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return;
sewardj636ad762004-12-07 11:16:04 +0000410 case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return;
411 case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return;
412 case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return;
413 case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return;
sewardj1e6ad742004-12-02 16:16:11 +0000414
415 case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return;
416 case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return;
417 case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return;
418 case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000419 case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return;
420 case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return;
421 case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return;
422 case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return;
sewardjc9a43662004-11-30 18:51:59 +0000423
sewardjf0c1c582005-02-07 23:47:38 +0000424 case Iop_V128to64: vex_printf("V128to64"); return;
425 case Iop_V128HIto64: vex_printf("V128HIto64"); return;
426 case Iop_64HLtoV128: vex_printf("64HLtoV128"); return;
sewardja0037df2004-12-10 18:56:29 +0000427
sewardjf0c1c582005-02-07 23:47:38 +0000428 case Iop_64UtoV128: vex_printf("64UtoV128"); return;
429 case Iop_SetV128lo64: vex_printf("SetV128lo64"); return;
sewardjc9a43662004-11-30 18:51:59 +0000430
sewardjf0c1c582005-02-07 23:47:38 +0000431 case Iop_32UtoV128: vex_printf("32UtoV128"); return;
432 case Iop_V128to32: vex_printf("V128to32"); return;
433 case Iop_SetV128lo32: vex_printf("SetV128lo32"); return;
sewardj129b3d92004-12-05 15:42:05 +0000434
cerionf887b3e2005-09-13 16:34:28 +0000435 case Iop_Dup8x16: vex_printf("Dup8x16"); return;
436 case Iop_Dup16x8: vex_printf("Dup16x8"); return;
437 case Iop_Dup32x4: vex_printf("Dup32x4"); return;
438
sewardjf0c1c582005-02-07 23:47:38 +0000439 case Iop_NotV128: vex_printf("NotV128"); return;
440 case Iop_AndV128: vex_printf("AndV128"); return;
441 case Iop_OrV128: vex_printf("OrV128"); return;
442 case Iop_XorV128: vex_printf("XorV128"); return;
sewardj18069182005-01-13 19:16:04 +0000443
sewardj2e383862004-12-12 16:46:47 +0000444 case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return;
445 case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return;
sewardj70f676d2004-12-10 14:59:57 +0000446 case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
sewardj109ffdb2004-12-10 21:45:38 +0000447 case Iop_CmpNEZ64x2: vex_printf("CmpNEZ64x2"); return;
sewardj164f9272004-12-09 00:39:32 +0000448
449 case Iop_Add8x16: vex_printf("Add8x16"); return;
450 case Iop_Add16x8: vex_printf("Add16x8"); return;
451 case Iop_Add32x4: vex_printf("Add32x4"); return;
452 case Iop_Add64x2: vex_printf("Add64x2"); return;
453 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
454 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000455 case Iop_QAdd32Ux4: vex_printf("QAdd32Ux4"); return;
sewardj164f9272004-12-09 00:39:32 +0000456 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
457 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000458 case Iop_QAdd32Sx4: vex_printf("QAdd32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000459
460 case Iop_Sub8x16: vex_printf("Sub8x16"); return;
461 case Iop_Sub16x8: vex_printf("Sub16x8"); return;
462 case Iop_Sub32x4: vex_printf("Sub32x4"); return;
463 case Iop_Sub64x2: vex_printf("Sub64x2"); return;
464 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
465 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000466 case Iop_QSub32Ux4: vex_printf("QSub32Ux4"); return;
sewardj164f9272004-12-09 00:39:32 +0000467 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
468 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000469 case Iop_QSub32Sx4: vex_printf("QSub32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000470
471 case Iop_Mul16x8: vex_printf("Mul16x8"); return;
472 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000473 case Iop_MulHi32Ux4: vex_printf("MulHi32Ux4"); return;
sewardj164f9272004-12-09 00:39:32 +0000474 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000475 case Iop_MulHi32Sx4: vex_printf("MulHi32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000476
cerion1ac656a2005-11-04 19:44:48 +0000477 case Iop_MullEven8Ux16: vex_printf("MullEven8Ux16"); return;
478 case Iop_MullEven16Ux8: vex_printf("MullEven16Ux8"); return;
479 case Iop_MullEven8Sx16: vex_printf("MullEven8Sx16"); return;
480 case Iop_MullEven16Sx8: vex_printf("MullEven16Sx8"); return;
481
sewardj164f9272004-12-09 00:39:32 +0000482 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
483 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000484 case Iop_Avg32Ux4: vex_printf("Avg32Ux4"); return;
485 case Iop_Avg8Sx16: vex_printf("Avg8Sx16"); return;
486 case Iop_Avg16Sx8: vex_printf("Avg16Sx8"); return;
487 case Iop_Avg32Sx4: vex_printf("Avg32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000488
cerionf887b3e2005-09-13 16:34:28 +0000489 case Iop_Max8Sx16: vex_printf("Max8Sx16"); return;
sewardj164f9272004-12-09 00:39:32 +0000490 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000491 case Iop_Max32Sx4: vex_printf("Max32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000492 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
cerionf887b3e2005-09-13 16:34:28 +0000493 case Iop_Max16Ux8: vex_printf("Max16Ux8"); return;
494 case Iop_Max32Ux4: vex_printf("Max32Ux4"); return;
495
496 case Iop_Min8Sx16: vex_printf("Min8Sx16"); return;
sewardj164f9272004-12-09 00:39:32 +0000497 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
cerionf887b3e2005-09-13 16:34:28 +0000498 case Iop_Min32Sx4: vex_printf("Min32Sx4"); return;
sewardj164f9272004-12-09 00:39:32 +0000499 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
cerionf887b3e2005-09-13 16:34:28 +0000500 case Iop_Min16Ux8: vex_printf("Min16Ux8"); return;
501 case Iop_Min32Ux4: vex_printf("Min32Ux4"); return;
sewardj164f9272004-12-09 00:39:32 +0000502
503 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return;
504 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return;
505 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return;
506 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
507 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
508 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
cerionf887b3e2005-09-13 16:34:28 +0000509 case Iop_CmpGT8Ux16: vex_printf("CmpGT8Ux16"); return;
510 case Iop_CmpGT16Ux8: vex_printf("CmpGT16Ux8"); return;
511 case Iop_CmpGT32Ux4: vex_printf("CmpGT32Ux4"); return;
512
513 case Iop_ShlV128: vex_printf("ShlV128"); return;
514 case Iop_ShrV128: vex_printf("ShrV128"); return;
sewardj164f9272004-12-09 00:39:32 +0000515
cerion2a4b8452005-09-15 16:28:36 +0000516 case Iop_ShlN8x16: vex_printf("ShlN8x16"); return;
sewardj164f9272004-12-09 00:39:32 +0000517 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
518 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
519 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
cerion2a4b8452005-09-15 16:28:36 +0000520 case Iop_ShrN8x16: vex_printf("ShrN8x16"); return;
sewardj164f9272004-12-09 00:39:32 +0000521 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
522 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
523 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
cerion2a4b8452005-09-15 16:28:36 +0000524 case Iop_SarN8x16: vex_printf("SarN8x16"); return;
sewardj164f9272004-12-09 00:39:32 +0000525 case Iop_SarN16x8: vex_printf("SarN16x8"); return;
526 case Iop_SarN32x4: vex_printf("SarN32x4"); return;
527
cerionf887b3e2005-09-13 16:34:28 +0000528 case Iop_Shl8x16: vex_printf("Shl8x16"); return;
529 case Iop_Shl16x8: vex_printf("Shl16x8"); return;
530 case Iop_Shl32x4: vex_printf("Shl32x4"); return;
531 case Iop_Shr8x16: vex_printf("Shr8x16"); return;
532 case Iop_Shr16x8: vex_printf("Shr16x8"); return;
533 case Iop_Shr32x4: vex_printf("Shr32x4"); return;
534 case Iop_Sar8x16: vex_printf("Sar8x16"); return;
535 case Iop_Sar16x8: vex_printf("Sar16x8"); return;
536 case Iop_Sar32x4: vex_printf("Sar32x4"); return;
sewardj1bee5612005-11-10 18:10:58 +0000537 case Iop_Rol8x16: vex_printf("Rol8x16"); return;
538 case Iop_Rol16x8: vex_printf("Rol16x8"); return;
539 case Iop_Rol32x4: vex_printf("Rol32x4"); return;
cerionf887b3e2005-09-13 16:34:28 +0000540
sewardj1bee5612005-11-10 18:10:58 +0000541 case Iop_Narrow16x8: vex_printf("Narrow16x8"); return;
542 case Iop_Narrow32x4: vex_printf("Narrow32x4"); return;
sewardj164f9272004-12-09 00:39:32 +0000543 case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return;
cerion9e7677b2005-09-13 17:25:41 +0000544 case Iop_QNarrow32Ux4: vex_printf("QNarrow32Ux4"); return;
sewardj164f9272004-12-09 00:39:32 +0000545 case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return;
546 case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return;
547
548 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
549 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
550 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
551 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
552 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
553 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
554 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
555 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
556
sewardjdc1f9132005-10-22 12:49:49 +0000557 case Iop_Perm8x16: vex_printf("Perm8x16"); return;
cerionf887b3e2005-09-13 16:34:28 +0000558
sewardjc9a43662004-11-30 18:51:59 +0000559 default: vpanic("ppIROp(1)");
sewardj41f43bc2004-07-08 14:23:22 +0000560 }
561
562 switch (op - base) {
563 case 0: vex_printf(str); vex_printf("8"); break;
564 case 1: vex_printf(str); vex_printf("16"); break;
565 case 2: vex_printf(str); vex_printf("32"); break;
566 case 3: vex_printf(str); vex_printf("64"); break;
567 default: vpanic("ppIROp(2)");
568 }
sewardje3d0d2e2004-06-27 10:42:44 +0000569}
570
sewardj35421a32004-07-05 13:12:34 +0000571void ppIRExpr ( IRExpr* e )
sewardje3d0d2e2004-06-27 10:42:44 +0000572{
sewardje87b4842004-07-10 12:23:30 +0000573 Int i;
sewardje3d0d2e2004-06-27 10:42:44 +0000574 switch (e->tag) {
sewardj443cd9d2004-07-18 23:06:45 +0000575 case Iex_Binder:
576 vex_printf("BIND-%d", e->Iex.Binder.binder);
577 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000578 case Iex_Get:
sewardjc9a43662004-11-30 18:51:59 +0000579 vex_printf( "GET:" );
sewardjfbcaf332004-07-08 01:46:01 +0000580 ppIRType(e->Iex.Get.ty);
sewardjc9a43662004-11-30 18:51:59 +0000581 vex_printf("(%d)", e->Iex.Get.offset);
sewardjec6ad592004-06-20 12:26:53 +0000582 break;
sewardjbb53f8c2004-08-14 11:50:01 +0000583 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +0000584 vex_printf( "GETI" );
585 ppIRArray(e->Iex.GetI.descr);
586 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000587 ppIRExpr(e->Iex.GetI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000588 vex_printf(",%d]", e->Iex.GetI.bias);
sewardjbb53f8c2004-08-14 11:50:01 +0000589 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000590 case Iex_Tmp:
sewardj35421a32004-07-05 13:12:34 +0000591 ppIRTemp(e->Iex.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +0000592 break;
sewardj40c80262006-02-08 19:30:46 +0000593 case Iex_Qop:
594 ppIROp(e->Iex.Qop.op);
595 vex_printf( "(" );
596 ppIRExpr(e->Iex.Qop.arg1);
597 vex_printf( "," );
598 ppIRExpr(e->Iex.Qop.arg2);
599 vex_printf( "," );
600 ppIRExpr(e->Iex.Qop.arg3);
601 vex_printf( "," );
602 ppIRExpr(e->Iex.Qop.arg4);
603 vex_printf( ")" );
604 break;
sewardjb183b852006-02-03 16:08:03 +0000605 case Iex_Triop:
606 ppIROp(e->Iex.Triop.op);
607 vex_printf( "(" );
608 ppIRExpr(e->Iex.Triop.arg1);
609 vex_printf( "," );
610 ppIRExpr(e->Iex.Triop.arg2);
611 vex_printf( "," );
612 ppIRExpr(e->Iex.Triop.arg3);
613 vex_printf( ")" );
614 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000615 case Iex_Binop:
sewardj35421a32004-07-05 13:12:34 +0000616 ppIROp(e->Iex.Binop.op);
617 vex_printf( "(" );
618 ppIRExpr(e->Iex.Binop.arg1);
619 vex_printf( "," );
620 ppIRExpr(e->Iex.Binop.arg2);
621 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000622 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000623 case Iex_Unop:
sewardj35421a32004-07-05 13:12:34 +0000624 ppIROp(e->Iex.Unop.op);
625 vex_printf( "(" );
626 ppIRExpr(e->Iex.Unop.arg);
627 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000628 break;
sewardjaf1ceca2005-06-30 23:31:27 +0000629 case Iex_Load:
630 vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" );
631 ppIRType(e->Iex.Load.ty);
sewardje05c42c2004-07-08 20:25:10 +0000632 vex_printf( "(" );
sewardjaf1ceca2005-06-30 23:31:27 +0000633 ppIRExpr(e->Iex.Load.addr);
sewardj35421a32004-07-05 13:12:34 +0000634 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000635 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000636 case Iex_Const:
sewardj35421a32004-07-05 13:12:34 +0000637 ppIRConst(e->Iex.Const.con);
sewardjec6ad592004-06-20 12:26:53 +0000638 break;
sewardje87b4842004-07-10 12:23:30 +0000639 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000640 ppIRCallee(e->Iex.CCall.cee);
641 vex_printf("(");
sewardje87b4842004-07-10 12:23:30 +0000642 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
643 ppIRExpr(e->Iex.CCall.args[i]);
644 if (e->Iex.CCall.args[i+1] != NULL)
645 vex_printf(",");
646 }
647 vex_printf("):");
648 ppIRType(e->Iex.CCall.retty);
649 break;
sewardj4042c7e2004-07-18 01:28:30 +0000650 case Iex_Mux0X:
651 vex_printf("Mux0X(");
652 ppIRExpr(e->Iex.Mux0X.cond);
sewardjeeb9ef82004-07-15 12:39:03 +0000653 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000654 ppIRExpr(e->Iex.Mux0X.expr0);
sewardjeeb9ef82004-07-15 12:39:03 +0000655 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000656 ppIRExpr(e->Iex.Mux0X.exprX);
sewardjeeb9ef82004-07-15 12:39:03 +0000657 vex_printf(")");
658 break;
sewardjec6ad592004-06-20 12:26:53 +0000659 default:
sewardj909c06d2005-02-19 22:47:41 +0000660 vpanic("ppIRExpr");
sewardjec6ad592004-06-20 12:26:53 +0000661 }
662}
663
sewardj17442fe2004-09-20 14:54:28 +0000664void ppIREffect ( IREffect fx )
665{
666 switch (fx) {
667 case Ifx_None: vex_printf("noFX"); return;
668 case Ifx_Read: vex_printf("RdFX"); return;
669 case Ifx_Write: vex_printf("WrFX"); return;
670 case Ifx_Modify: vex_printf("MoFX"); return;
671 default: vpanic("ppIREffect");
672 }
673}
674
675void ppIRDirty ( IRDirty* d )
676{
677 Int i;
sewardj92d168d2004-11-15 14:22:12 +0000678 if (d->tmp != IRTemp_INVALID) {
sewardj4b861de2004-11-03 15:24:42 +0000679 ppIRTemp(d->tmp);
680 vex_printf(" = ");
681 }
sewardjb8385d82004-11-02 01:34:15 +0000682 vex_printf("DIRTY ");
683 ppIRExpr(d->guard);
sewardjc5fc7aa2004-10-27 23:00:55 +0000684 if (d->needsBBP)
685 vex_printf(" NeedsBBP");
sewardj17442fe2004-09-20 14:54:28 +0000686 if (d->mFx != Ifx_None) {
sewardj49651f42004-10-28 22:11:04 +0000687 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000688 ppIREffect(d->mFx);
689 vex_printf("-mem(");
690 ppIRExpr(d->mAddr);
sewardj49651f42004-10-28 22:11:04 +0000691 vex_printf(",%d)", d->mSize);
sewardj17442fe2004-09-20 14:54:28 +0000692 }
693 for (i = 0; i < d->nFxState; i++) {
sewardj49651f42004-10-28 22:11:04 +0000694 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000695 ppIREffect(d->fxState[i].fx);
sewardj49651f42004-10-28 22:11:04 +0000696 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
sewardj17442fe2004-09-20 14:54:28 +0000697 }
sewardjc5fc7aa2004-10-27 23:00:55 +0000698 vex_printf(" ::: ");
sewardj8ea867b2004-10-30 19:03:02 +0000699 ppIRCallee(d->cee);
700 vex_printf("(");
sewardj17442fe2004-09-20 14:54:28 +0000701 for (i = 0; d->args[i] != NULL; i++) {
702 ppIRExpr(d->args[i]);
703 if (d->args[i+1] != NULL) {
704 vex_printf(",");
705 }
706 }
707 vex_printf(")");
708}
709
sewardj893aada2004-11-29 19:57:54 +0000710void ppIRJumpKind ( IRJumpKind kind )
711{
712 switch (kind) {
sewardj4fa325a2005-11-03 13:27:24 +0000713 case Ijk_Boring: vex_printf("Boring"); break;
714 case Ijk_Call: vex_printf("Call"); break;
715 case Ijk_Ret: vex_printf("Return"); break;
716 case Ijk_ClientReq: vex_printf("ClientReq"); break;
717 case Ijk_Yield: vex_printf("Yield"); break;
718 case Ijk_EmWarn: vex_printf("EmWarn"); break;
sewardj9dd9cf12006-01-20 14:13:55 +0000719 case Ijk_EmFail: vex_printf("EmFail"); break;
sewardj4fa325a2005-11-03 13:27:24 +0000720 case Ijk_NoDecode: vex_printf("NoDecode"); break;
721 case Ijk_MapFail: vex_printf("MapFail"); break;
722 case Ijk_TInval: vex_printf("Invalidate"); break;
sewardjce02aa72006-01-12 12:27:58 +0000723 case Ijk_NoRedir: vex_printf("NoRedir"); break;
sewardj334870d2006-02-07 16:42:39 +0000724 case Ijk_Trap: vex_printf("Trap"); break;
sewardj4fa325a2005-11-03 13:27:24 +0000725 case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
726 case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
727 case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
728 case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break;
729 default: vpanic("ppIRJumpKind");
sewardj893aada2004-11-29 19:57:54 +0000730 }
731}
732
sewardj35421a32004-07-05 13:12:34 +0000733void ppIRStmt ( IRStmt* s )
sewardjec6ad592004-06-20 12:26:53 +0000734{
sewardjd2445f62005-03-21 00:15:53 +0000735 if (!s) {
736 vex_printf("!!! IRStmt* which is NULL !!!");
737 return;
738 }
sewardj17442fe2004-09-20 14:54:28 +0000739 switch (s->tag) {
sewardjd2445f62005-03-21 00:15:53 +0000740 case Ist_NoOp:
741 vex_printf("IR-NoOp");
742 break;
sewardjf1689312005-03-16 18:19:10 +0000743 case Ist_IMark:
sewardj0c12a272005-03-17 09:57:03 +0000744 vex_printf( "------ IMark(0x%llx, %d) ------",
745 s->Ist.IMark.addr, s->Ist.IMark.len);
sewardjf1689312005-03-16 18:19:10 +0000746 break;
sewardj5a9ffab2005-05-12 17:55:01 +0000747 case Ist_AbiHint:
748 vex_printf("====== AbiHint(");
749 ppIRExpr(s->Ist.AbiHint.base);
750 vex_printf(", %d) ======", s->Ist.AbiHint.len);
751 break;
sewardj17442fe2004-09-20 14:54:28 +0000752 case Ist_Put:
753 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
sewardj6d076362004-09-23 11:06:17 +0000754 ppIRExpr(s->Ist.Put.data);
sewardj17442fe2004-09-20 14:54:28 +0000755 break;
756 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +0000757 vex_printf( "PUTI" );
758 ppIRArray(s->Ist.PutI.descr);
759 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000760 ppIRExpr(s->Ist.PutI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000761 vex_printf(",%d] = ", s->Ist.PutI.bias);
762 ppIRExpr(s->Ist.PutI.data);
sewardj17442fe2004-09-20 14:54:28 +0000763 break;
764 case Ist_Tmp:
765 ppIRTemp(s->Ist.Tmp.tmp);
766 vex_printf( " = " );
sewardj6d076362004-09-23 11:06:17 +0000767 ppIRExpr(s->Ist.Tmp.data);
sewardj17442fe2004-09-20 14:54:28 +0000768 break;
sewardjaf1ceca2005-06-30 23:31:27 +0000769 case Ist_Store:
770 vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" );
771 ppIRExpr(s->Ist.Store.addr);
sewardj17442fe2004-09-20 14:54:28 +0000772 vex_printf( ") = ");
sewardjaf1ceca2005-06-30 23:31:27 +0000773 ppIRExpr(s->Ist.Store.data);
sewardj17442fe2004-09-20 14:54:28 +0000774 break;
775 case Ist_Dirty:
776 ppIRDirty(s->Ist.Dirty.details);
777 break;
sewardj3e838932005-01-07 12:09:15 +0000778 case Ist_MFence:
sewardjd2445f62005-03-21 00:15:53 +0000779 vex_printf("IR-MFence");
sewardj3e838932005-01-07 12:09:15 +0000780 break;
sewardj17442fe2004-09-20 14:54:28 +0000781 case Ist_Exit:
782 vex_printf( "if (" );
sewardj0276d4b2004-11-15 15:30:21 +0000783 ppIRExpr(s->Ist.Exit.guard);
sewardj893aada2004-11-29 19:57:54 +0000784 vex_printf( ") goto {");
785 ppIRJumpKind(s->Ist.Exit.jk);
786 vex_printf("} ");
sewardj17442fe2004-09-20 14:54:28 +0000787 ppIRConst(s->Ist.Exit.dst);
788 break;
789 default:
790 vpanic("ppIRStmt");
791 }
sewardjec6ad592004-06-20 12:26:53 +0000792}
793
sewardj35421a32004-07-05 13:12:34 +0000794void ppIRTypeEnv ( IRTypeEnv* env ) {
sewardjc97096c2004-06-30 09:28:04 +0000795 UInt i;
sewardje539a402004-07-14 18:24:17 +0000796 for (i = 0; i < env->types_used; i++) {
sewardjc97096c2004-06-30 09:28:04 +0000797 if (i % 8 == 0)
sewardj35421a32004-07-05 13:12:34 +0000798 vex_printf( " ");
sewardje539a402004-07-14 18:24:17 +0000799 ppIRTemp(i);
sewardj35421a32004-07-05 13:12:34 +0000800 vex_printf( ":");
sewardje539a402004-07-14 18:24:17 +0000801 ppIRType(env->types[i]);
sewardjc97096c2004-06-30 09:28:04 +0000802 if (i % 8 == 7)
sewardj35421a32004-07-05 13:12:34 +0000803 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000804 else
sewardj35421a32004-07-05 13:12:34 +0000805 vex_printf( " ");
sewardjc97096c2004-06-30 09:28:04 +0000806 }
sewardje539a402004-07-14 18:24:17 +0000807 if (env->types_used > 0 && env->types_used % 8 != 7)
sewardj35421a32004-07-05 13:12:34 +0000808 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000809}
810
sewardj35421a32004-07-05 13:12:34 +0000811void ppIRBB ( IRBB* bb )
sewardjec6ad592004-06-20 12:26:53 +0000812{
sewardjd7cb8532004-08-17 23:59:23 +0000813 Int i;
sewardj35439212004-07-14 22:36:10 +0000814 vex_printf("IRBB {\n");
sewardj35421a32004-07-05 13:12:34 +0000815 ppIRTypeEnv(bb->tyenv);
sewardj35439212004-07-14 22:36:10 +0000816 vex_printf("\n");
sewardjd7cb8532004-08-17 23:59:23 +0000817 for (i = 0; i < bb->stmts_used; i++) {
sewardjd2445f62005-03-21 00:15:53 +0000818 vex_printf( " ");
819 ppIRStmt(bb->stmts[i]);
sewardj35421a32004-07-05 13:12:34 +0000820 vex_printf( "\n");
sewardjec6ad592004-06-20 12:26:53 +0000821 }
sewardje539a402004-07-14 18:24:17 +0000822 vex_printf( " goto {");
823 ppIRJumpKind(bb->jumpkind);
824 vex_printf( "} ");
825 ppIRExpr( bb->next );
sewardj35439212004-07-14 22:36:10 +0000826 vex_printf( "\n}\n");
sewardjec6ad592004-06-20 12:26:53 +0000827}
828
829
830/*---------------------------------------------------------------*/
831/*--- Constructors ---*/
832/*---------------------------------------------------------------*/
833
sewardjc97096c2004-06-30 09:28:04 +0000834
835/* Constructors -- IRConst */
836
sewardjba999312004-11-15 15:21:17 +0000837IRConst* IRConst_U1 ( Bool bit )
sewardjb8e75862004-08-19 17:58:45 +0000838{
839 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjba999312004-11-15 15:21:17 +0000840 c->tag = Ico_U1;
841 c->Ico.U1 = bit;
sewardj4b861de2004-11-03 15:24:42 +0000842 /* call me paranoid; I don't care :-) */
843 vassert(bit == False || bit == True);
sewardjb8e75862004-08-19 17:58:45 +0000844 return c;
845}
sewardjc97096c2004-06-30 09:28:04 +0000846IRConst* IRConst_U8 ( UChar u8 )
847{
sewardj35421a32004-07-05 13:12:34 +0000848 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000849 c->tag = Ico_U8;
850 c->Ico.U8 = u8;
851 return c;
852}
853IRConst* IRConst_U16 ( UShort u16 )
854{
sewardj35421a32004-07-05 13:12:34 +0000855 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000856 c->tag = Ico_U16;
857 c->Ico.U16 = u16;
858 return c;
859}
860IRConst* IRConst_U32 ( UInt u32 )
861{
sewardj35421a32004-07-05 13:12:34 +0000862 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000863 c->tag = Ico_U32;
864 c->Ico.U32 = u32;
865 return c;
866}
867IRConst* IRConst_U64 ( ULong u64 )
868{
sewardj35421a32004-07-05 13:12:34 +0000869 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000870 c->tag = Ico_U64;
871 c->Ico.U64 = u64;
872 return c;
873}
sewardja58ea662004-08-15 03:12:41 +0000874IRConst* IRConst_F64 ( Double f64 )
875{
876 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
877 c->tag = Ico_F64;
878 c->Ico.F64 = f64;
879 return c;
880}
sewardj17442fe2004-09-20 14:54:28 +0000881IRConst* IRConst_F64i ( ULong f64i )
sewardj207557a2004-08-27 12:00:18 +0000882{
sewardj17442fe2004-09-20 14:54:28 +0000883 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
884 c->tag = Ico_F64i;
885 c->Ico.F64i = f64i;
sewardj207557a2004-08-27 12:00:18 +0000886 return c;
887}
sewardj1e6ad742004-12-02 16:16:11 +0000888IRConst* IRConst_V128 ( UShort con )
889{
890 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
891 c->tag = Ico_V128;
892 c->Ico.V128 = con;
893 return c;
894}
sewardjc97096c2004-06-30 09:28:04 +0000895
sewardj8ea867b2004-10-30 19:03:02 +0000896/* Constructors -- IRCallee */
897
sewardj2d49b432005-02-01 00:37:06 +0000898IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr )
sewardj8ea867b2004-10-30 19:03:02 +0000899{
900 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
sewardj77352542004-10-30 20:39:01 +0000901 ce->regparms = regparms;
902 ce->name = name;
903 ce->addr = addr;
sewardj43c56462004-11-06 12:17:57 +0000904 ce->mcx_mask = 0;
sewardj77352542004-10-30 20:39:01 +0000905 vassert(regparms >= 0 && regparms <= 3);
sewardj8ea867b2004-10-30 19:03:02 +0000906 vassert(name != NULL);
907 vassert(addr != 0);
908 return ce;
909}
910
911
912/* Constructors -- IRArray */
sewardje3d0d2e2004-06-27 10:42:44 +0000913
sewardj2d3f77c2004-09-22 23:49:09 +0000914IRArray* mkIRArray ( Int base, IRType elemTy, Int nElems )
915{
916 IRArray* arr = LibVEX_Alloc(sizeof(IRArray));
917 arr->base = base;
918 arr->elemTy = elemTy;
919 arr->nElems = nElems;
920 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
sewardjba999312004-11-15 15:21:17 +0000921 vassert(!(arr->elemTy == Ity_I1));
sewardj2d3f77c2004-09-22 23:49:09 +0000922 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
923 return arr;
924}
925
926
927/* Constructors -- IRExpr */
928
sewardj443cd9d2004-07-18 23:06:45 +0000929IRExpr* IRExpr_Binder ( Int binder ) {
930 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
931 e->tag = Iex_Binder;
932 e->Iex.Binder.binder = binder;
933 return e;
934}
sewardjfbcaf332004-07-08 01:46:01 +0000935IRExpr* IRExpr_Get ( Int off, IRType ty ) {
sewardj35421a32004-07-05 13:12:34 +0000936 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000937 e->tag = Iex_Get;
938 e->Iex.Get.offset = off;
sewardjfbcaf332004-07-08 01:46:01 +0000939 e->Iex.Get.ty = ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000940 return e;
941}
sewardjeeac8412004-11-02 00:26:55 +0000942IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ) {
sewardj2d3f77c2004-09-22 23:49:09 +0000943 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
944 e->tag = Iex_GetI;
945 e->Iex.GetI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000946 e->Iex.GetI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000947 e->Iex.GetI.bias = bias;
sewardjd1725d12004-08-12 20:46:53 +0000948 return e;
949}
sewardjc97096c2004-06-30 09:28:04 +0000950IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
sewardj35421a32004-07-05 13:12:34 +0000951 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000952 e->tag = Iex_Tmp;
953 e->Iex.Tmp.tmp = tmp;
954 return e;
955}
sewardj40c80262006-02-08 19:30:46 +0000956IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
957 IRExpr* arg3, IRExpr* arg4 ) {
958 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
959 e->tag = Iex_Qop;
960 e->Iex.Qop.op = op;
961 e->Iex.Qop.arg1 = arg1;
962 e->Iex.Qop.arg2 = arg2;
963 e->Iex.Qop.arg3 = arg3;
964 e->Iex.Qop.arg4 = arg4;
965 return e;
966}
sewardjb183b852006-02-03 16:08:03 +0000967IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
968 IRExpr* arg2, IRExpr* arg3 ) {
969 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
970 e->tag = Iex_Triop;
971 e->Iex.Triop.op = op;
972 e->Iex.Triop.arg1 = arg1;
973 e->Iex.Triop.arg2 = arg2;
974 e->Iex.Triop.arg3 = arg3;
975 return e;
976}
sewardjc97096c2004-06-30 09:28:04 +0000977IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
sewardj35421a32004-07-05 13:12:34 +0000978 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000979 e->tag = Iex_Binop;
980 e->Iex.Binop.op = op;
981 e->Iex.Binop.arg1 = arg1;
982 e->Iex.Binop.arg2 = arg2;
983 return e;
984}
sewardjc97096c2004-06-30 09:28:04 +0000985IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
sewardj35421a32004-07-05 13:12:34 +0000986 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000987 e->tag = Iex_Unop;
988 e->Iex.Unop.op = op;
989 e->Iex.Unop.arg = arg;
990 return e;
991}
sewardjaf1ceca2005-06-30 23:31:27 +0000992IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) {
sewardj35421a32004-07-05 13:12:34 +0000993 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardjaf1ceca2005-06-30 23:31:27 +0000994 e->tag = Iex_Load;
995 e->Iex.Load.end = end;
996 e->Iex.Load.ty = ty;
997 e->Iex.Load.addr = addr;
998 vassert(end == Iend_LE || end == Iend_BE);
sewardje3d0d2e2004-06-27 10:42:44 +0000999 return e;
1000}
sewardjc97096c2004-06-30 09:28:04 +00001001IRExpr* IRExpr_Const ( IRConst* con ) {
sewardj35421a32004-07-05 13:12:34 +00001002 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +00001003 e->tag = Iex_Const;
1004 e->Iex.Const.con = con;
1005 return e;
sewardjec6ad592004-06-20 12:26:53 +00001006}
sewardj8ea867b2004-10-30 19:03:02 +00001007IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
sewardje87b4842004-07-10 12:23:30 +00001008 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
1009 e->tag = Iex_CCall;
sewardj8ea867b2004-10-30 19:03:02 +00001010 e->Iex.CCall.cee = cee;
sewardje87b4842004-07-10 12:23:30 +00001011 e->Iex.CCall.retty = retty;
1012 e->Iex.CCall.args = args;
1013 return e;
1014}
sewardj4042c7e2004-07-18 01:28:30 +00001015IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
sewardjeeb9ef82004-07-15 12:39:03 +00001016 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardj4042c7e2004-07-18 01:28:30 +00001017 e->tag = Iex_Mux0X;
1018 e->Iex.Mux0X.cond = cond;
1019 e->Iex.Mux0X.expr0 = expr0;
1020 e->Iex.Mux0X.exprX = exprX;
sewardjeeb9ef82004-07-15 12:39:03 +00001021 return e;
1022}
sewardjec6ad592004-06-20 12:26:53 +00001023
sewardjec6ad592004-06-20 12:26:53 +00001024
sewardjc5fc7aa2004-10-27 23:00:55 +00001025/* Constructors for NULL-terminated IRExpr expression vectors,
1026 suitable for use as arg lists in clean/dirty helper calls. */
1027
1028IRExpr** mkIRExprVec_0 ( void ) {
1029 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
1030 vec[0] = NULL;
1031 return vec;
1032}
1033IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
1034 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
1035 vec[0] = arg1;
1036 vec[1] = NULL;
1037 return vec;
1038}
1039IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
1040 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
1041 vec[0] = arg1;
1042 vec[1] = arg2;
1043 vec[2] = NULL;
1044 return vec;
1045}
sewardjf9655262004-10-31 20:02:16 +00001046IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
1047 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
1048 vec[0] = arg1;
1049 vec[1] = arg2;
1050 vec[2] = arg3;
1051 vec[3] = NULL;
1052 return vec;
1053}
1054IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2,
1055 IRExpr* arg3, IRExpr* arg4 ) {
1056 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
1057 vec[0] = arg1;
1058 vec[1] = arg2;
1059 vec[2] = arg3;
1060 vec[3] = arg4;
1061 vec[4] = NULL;
1062 return vec;
1063}
sewardjf32c67d2004-11-08 13:10:44 +00001064IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2,
1065 IRExpr* arg3, IRExpr* arg4, IRExpr* arg5 ) {
1066 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
1067 vec[0] = arg1;
1068 vec[1] = arg2;
1069 vec[2] = arg3;
1070 vec[3] = arg4;
1071 vec[4] = arg5;
1072 vec[5] = NULL;
1073 return vec;
1074}
sewardjc5fc7aa2004-10-27 23:00:55 +00001075
1076
sewardj17442fe2004-09-20 14:54:28 +00001077/* Constructors -- IRDirty */
1078
sewardjc5fc7aa2004-10-27 23:00:55 +00001079IRDirty* emptyIRDirty ( void ) {
sewardj17442fe2004-09-20 14:54:28 +00001080 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
sewardj8ea867b2004-10-30 19:03:02 +00001081 d->cee = NULL;
sewardjb8385d82004-11-02 01:34:15 +00001082 d->guard = NULL;
sewardj17442fe2004-09-20 14:54:28 +00001083 d->args = NULL;
sewardj92d168d2004-11-15 14:22:12 +00001084 d->tmp = IRTemp_INVALID;
sewardj17442fe2004-09-20 14:54:28 +00001085 d->mFx = Ifx_None;
1086 d->mAddr = NULL;
1087 d->mSize = 0;
sewardjc5fc7aa2004-10-27 23:00:55 +00001088 d->needsBBP = False;
sewardj17442fe2004-09-20 14:54:28 +00001089 d->nFxState = 0;
1090 return d;
1091}
1092
1093
sewardjec6ad592004-06-20 12:26:53 +00001094/* Constructors -- IRStmt */
sewardje3d0d2e2004-06-27 10:42:44 +00001095
sewardjd2445f62005-03-21 00:15:53 +00001096IRStmt* IRStmt_NoOp ( void )
1097{
1098 /* Just use a single static closure. */
1099 static IRStmt static_closure;
1100 static_closure.tag = Ist_NoOp;
1101 return &static_closure;
1102}
sewardjf1689312005-03-16 18:19:10 +00001103IRStmt* IRStmt_IMark ( Addr64 addr, Int len ) {
1104 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1105 s->tag = Ist_IMark;
1106 s->Ist.IMark.addr = addr;
1107 s->Ist.IMark.len = len;
1108 return s;
1109}
sewardj5a9ffab2005-05-12 17:55:01 +00001110IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len ) {
1111 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1112 s->tag = Ist_AbiHint;
1113 s->Ist.AbiHint.base = base;
1114 s->Ist.AbiHint.len = len;
1115 return s;
1116}
sewardj6d076362004-09-23 11:06:17 +00001117IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +00001118 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +00001119 s->tag = Ist_Put;
1120 s->Ist.Put.offset = off;
sewardj6d076362004-09-23 11:06:17 +00001121 s->Ist.Put.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +00001122 return s;
sewardjec6ad592004-06-20 12:26:53 +00001123}
sewardjeeac8412004-11-02 00:26:55 +00001124IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix,
sewardj2d3f77c2004-09-22 23:49:09 +00001125 Int bias, IRExpr* data ) {
1126 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1127 s->tag = Ist_PutI;
1128 s->Ist.PutI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +00001129 s->Ist.PutI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +00001130 s->Ist.PutI.bias = bias;
1131 s->Ist.PutI.data = data;
sewardjd1725d12004-08-12 20:46:53 +00001132 return s;
1133}
sewardj6d076362004-09-23 11:06:17 +00001134IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +00001135 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +00001136 s->tag = Ist_Tmp;
1137 s->Ist.Tmp.tmp = tmp;
sewardj6d076362004-09-23 11:06:17 +00001138 s->Ist.Tmp.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +00001139 return s;
sewardjec6ad592004-06-20 12:26:53 +00001140}
sewardjaf1ceca2005-06-30 23:31:27 +00001141IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) {
1142 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1143 s->tag = Ist_Store;
1144 s->Ist.Store.end = end;
1145 s->Ist.Store.addr = addr;
1146 s->Ist.Store.data = data;
1147 vassert(end == Iend_LE || end == Iend_BE);
sewardje3d0d2e2004-06-27 10:42:44 +00001148 return s;
sewardjec6ad592004-06-20 12:26:53 +00001149}
sewardj17442fe2004-09-20 14:54:28 +00001150IRStmt* IRStmt_Dirty ( IRDirty* d )
1151{
1152 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1153 s->tag = Ist_Dirty;
1154 s->Ist.Dirty.details = d;
1155 return s;
1156}
sewardj3e838932005-01-07 12:09:15 +00001157IRStmt* IRStmt_MFence ( void )
1158{
sewardjd2445f62005-03-21 00:15:53 +00001159 /* Just use a single static closure. */
1160 static IRStmt static_closure;
1161 static_closure.tag = Ist_MFence;
1162 return &static_closure;
sewardj3e838932005-01-07 12:09:15 +00001163}
sewardj893aada2004-11-29 19:57:54 +00001164IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
sewardj0276d4b2004-11-15 15:30:21 +00001165 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
1166 s->tag = Ist_Exit;
1167 s->Ist.Exit.guard = guard;
sewardj893aada2004-11-29 19:57:54 +00001168 s->Ist.Exit.jk = jk;
sewardj0276d4b2004-11-15 15:30:21 +00001169 s->Ist.Exit.dst = dst;
sewardj64e1d652004-07-12 14:00:46 +00001170 return s;
1171}
sewardje3d0d2e2004-06-27 10:42:44 +00001172
sewardj695cff92004-10-13 14:50:14 +00001173
1174/* Constructors -- IRTypeEnv */
1175
1176IRTypeEnv* emptyIRTypeEnv ( void )
1177{
1178 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
1179 env->types = LibVEX_Alloc(8 * sizeof(IRType));
1180 env->types_size = 8;
1181 env->types_used = 0;
1182 return env;
1183}
1184
1185
1186/* Constructors -- IRBB */
sewardje3d0d2e2004-06-27 10:42:44 +00001187
sewardjd7cb8532004-08-17 23:59:23 +00001188IRBB* emptyIRBB ( void )
1189{
1190 IRBB* bb = LibVEX_Alloc(sizeof(IRBB));
1191 bb->tyenv = emptyIRTypeEnv();
1192 bb->stmts_used = 0;
1193 bb->stmts_size = 8;
1194 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
1195 bb->next = NULL;
1196 bb->jumpkind = Ijk_Boring;
sewardje3d0d2e2004-06-27 10:42:44 +00001197 return bb;
sewardjec6ad592004-06-20 12:26:53 +00001198}
1199
sewardj695cff92004-10-13 14:50:14 +00001200
1201/*---------------------------------------------------------------*/
1202/*--- (Deep) copy constructors. These make complete copies ---*/
1203/*--- the original, which can be modified without affecting ---*/
1204/*--- the original. ---*/
1205/*---------------------------------------------------------------*/
1206
1207/* Copying IR Expr vectors (for call args). */
1208
1209/* Shallow copy of an IRExpr vector */
1210
1211IRExpr** sopyIRExprVec ( IRExpr** vec )
sewardjd7cb8532004-08-17 23:59:23 +00001212{
sewardj695cff92004-10-13 14:50:14 +00001213 Int i;
1214 IRExpr** newvec;
1215 for (i = 0; vec[i]; i++)
1216 ;
1217 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
1218 for (i = 0; vec[i]; i++)
1219 newvec[i] = vec[i];
1220 newvec[i] = NULL;
1221 return newvec;
1222}
1223
1224/* Deep copy of an IRExpr vector */
1225
1226IRExpr** dopyIRExprVec ( IRExpr** vec )
1227{
1228 Int i;
1229 IRExpr** newvec = sopyIRExprVec( vec );
1230 for (i = 0; newvec[i]; i++)
1231 newvec[i] = dopyIRExpr(newvec[i]);
1232 return newvec;
1233}
1234
1235/* Deep copy constructors for all heap-allocated IR types follow. */
1236
1237IRConst* dopyIRConst ( IRConst* c )
1238{
1239 switch (c->tag) {
sewardjba999312004-11-15 15:21:17 +00001240 case Ico_U1: return IRConst_U1(c->Ico.U1);
sewardj695cff92004-10-13 14:50:14 +00001241 case Ico_U8: return IRConst_U8(c->Ico.U8);
1242 case Ico_U16: return IRConst_U16(c->Ico.U16);
1243 case Ico_U32: return IRConst_U32(c->Ico.U32);
1244 case Ico_U64: return IRConst_U64(c->Ico.U64);
1245 case Ico_F64: return IRConst_F64(c->Ico.F64);
1246 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
sewardj1e6ad742004-12-02 16:16:11 +00001247 case Ico_V128: return IRConst_V128(c->Ico.V128);
sewardj695cff92004-10-13 14:50:14 +00001248 default: vpanic("dopyIRConst");
sewardjd7cb8532004-08-17 23:59:23 +00001249 }
sewardj695cff92004-10-13 14:50:14 +00001250}
1251
sewardj8ea867b2004-10-30 19:03:02 +00001252IRCallee* dopyIRCallee ( IRCallee* ce )
1253{
sewardj43c56462004-11-06 12:17:57 +00001254 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
1255 ce2->mcx_mask = ce->mcx_mask;
1256 return ce2;
sewardj8ea867b2004-10-30 19:03:02 +00001257}
1258
sewardj695cff92004-10-13 14:50:14 +00001259IRArray* dopyIRArray ( IRArray* d )
1260{
1261 return mkIRArray(d->base, d->elemTy, d->nElems);
1262}
1263
1264IRExpr* dopyIRExpr ( IRExpr* e )
1265{
1266 switch (e->tag) {
1267 case Iex_Get:
1268 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
1269 case Iex_GetI:
1270 return IRExpr_GetI(dopyIRArray(e->Iex.GetI.descr),
sewardjeeac8412004-11-02 00:26:55 +00001271 dopyIRExpr(e->Iex.GetI.ix),
sewardj695cff92004-10-13 14:50:14 +00001272 e->Iex.GetI.bias);
1273 case Iex_Tmp:
1274 return IRExpr_Tmp(e->Iex.Tmp.tmp);
sewardj1a866b42006-02-09 02:54:03 +00001275 case Iex_Qop:
1276 return IRExpr_Qop(e->Iex.Qop.op,
1277 dopyIRExpr(e->Iex.Qop.arg1),
1278 dopyIRExpr(e->Iex.Qop.arg2),
1279 dopyIRExpr(e->Iex.Qop.arg3),
1280 dopyIRExpr(e->Iex.Qop.arg4));
sewardjb183b852006-02-03 16:08:03 +00001281 case Iex_Triop:
1282 return IRExpr_Triop(e->Iex.Triop.op,
1283 dopyIRExpr(e->Iex.Triop.arg1),
1284 dopyIRExpr(e->Iex.Triop.arg2),
1285 dopyIRExpr(e->Iex.Triop.arg3));
sewardj695cff92004-10-13 14:50:14 +00001286 case Iex_Binop:
1287 return IRExpr_Binop(e->Iex.Binop.op,
1288 dopyIRExpr(e->Iex.Binop.arg1),
1289 dopyIRExpr(e->Iex.Binop.arg2));
1290 case Iex_Unop:
1291 return IRExpr_Unop(e->Iex.Unop.op,
1292 dopyIRExpr(e->Iex.Unop.arg));
sewardjaf1ceca2005-06-30 23:31:27 +00001293 case Iex_Load:
1294 return IRExpr_Load(e->Iex.Load.end,
1295 e->Iex.Load.ty,
1296 dopyIRExpr(e->Iex.Load.addr));
sewardj695cff92004-10-13 14:50:14 +00001297 case Iex_Const:
1298 return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
1299 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +00001300 return IRExpr_CCall(dopyIRCallee(e->Iex.CCall.cee),
sewardj695cff92004-10-13 14:50:14 +00001301 e->Iex.CCall.retty,
1302 dopyIRExprVec(e->Iex.CCall.args));
1303
1304 case Iex_Mux0X:
1305 return IRExpr_Mux0X(dopyIRExpr(e->Iex.Mux0X.cond),
1306 dopyIRExpr(e->Iex.Mux0X.expr0),
1307 dopyIRExpr(e->Iex.Mux0X.exprX));
1308 default:
1309 vpanic("dopyIRExpr");
1310 }
1311}
1312
1313IRDirty* dopyIRDirty ( IRDirty* d )
1314{
1315 Int i;
1316 IRDirty* d2 = emptyIRDirty();
sewardj8ea867b2004-10-30 19:03:02 +00001317 d2->cee = dopyIRCallee(d->cee);
sewardjb8385d82004-11-02 01:34:15 +00001318 d2->guard = dopyIRExpr(d->guard);
sewardj695cff92004-10-13 14:50:14 +00001319 d2->args = dopyIRExprVec(d->args);
1320 d2->tmp = d->tmp;
1321 d2->mFx = d->mFx;
1322 d2->mAddr = d->mAddr==NULL ? NULL : dopyIRExpr(d->mAddr);
1323 d2->mSize = d->mSize;
sewardjc5fc7aa2004-10-27 23:00:55 +00001324 d2->needsBBP = d->needsBBP;
sewardj695cff92004-10-13 14:50:14 +00001325 d2->nFxState = d->nFxState;
1326 for (i = 0; i < d2->nFxState; i++)
1327 d2->fxState[i] = d->fxState[i];
1328 return d2;
1329}
1330
1331IRStmt* dopyIRStmt ( IRStmt* s )
1332{
1333 switch (s->tag) {
sewardjd2445f62005-03-21 00:15:53 +00001334 case Ist_NoOp:
1335 return IRStmt_NoOp();
sewardj5a9ffab2005-05-12 17:55:01 +00001336 case Ist_AbiHint:
1337 return IRStmt_AbiHint(dopyIRExpr(s->Ist.AbiHint.base),
1338 s->Ist.AbiHint.len);
sewardjf1689312005-03-16 18:19:10 +00001339 case Ist_IMark:
1340 return IRStmt_IMark(s->Ist.IMark.addr, s->Ist.IMark.len);
sewardj695cff92004-10-13 14:50:14 +00001341 case Ist_Put:
1342 return IRStmt_Put(s->Ist.Put.offset,
1343 dopyIRExpr(s->Ist.Put.data));
1344 case Ist_PutI:
1345 return IRStmt_PutI(dopyIRArray(s->Ist.PutI.descr),
sewardjeeac8412004-11-02 00:26:55 +00001346 dopyIRExpr(s->Ist.PutI.ix),
sewardj695cff92004-10-13 14:50:14 +00001347 s->Ist.PutI.bias,
1348 dopyIRExpr(s->Ist.PutI.data));
1349 case Ist_Tmp:
1350 return IRStmt_Tmp(s->Ist.Tmp.tmp,
1351 dopyIRExpr(s->Ist.Tmp.data));
sewardjaf1ceca2005-06-30 23:31:27 +00001352 case Ist_Store:
1353 return IRStmt_Store(s->Ist.Store.end,
1354 dopyIRExpr(s->Ist.Store.addr),
1355 dopyIRExpr(s->Ist.Store.data));
sewardj695cff92004-10-13 14:50:14 +00001356 case Ist_Dirty:
1357 return IRStmt_Dirty(dopyIRDirty(s->Ist.Dirty.details));
sewardjd2445f62005-03-21 00:15:53 +00001358 case Ist_MFence:
1359 return IRStmt_MFence();
sewardj695cff92004-10-13 14:50:14 +00001360 case Ist_Exit:
sewardj893aada2004-11-29 19:57:54 +00001361 return IRStmt_Exit(dopyIRExpr(s->Ist.Exit.guard),
1362 s->Ist.Exit.jk,
sewardj695cff92004-10-13 14:50:14 +00001363 dopyIRConst(s->Ist.Exit.dst));
1364 default:
1365 vpanic("dopyIRStmt");
1366 }
1367}
1368
1369IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* src )
1370{
1371 Int i;
1372 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
1373 dst->types_size = src->types_size;
1374 dst->types_used = src->types_used;
1375 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
1376 for (i = 0; i < src->types_used; i++)
1377 dst->types[i] = src->types[i];
1378 return dst;
1379}
1380
1381IRBB* dopyIRBB ( IRBB* bb )
1382{
1383 Int i;
1384 IRStmt** sts2;
1385 IRBB* bb2 = emptyIRBB();
1386 bb2->tyenv = dopyIRTypeEnv(bb->tyenv);
1387 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
1388 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
1389 for (i = 0; i < bb2->stmts_used; i++)
sewardjd2445f62005-03-21 00:15:53 +00001390 sts2[i] = dopyIRStmt(bb->stmts[i]);
sewardj695cff92004-10-13 14:50:14 +00001391 bb2->stmts = sts2;
1392 bb2->next = dopyIRExpr(bb->next);
1393 bb2->jumpkind = bb->jumpkind;
1394 return bb2;
sewardjd7cb8532004-08-17 23:59:23 +00001395}
1396
sewardjec6ad592004-06-20 12:26:53 +00001397
sewardjc97096c2004-06-30 09:28:04 +00001398/*---------------------------------------------------------------*/
sewardj6efd4a12004-07-15 03:54:23 +00001399/*--- Primop types ---*/
1400/*---------------------------------------------------------------*/
1401
1402static
sewardjb183b852006-02-03 16:08:03 +00001403void typeOfPrimop ( IROp op,
1404 /*OUTs*/
1405 IRType* t_dst,
sewardj40c80262006-02-08 19:30:46 +00001406 IRType* t_arg1, IRType* t_arg2,
1407 IRType* t_arg3, IRType* t_arg4 )
sewardj6efd4a12004-07-15 03:54:23 +00001408{
sewardjb183b852006-02-03 16:08:03 +00001409# define UNARY(_ta1,_td) \
sewardj6efd4a12004-07-15 03:54:23 +00001410 *t_dst = (_td); *t_arg1 = (_ta1); break
sewardjb183b852006-02-03 16:08:03 +00001411# define BINARY(_ta1,_ta2,_td) \
sewardj6efd4a12004-07-15 03:54:23 +00001412 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
sewardjb183b852006-02-03 16:08:03 +00001413# define TERNARY(_ta1,_ta2,_ta3,_td) \
1414 *t_dst = (_td); *t_arg1 = (_ta1); \
1415 *t_arg2 = (_ta2); *t_arg3 = (_ta3); break
sewardj40c80262006-02-08 19:30:46 +00001416# define QUATERNARY(_ta1,_ta2,_ta3,_ta4,_td) \
1417 *t_dst = (_td); *t_arg1 = (_ta1); \
1418 *t_arg2 = (_ta2); *t_arg3 = (_ta3); \
1419 *t_arg4 = (_ta4); break
sewardjb183b852006-02-03 16:08:03 +00001420# define COMPARISON(_ta) \
sewardjba999312004-11-15 15:21:17 +00001421 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
sewardjb183b852006-02-03 16:08:03 +00001422# define UNARY_COMPARISON(_ta) \
sewardj0033ddc2005-04-26 23:34:34 +00001423 *t_dst = Ity_I1; *t_arg1 = (_ta); break;
sewardj6efd4a12004-07-15 03:54:23 +00001424
sewardjb183b852006-02-03 16:08:03 +00001425 /* Rounding mode values are always Ity_I32, encoded as per
1426 IRRoundingMode */
1427 const IRType ity_RMode = Ity_I32;
1428
sewardj6efd4a12004-07-15 03:54:23 +00001429 *t_dst = Ity_INVALID;
1430 *t_arg1 = Ity_INVALID;
1431 *t_arg2 = Ity_INVALID;
sewardjb183b852006-02-03 16:08:03 +00001432 *t_arg3 = Ity_INVALID;
sewardj40c80262006-02-08 19:30:46 +00001433 *t_arg4 = Ity_INVALID;
sewardj6efd4a12004-07-15 03:54:23 +00001434 switch (op) {
sewardj17442fe2004-09-20 14:54:28 +00001435 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
1436 case Iop_Or8: case Iop_And8: case Iop_Xor8:
sewardjb183b852006-02-03 16:08:03 +00001437 BINARY(Ity_I8,Ity_I8, Ity_I8);
sewardj6efd4a12004-07-15 03:54:23 +00001438
sewardj17442fe2004-09-20 14:54:28 +00001439 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
1440 case Iop_Or16: case Iop_And16: case Iop_Xor16:
sewardjb183b852006-02-03 16:08:03 +00001441 BINARY(Ity_I16,Ity_I16, Ity_I16);
sewardj6efd4a12004-07-15 03:54:23 +00001442
sewardjb51f0f42005-07-18 11:38:02 +00001443 case Iop_CmpORD32U:
1444 case Iop_CmpORD32S:
sewardj17442fe2004-09-20 14:54:28 +00001445 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
1446 case Iop_Or32: case Iop_And32: case Iop_Xor32:
sewardjb183b852006-02-03 16:08:03 +00001447 BINARY(Ity_I32,Ity_I32, Ity_I32);
sewardj6efd4a12004-07-15 03:54:23 +00001448
sewardj17442fe2004-09-20 14:54:28 +00001449 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
1450 case Iop_Or64: case Iop_And64: case Iop_Xor64:
cerion2831b002005-11-30 19:55:22 +00001451 case Iop_CmpORD64U:
1452 case Iop_CmpORD64S:
sewardj38a3f862005-01-13 15:06:51 +00001453 case Iop_Avg8Ux8: case Iop_Avg16Ux4:
1454 case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2:
1455 case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2:
1456 case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2:
1457 case Iop_InterleaveHI8x8: case Iop_InterleaveLO8x8:
1458 case Iop_InterleaveHI16x4: case Iop_InterleaveLO16x4:
1459 case Iop_InterleaveHI32x2: case Iop_InterleaveLO32x2:
1460 case Iop_Max8Ux8: case Iop_Max16Sx4:
1461 case Iop_Min8Ux8: case Iop_Min16Sx4:
1462 case Iop_Mul16x4: case Iop_MulHi16Sx4: case Iop_MulHi16Ux4:
1463 case Iop_QAdd8Sx8: case Iop_QAdd16Sx4:
1464 case Iop_QAdd8Ux8: case Iop_QAdd16Ux4:
1465 case Iop_QNarrow32Sx2:
1466 case Iop_QNarrow16Sx4: case Iop_QNarrow16Ux4:
1467 case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2:
1468 case Iop_QSub8Sx8: case Iop_QSub16Sx4:
1469 case Iop_QSub8Ux8: case Iop_QSub16Ux4:
sewardjb183b852006-02-03 16:08:03 +00001470 BINARY(Ity_I64,Ity_I64, Ity_I64);
sewardj38a3f862005-01-13 15:06:51 +00001471
1472 case Iop_ShlN32x2: case Iop_ShlN16x4:
1473 case Iop_ShrN32x2: case Iop_ShrN16x4:
1474 case Iop_SarN32x2: case Iop_SarN16x4:
sewardjb183b852006-02-03 16:08:03 +00001475 BINARY(Ity_I64,Ity_I8, Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +00001476
1477 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
sewardjb183b852006-02-03 16:08:03 +00001478 BINARY(Ity_I8,Ity_I8, Ity_I8);
sewardj6efd4a12004-07-15 03:54:23 +00001479 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
sewardjb183b852006-02-03 16:08:03 +00001480 BINARY(Ity_I16,Ity_I8, Ity_I16);
sewardj6efd4a12004-07-15 03:54:23 +00001481 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
sewardjb183b852006-02-03 16:08:03 +00001482 BINARY(Ity_I32,Ity_I8, Ity_I32);
sewardj6efd4a12004-07-15 03:54:23 +00001483 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
sewardjb183b852006-02-03 16:08:03 +00001484 BINARY(Ity_I64,Ity_I8, Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +00001485
sewardj0033ddc2005-04-26 23:34:34 +00001486 case Iop_Not8: case Iop_Neg8:
sewardjb183b852006-02-03 16:08:03 +00001487 UNARY(Ity_I8, Ity_I8);
sewardj0033ddc2005-04-26 23:34:34 +00001488 case Iop_Not16: case Iop_Neg16:
sewardjb183b852006-02-03 16:08:03 +00001489 UNARY(Ity_I16, Ity_I16);
sewardj0033ddc2005-04-26 23:34:34 +00001490 case Iop_Not32: case Iop_Neg32:
sewardjb183b852006-02-03 16:08:03 +00001491 UNARY(Ity_I32, Ity_I32);
sewardj18069182005-01-13 19:16:04 +00001492
sewardj0033ddc2005-04-26 23:34:34 +00001493 case Iop_Neg64:
1494 case Iop_Not64:
sewardj18069182005-01-13 19:16:04 +00001495 case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8:
sewardjb183b852006-02-03 16:08:03 +00001496 UNARY(Ity_I64, Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +00001497
1498 case Iop_CmpEQ8: case Iop_CmpNE8:
1499 COMPARISON(Ity_I8);
1500 case Iop_CmpEQ16: case Iop_CmpNE16:
1501 COMPARISON(Ity_I16);
1502 case Iop_CmpEQ32: case Iop_CmpNE32:
sewardj17442fe2004-09-20 14:54:28 +00001503 case Iop_CmpLT32S: case Iop_CmpLE32S:
1504 case Iop_CmpLT32U: case Iop_CmpLE32U:
sewardj6efd4a12004-07-15 03:54:23 +00001505 COMPARISON(Ity_I32);
1506 case Iop_CmpEQ64: case Iop_CmpNE64:
sewardj98540072005-04-26 01:52:01 +00001507 case Iop_CmpLT64S: case Iop_CmpLE64S:
1508 case Iop_CmpLT64U: case Iop_CmpLE64U:
sewardj6efd4a12004-07-15 03:54:23 +00001509 COMPARISON(Ity_I64);
1510
sewardj0033ddc2005-04-26 23:34:34 +00001511 case Iop_CmpNEZ8: UNARY_COMPARISON(Ity_I8);
1512 case Iop_CmpNEZ16: UNARY_COMPARISON(Ity_I16);
1513 case Iop_CmpNEZ32: UNARY_COMPARISON(Ity_I32);
1514 case Iop_CmpNEZ64: UNARY_COMPARISON(Ity_I64);
1515
sewardjb81f8b32004-07-30 10:17:50 +00001516 case Iop_MullU8: case Iop_MullS8:
sewardjb183b852006-02-03 16:08:03 +00001517 BINARY(Ity_I8,Ity_I8, Ity_I16);
sewardjb81f8b32004-07-30 10:17:50 +00001518 case Iop_MullU16: case Iop_MullS16:
sewardjb183b852006-02-03 16:08:03 +00001519 BINARY(Ity_I16,Ity_I16, Ity_I32);
sewardj6d2638e2004-07-15 09:38:27 +00001520 case Iop_MullU32: case Iop_MullS32:
sewardjb183b852006-02-03 16:08:03 +00001521 BINARY(Ity_I32,Ity_I32, Ity_I64);
sewardj9b967672005-02-08 11:13:09 +00001522 case Iop_MullU64: case Iop_MullS64:
sewardjb183b852006-02-03 16:08:03 +00001523 BINARY(Ity_I64,Ity_I64, Ity_I128);
sewardj6d2638e2004-07-15 09:38:27 +00001524
sewardj17442fe2004-09-20 14:54:28 +00001525 case Iop_Clz32: case Iop_Ctz32:
sewardjb183b852006-02-03 16:08:03 +00001526 UNARY(Ity_I32, Ity_I32);
sewardjce646f22004-08-31 23:55:54 +00001527
sewardjf53b7352005-04-06 20:01:56 +00001528 case Iop_Clz64: case Iop_Ctz64:
sewardjb183b852006-02-03 16:08:03 +00001529 UNARY(Ity_I64, Ity_I64);
sewardjf53b7352005-04-06 20:01:56 +00001530
cerion5c8a0cb2005-02-03 13:59:46 +00001531 case Iop_DivU32: case Iop_DivS32:
sewardjb183b852006-02-03 16:08:03 +00001532 BINARY(Ity_I32,Ity_I32, Ity_I32);
cerion5c8a0cb2005-02-03 13:59:46 +00001533
cerionf0de28c2005-12-13 20:21:11 +00001534 case Iop_DivU64: case Iop_DivS64:
sewardjb183b852006-02-03 16:08:03 +00001535 BINARY(Ity_I64,Ity_I64, Ity_I64);
cerionf0de28c2005-12-13 20:21:11 +00001536
sewardj17442fe2004-09-20 14:54:28 +00001537 case Iop_DivModU64to32: case Iop_DivModS64to32:
sewardjb183b852006-02-03 16:08:03 +00001538 BINARY(Ity_I64,Ity_I32, Ity_I64);
sewardj6d2638e2004-07-15 09:38:27 +00001539
sewardj343b9d02005-01-31 18:08:45 +00001540 case Iop_DivModU128to64: case Iop_DivModS128to64:
sewardjb183b852006-02-03 16:08:03 +00001541 BINARY(Ity_I128,Ity_I64, Ity_I128);
sewardj343b9d02005-01-31 18:08:45 +00001542
sewardjb81f8b32004-07-30 10:17:50 +00001543 case Iop_16HIto8: case Iop_16to8:
sewardjb183b852006-02-03 16:08:03 +00001544 UNARY(Ity_I16, Ity_I8);
sewardjb81f8b32004-07-30 10:17:50 +00001545 case Iop_8HLto16:
sewardjb183b852006-02-03 16:08:03 +00001546 BINARY(Ity_I8,Ity_I8, Ity_I16);
sewardjb81f8b32004-07-30 10:17:50 +00001547
sewardj8c7f1ab2004-07-29 20:31:09 +00001548 case Iop_32HIto16: case Iop_32to16:
sewardjb183b852006-02-03 16:08:03 +00001549 UNARY(Ity_I32, Ity_I16);
sewardj8c7f1ab2004-07-29 20:31:09 +00001550 case Iop_16HLto32:
sewardjb183b852006-02-03 16:08:03 +00001551 BINARY(Ity_I16,Ity_I16, Ity_I32);
sewardj8c7f1ab2004-07-29 20:31:09 +00001552
1553 case Iop_64HIto32: case Iop_64to32:
sewardjb183b852006-02-03 16:08:03 +00001554 UNARY(Ity_I64, Ity_I32);
sewardj6d2638e2004-07-15 09:38:27 +00001555 case Iop_32HLto64:
sewardjb183b852006-02-03 16:08:03 +00001556 BINARY(Ity_I32,Ity_I32, Ity_I64);
sewardj6d2638e2004-07-15 09:38:27 +00001557
sewardj9b967672005-02-08 11:13:09 +00001558 case Iop_128HIto64: case Iop_128to64:
sewardjb183b852006-02-03 16:08:03 +00001559 UNARY(Ity_I128, Ity_I64);
sewardj9b967672005-02-08 11:13:09 +00001560 case Iop_64HLto128:
sewardjb183b852006-02-03 16:08:03 +00001561 BINARY(Ity_I64,Ity_I64, Ity_I128);
sewardj9b967672005-02-08 11:13:09 +00001562
sewardjb183b852006-02-03 16:08:03 +00001563 case Iop_Not1: UNARY(Ity_I1, Ity_I1);
1564 case Iop_1Uto8: UNARY(Ity_I1, Ity_I8);
1565 case Iop_1Sto8: UNARY(Ity_I1, Ity_I8);
1566 case Iop_1Sto16: UNARY(Ity_I1, Ity_I16);
1567 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I1, Ity_I32);
1568 case Iop_1Sto64: case Iop_1Uto64: UNARY(Ity_I1, Ity_I64);
1569 case Iop_32to1: UNARY(Ity_I32, Ity_I1);
1570 case Iop_64to1: UNARY(Ity_I64, Ity_I1);
sewardj47341042004-09-19 11:55:46 +00001571
sewardj17442fe2004-09-20 14:54:28 +00001572 case Iop_8Uto32: case Iop_8Sto32:
sewardjb183b852006-02-03 16:08:03 +00001573 UNARY(Ity_I8, Ity_I32);
sewardj47341042004-09-19 11:55:46 +00001574
sewardj17442fe2004-09-20 14:54:28 +00001575 case Iop_8Uto16: case Iop_8Sto16:
sewardjb183b852006-02-03 16:08:03 +00001576 UNARY(Ity_I8, Ity_I16);
sewardj47341042004-09-19 11:55:46 +00001577
sewardj17442fe2004-09-20 14:54:28 +00001578 case Iop_16Uto32: case Iop_16Sto32:
sewardjb183b852006-02-03 16:08:03 +00001579 UNARY(Ity_I16, Ity_I32);
sewardj6d2638e2004-07-15 09:38:27 +00001580
sewardj17442fe2004-09-20 14:54:28 +00001581 case Iop_32Sto64: case Iop_32Uto64:
sewardjb183b852006-02-03 16:08:03 +00001582 UNARY(Ity_I32, Ity_I64);
sewardj17442fe2004-09-20 14:54:28 +00001583
sewardj291a7e82005-04-27 11:42:44 +00001584 case Iop_8Uto64: case Iop_8Sto64:
sewardjb183b852006-02-03 16:08:03 +00001585 UNARY(Ity_I8, Ity_I64);
sewardj291a7e82005-04-27 11:42:44 +00001586
1587 case Iop_16Uto64: case Iop_16Sto64:
sewardj291a7e82005-04-27 11:42:44 +00001588 UNARY(Ity_I16, Ity_I64);
sewardjb183b852006-02-03 16:08:03 +00001589 case Iop_64to16:
1590 UNARY(Ity_I64, Ity_I16);
sewardj291a7e82005-04-27 11:42:44 +00001591
sewardjb183b852006-02-03 16:08:03 +00001592 case Iop_32to8: UNARY(Ity_I32, Ity_I8);
1593 case Iop_64to8: UNARY(Ity_I64, Ity_I8);
sewardj17442fe2004-09-20 14:54:28 +00001594
sewardjb183b852006-02-03 16:08:03 +00001595 case Iop_AddF64: case Iop_SubF64:
1596 case Iop_MulF64: case Iop_DivF64:
1597 case Iop_AddF64r32: case Iop_SubF64r32:
1598 case Iop_MulF64r32: case Iop_DivF64r32:
1599 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1600
1601 case Iop_NegF64: case Iop_AbsF64:
1602 UNARY(Ity_F64, Ity_F64);
1603
1604 case Iop_SqrtF64:
1605 case Iop_SqrtF64r32:
1606 BINARY(ity_RMode,Ity_F64, Ity_F64);
1607
sewardjbdc7d212004-09-09 02:46:40 +00001608 case Iop_CmpF64:
sewardjb183b852006-02-03 16:08:03 +00001609 BINARY(Ity_F64,Ity_F64, Ity_I32);
sewardj8f3debf2004-09-08 23:42:23 +00001610
sewardjb183b852006-02-03 16:08:03 +00001611 case Iop_F64toI16: BINARY(ity_RMode,Ity_F64, Ity_I16);
1612 case Iop_F64toI32: BINARY(ity_RMode,Ity_F64, Ity_I32);
1613 case Iop_F64toI64: BINARY(ity_RMode,Ity_F64, Ity_I64);
sewardj8f3debf2004-09-08 23:42:23 +00001614
sewardjb183b852006-02-03 16:08:03 +00001615 case Iop_I16toF64: UNARY(Ity_I16, Ity_F64);
1616 case Iop_I32toF64: UNARY(Ity_I32, Ity_F64);
1617 case Iop_I64toF64: BINARY(ity_RMode,Ity_I64, Ity_F64);
sewardj3bca9062004-12-04 14:36:09 +00001618
sewardjb183b852006-02-03 16:08:03 +00001619 case Iop_F32toF64: UNARY(Ity_F32, Ity_F64);
1620 case Iop_F64toF32: BINARY(ity_RMode,Ity_F64, Ity_F32);
sewardj4cb918d2004-12-03 19:43:31 +00001621
sewardjb183b852006-02-03 16:08:03 +00001622 case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64);
1623 case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64);
1624 case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32);
sewardj8f3debf2004-09-08 23:42:23 +00001625
sewardjb183b852006-02-03 16:08:03 +00001626 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
1627 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
1628 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64);
1629
1630 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
1631 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_I32);
1632
1633 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64:
1634 case Iop_2xm1F64:
1635 case Iop_RoundF64toInt: BINARY(ity_RMode,Ity_F64, Ity_F64);
1636
sewardj40c80262006-02-08 19:30:46 +00001637 case Iop_MAddF64: case Iop_MSubF64:
1638 case Iop_MAddF64r32: case Iop_MSubF64r32:
1639 QUATERNARY(ity_RMode,Ity_F64,Ity_F64,Ity_F64, Ity_F64);
1640
sewardjb183b852006-02-03 16:08:03 +00001641 case Iop_Est5FRSqrt:
1642 UNARY(Ity_F64, Ity_F64);
1643 case Iop_RoundF64toF32:
1644 BINARY(ity_RMode,Ity_F64, Ity_F64);
1645 case Iop_CalcFPRF:
1646 UNARY(Ity_F64, Ity_I32);
1647 case Iop_TruncF64asF32:
1648 UNARY(Ity_F64, Ity_F32);
sewardjbb53f8c2004-08-14 11:50:01 +00001649
cerionf294eb32005-11-16 17:21:10 +00001650 case Iop_I32UtoFx4:
1651 case Iop_I32StoFx4:
1652 case Iop_QFtoI32Ux4_RZ:
1653 case Iop_QFtoI32Sx4_RZ:
1654 case Iop_RoundF32x4_RM:
1655 case Iop_RoundF32x4_RP:
1656 case Iop_RoundF32x4_RN:
1657 case Iop_RoundF32x4_RZ:
1658 UNARY(Ity_V128, Ity_V128);
1659
sewardjb183b852006-02-03 16:08:03 +00001660 case Iop_64HLtoV128: BINARY(Ity_I64,Ity_I64, Ity_V128);
sewardjf0c1c582005-02-07 23:47:38 +00001661 case Iop_V128to64: case Iop_V128HIto64:
sewardjb183b852006-02-03 16:08:03 +00001662 UNARY(Ity_V128, Ity_I64);
sewardjc9a43662004-11-30 18:51:59 +00001663
sewardjb183b852006-02-03 16:08:03 +00001664 case Iop_V128to32: UNARY(Ity_V128, Ity_I32);
1665 case Iop_32UtoV128: UNARY(Ity_I32, Ity_V128);
1666 case Iop_64UtoV128: UNARY(Ity_I64, Ity_V128);
1667 case Iop_SetV128lo32: BINARY(Ity_V128,Ity_I32, Ity_V128);
1668 case Iop_SetV128lo64: BINARY(Ity_V128,Ity_I64, Ity_V128);
sewardj129b3d92004-12-05 15:42:05 +00001669
sewardjb183b852006-02-03 16:08:03 +00001670 case Iop_Dup8x16: UNARY(Ity_I8, Ity_V128);
1671 case Iop_Dup16x8: UNARY(Ity_I16, Ity_V128);
1672 case Iop_Dup32x4: UNARY(Ity_I32, Ity_V128);
cerionf887b3e2005-09-13 16:34:28 +00001673
sewardj1e6ad742004-12-02 16:16:11 +00001674 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001675 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
sewardj1e6ad742004-12-02 16:16:11 +00001676 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001677 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
cerion206c3642005-11-14 00:35:59 +00001678 case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4:
sewardj1e6ad742004-12-02 16:16:11 +00001679 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001680 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001681 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001682 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001683 case Iop_Add32Fx4: case Iop_Add32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001684 case Iop_Add64Fx2: case Iop_Add64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001685 case Iop_Div32Fx4: case Iop_Div32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001686 case Iop_Div64Fx2: case Iop_Div64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001687 case Iop_Max32Fx4: case Iop_Max32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001688 case Iop_Max64Fx2: case Iop_Max64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001689 case Iop_Min32Fx4: case Iop_Min32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001690 case Iop_Min64Fx2: case Iop_Min64F0x2:
sewardj9636b442004-12-04 01:38:37 +00001691 case Iop_Mul32Fx4: case Iop_Mul32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001692 case Iop_Mul64Fx2: case Iop_Mul64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001693 case Iop_Sub32Fx4: case Iop_Sub32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001694 case Iop_Sub64Fx2: case Iop_Sub64F0x2:
sewardjf0c1c582005-02-07 23:47:38 +00001695 case Iop_AndV128: case Iop_OrV128: case Iop_XorV128:
sewardj164f9272004-12-09 00:39:32 +00001696 case Iop_Add8x16: case Iop_Add16x8:
1697 case Iop_Add32x4: case Iop_Add64x2:
cerionf887b3e2005-09-13 16:34:28 +00001698 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8: case Iop_QAdd32Ux4:
1699 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8: case Iop_QAdd32Sx4:
sewardj164f9272004-12-09 00:39:32 +00001700 case Iop_Sub8x16: case Iop_Sub16x8:
1701 case Iop_Sub32x4: case Iop_Sub64x2:
cerionf887b3e2005-09-13 16:34:28 +00001702 case Iop_QSub8Ux16: case Iop_QSub16Ux8: case Iop_QSub32Ux4:
1703 case Iop_QSub8Sx16: case Iop_QSub16Sx8: case Iop_QSub32Sx4:
sewardj164f9272004-12-09 00:39:32 +00001704 case Iop_Mul16x8:
cerionf887b3e2005-09-13 16:34:28 +00001705 case Iop_MulHi16Ux8: case Iop_MulHi32Ux4:
1706 case Iop_MulHi16Sx8: case Iop_MulHi32Sx4:
cerion1ac656a2005-11-04 19:44:48 +00001707 case Iop_MullEven8Ux16: case Iop_MullEven16Ux8:
1708 case Iop_MullEven8Sx16: case Iop_MullEven16Sx8:
cerionf887b3e2005-09-13 16:34:28 +00001709 case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4:
1710 case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4:
1711 case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4:
1712 case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4:
1713 case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4:
1714 case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4:
sewardj164f9272004-12-09 00:39:32 +00001715 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
1716 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
cerionf887b3e2005-09-13 16:34:28 +00001717 case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4:
1718 case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4:
1719 case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4:
1720 case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4:
sewardj1bee5612005-11-10 18:10:58 +00001721 case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4:
cerion9e7677b2005-09-13 17:25:41 +00001722 case Iop_QNarrow16Ux8: case Iop_QNarrow32Ux4:
sewardj164f9272004-12-09 00:39:32 +00001723 case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4:
sewardj1bee5612005-11-10 18:10:58 +00001724 case Iop_Narrow16x8: case Iop_Narrow32x4:
sewardj164f9272004-12-09 00:39:32 +00001725 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
1726 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
1727 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
1728 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
sewardjdc1f9132005-10-22 12:49:49 +00001729 case Iop_Perm8x16:
sewardjb183b852006-02-03 16:08:03 +00001730 BINARY(Ity_V128,Ity_V128, Ity_V128);
sewardjc9a43662004-11-30 18:51:59 +00001731
sewardjf0c1c582005-02-07 23:47:38 +00001732 case Iop_NotV128:
sewardj0bd7ce62004-12-05 02:47:40 +00001733 case Iop_Recip32Fx4: case Iop_Recip32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001734 case Iop_Recip64Fx2: case Iop_Recip64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001735 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001736 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001737 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001738 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2:
sewardj2e383862004-12-12 16:46:47 +00001739 case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8:
sewardj109ffdb2004-12-10 21:45:38 +00001740 case Iop_CmpNEZ32x4: case Iop_CmpNEZ64x2:
sewardj0bd7ce62004-12-05 02:47:40 +00001741 UNARY(Ity_V128, Ity_V128);
1742
cerionf887b3e2005-09-13 16:34:28 +00001743 case Iop_ShlV128: case Iop_ShrV128:
sewardjb183b852006-02-03 16:08:03 +00001744 case Iop_ShlN8x16: case Iop_ShlN16x8:
1745 case Iop_ShlN32x4: case Iop_ShlN64x2:
1746 case Iop_ShrN8x16: case Iop_ShrN16x8:
1747 case Iop_ShrN32x4: case Iop_ShrN64x2:
cerion2a4b8452005-09-15 16:28:36 +00001748 case Iop_SarN8x16: case Iop_SarN16x8: case Iop_SarN32x4:
sewardjb183b852006-02-03 16:08:03 +00001749 BINARY(Ity_V128,Ity_I8, Ity_V128);
sewardj164f9272004-12-09 00:39:32 +00001750
sewardj6efd4a12004-07-15 03:54:23 +00001751 default:
1752 ppIROp(op);
1753 vpanic("typeOfPrimop");
1754 }
1755# undef UNARY
1756# undef BINARY
sewardjb183b852006-02-03 16:08:03 +00001757# undef TERNARY
sewardj6efd4a12004-07-15 03:54:23 +00001758# undef COMPARISON
sewardj0033ddc2005-04-26 23:34:34 +00001759# undef UNARY_COMPARISON
sewardj6efd4a12004-07-15 03:54:23 +00001760}
1761
1762
1763/*---------------------------------------------------------------*/
sewardj695cff92004-10-13 14:50:14 +00001764/*--- Helper functions for the IR -- IR Basic Blocks ---*/
sewardjc97096c2004-06-30 09:28:04 +00001765/*---------------------------------------------------------------*/
1766
sewardj695cff92004-10-13 14:50:14 +00001767void addStmtToIRBB ( IRBB* bb, IRStmt* st )
sewardjd7cb8532004-08-17 23:59:23 +00001768{
1769 Int i;
sewardj695cff92004-10-13 14:50:14 +00001770 if (bb->stmts_used == bb->stmts_size) {
1771 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1772 for (i = 0; i < bb->stmts_size; i++)
1773 stmts2[i] = bb->stmts[i];
1774 bb->stmts = stmts2;
1775 bb->stmts_size *= 2;
1776 }
1777 vassert(bb->stmts_used < bb->stmts_size);
1778 bb->stmts[bb->stmts_used] = st;
1779 bb->stmts_used++;
sewardjd7cb8532004-08-17 23:59:23 +00001780}
1781
sewardj695cff92004-10-13 14:50:14 +00001782
1783/*---------------------------------------------------------------*/
1784/*--- Helper functions for the IR -- IR Type Environments ---*/
1785/*---------------------------------------------------------------*/
1786
sewardjd7cb8532004-08-17 23:59:23 +00001787/* Allocate a new IRTemp, given its type. */
sewardje3d0d2e2004-06-27 10:42:44 +00001788
sewardje539a402004-07-14 18:24:17 +00001789IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
sewardjc97096c2004-06-30 09:28:04 +00001790{
sewardj35421a32004-07-05 13:12:34 +00001791 vassert(env);
sewardje539a402004-07-14 18:24:17 +00001792 vassert(env->types_used >= 0);
1793 vassert(env->types_size >= 0);
1794 vassert(env->types_used <= env->types_size);
1795 if (env->types_used < env->types_size) {
1796 env->types[env->types_used] = ty;
1797 return env->types_used++;
sewardjc97096c2004-06-30 09:28:04 +00001798 } else {
1799 Int i;
sewardje539a402004-07-14 18:24:17 +00001800 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
1801 IRType* new_types
1802 = LibVEX_Alloc(new_size * sizeof(IRType));
1803 for (i = 0; i < env->types_used; i++)
1804 new_types[i] = env->types[i];
1805 env->types = new_types;
1806 env->types_size = new_size;
1807 return newIRTemp(env, ty);
sewardjc97096c2004-06-30 09:28:04 +00001808 }
1809}
1810
1811
sewardj17442fe2004-09-20 14:54:28 +00001812/*---------------------------------------------------------------*/
1813/*--- Helper functions for the IR -- finding types of exprs ---*/
1814/*---------------------------------------------------------------*/
1815
sewardjedeb4c42004-09-21 23:39:25 +00001816inline
sewardj17442fe2004-09-20 14:54:28 +00001817IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
sewardjc97096c2004-06-30 09:28:04 +00001818{
sewardje539a402004-07-14 18:24:17 +00001819 vassert(tmp >= 0);
1820 vassert(tmp < env->types_used);
1821 return env->types[tmp];
sewardjc97096c2004-06-30 09:28:04 +00001822}
1823
1824
sewardj6efd4a12004-07-15 03:54:23 +00001825IRType typeOfIRConst ( IRConst* con )
1826{
1827 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +00001828 case Ico_U1: return Ity_I1;
sewardj207557a2004-08-27 12:00:18 +00001829 case Ico_U8: return Ity_I8;
1830 case Ico_U16: return Ity_I16;
1831 case Ico_U32: return Ity_I32;
1832 case Ico_U64: return Ity_I64;
1833 case Ico_F64: return Ity_F64;
sewardj17442fe2004-09-20 14:54:28 +00001834 case Ico_F64i: return Ity_F64;
sewardj1e6ad742004-12-02 16:16:11 +00001835 case Ico_V128: return Ity_V128;
sewardj6efd4a12004-07-15 03:54:23 +00001836 default: vpanic("typeOfIRConst");
1837 }
1838}
1839
sewardjc97096c2004-06-30 09:28:04 +00001840IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
1841{
sewardj40c80262006-02-08 19:30:46 +00001842 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
sewardjedeb4c42004-09-21 23:39:25 +00001843 start:
sewardjc97096c2004-06-30 09:28:04 +00001844 switch (e->tag) {
sewardjaf1ceca2005-06-30 23:31:27 +00001845 case Iex_Load:
1846 return e->Iex.Load.ty;
sewardjfbcaf332004-07-08 01:46:01 +00001847 case Iex_Get:
1848 return e->Iex.Get.ty;
sewardjbb53f8c2004-08-14 11:50:01 +00001849 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +00001850 return e->Iex.GetI.descr->elemTy;
sewardjc97096c2004-06-30 09:28:04 +00001851 case Iex_Tmp:
sewardj17442fe2004-09-20 14:54:28 +00001852 return typeOfIRTemp(tyenv, e->Iex.Tmp.tmp);
sewardjc97096c2004-06-30 09:28:04 +00001853 case Iex_Const:
sewardj695cff92004-10-13 14:50:14 +00001854 return typeOfIRConst(e->Iex.Const.con);
sewardj40c80262006-02-08 19:30:46 +00001855 case Iex_Qop:
1856 typeOfPrimop(e->Iex.Qop.op,
1857 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
1858 return t_dst;
sewardjb183b852006-02-03 16:08:03 +00001859 case Iex_Triop:
sewardj40c80262006-02-08 19:30:46 +00001860 typeOfPrimop(e->Iex.Triop.op,
1861 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardjb183b852006-02-03 16:08:03 +00001862 return t_dst;
sewardjc97096c2004-06-30 09:28:04 +00001863 case Iex_Binop:
sewardj40c80262006-02-08 19:30:46 +00001864 typeOfPrimop(e->Iex.Binop.op,
1865 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardj6efd4a12004-07-15 03:54:23 +00001866 return t_dst;
1867 case Iex_Unop:
sewardj40c80262006-02-08 19:30:46 +00001868 typeOfPrimop(e->Iex.Unop.op,
1869 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardj6efd4a12004-07-15 03:54:23 +00001870 return t_dst;
1871 case Iex_CCall:
1872 return e->Iex.CCall.retty;
sewardj4042c7e2004-07-18 01:28:30 +00001873 case Iex_Mux0X:
sewardjedeb4c42004-09-21 23:39:25 +00001874 e = e->Iex.Mux0X.expr0;
1875 goto start;
1876 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
sewardj443cd9d2004-07-18 23:06:45 +00001877 case Iex_Binder:
1878 vpanic("typeOfIRExpr: Binder is not a valid expression");
sewardjc97096c2004-06-30 09:28:04 +00001879 default:
sewardj6efd4a12004-07-15 03:54:23 +00001880 ppIRExpr(e);
1881 vpanic("typeOfIRExpr");
sewardjc97096c2004-06-30 09:28:04 +00001882 }
sewardjc97096c2004-06-30 09:28:04 +00001883}
sewardj887a11a2004-07-05 17:26:47 +00001884
sewardj6d2638e2004-07-15 09:38:27 +00001885/* Is this any value actually in the enumeration 'IRType' ? */
sewardj496a58d2005-03-20 18:44:44 +00001886Bool isPlausibleIRType ( IRType ty )
sewardj6d2638e2004-07-15 09:38:27 +00001887{
1888 switch (ty) {
sewardjba999312004-11-15 15:21:17 +00001889 case Ity_INVALID: case Ity_I1:
sewardj9b967672005-02-08 11:13:09 +00001890 case Ity_I8: case Ity_I16: case Ity_I32:
1891 case Ity_I64: case Ity_I128:
sewardjbb53f8c2004-08-14 11:50:01 +00001892 case Ity_F32: case Ity_F64:
sewardjc9a43662004-11-30 18:51:59 +00001893 case Ity_V128:
sewardj6d2638e2004-07-15 09:38:27 +00001894 return True;
1895 default:
1896 return False;
1897 }
1898}
1899
sewardj6efd4a12004-07-15 03:54:23 +00001900
sewardj887a11a2004-07-05 17:26:47 +00001901/*---------------------------------------------------------------*/
sewardjcf787902004-11-03 09:08:33 +00001902/*--- Sanity checking -- FLATNESS ---*/
1903/*---------------------------------------------------------------*/
1904
1905/* Check that the canonical flatness constraints hold on an
1906 IRStmt. The only place where any expression is allowed to be
1907 non-atomic is the RHS of IRStmt_Tmp. */
1908
1909/* Relies on:
1910 inline static Bool isAtom ( IRExpr* e ) {
1911 return e->tag == Iex_Tmp || e->tag == Iex_Const;
1912 }
1913*/
1914
1915Bool isFlatIRStmt ( IRStmt* st )
1916{
1917 Int i;
1918 IRExpr* e;
1919 IRDirty* di;
1920
1921 switch (st->tag) {
sewardj5a9ffab2005-05-12 17:55:01 +00001922 case Ist_AbiHint:
1923 return isIRAtom(st->Ist.AbiHint.base);
sewardjcf787902004-11-03 09:08:33 +00001924 case Ist_Put:
sewardj496a58d2005-03-20 18:44:44 +00001925 return isIRAtom(st->Ist.Put.data);
sewardjcf787902004-11-03 09:08:33 +00001926 case Ist_PutI:
sewardj496a58d2005-03-20 18:44:44 +00001927 return toBool( isIRAtom(st->Ist.PutI.ix)
1928 && isIRAtom(st->Ist.PutI.data) );
sewardjcf787902004-11-03 09:08:33 +00001929 case Ist_Tmp:
1930 /* This is the only interesting case. The RHS can be any
1931 expression, *but* all its subexpressions *must* be
1932 atoms. */
1933 e = st->Ist.Tmp.data;
1934 switch (e->tag) {
1935 case Iex_Binder: return True;
1936 case Iex_Get: return True;
sewardj496a58d2005-03-20 18:44:44 +00001937 case Iex_GetI: return isIRAtom(e->Iex.GetI.ix);
sewardjcf787902004-11-03 09:08:33 +00001938 case Iex_Tmp: return True;
sewardj40c80262006-02-08 19:30:46 +00001939 case Iex_Qop: return toBool(
1940 isIRAtom(e->Iex.Qop.arg1)
1941 && isIRAtom(e->Iex.Qop.arg2)
1942 && isIRAtom(e->Iex.Qop.arg3)
1943 && isIRAtom(e->Iex.Qop.arg4));
sewardjb183b852006-02-03 16:08:03 +00001944 case Iex_Triop: return toBool(
1945 isIRAtom(e->Iex.Triop.arg1)
1946 && isIRAtom(e->Iex.Triop.arg2)
1947 && isIRAtom(e->Iex.Triop.arg3));
sewardja98bf492005-02-07 01:39:17 +00001948 case Iex_Binop: return toBool(
sewardj496a58d2005-03-20 18:44:44 +00001949 isIRAtom(e->Iex.Binop.arg1)
1950 && isIRAtom(e->Iex.Binop.arg2));
1951 case Iex_Unop: return isIRAtom(e->Iex.Unop.arg);
sewardjaf1ceca2005-06-30 23:31:27 +00001952 case Iex_Load: return isIRAtom(e->Iex.Load.addr);
sewardjcf787902004-11-03 09:08:33 +00001953 case Iex_Const: return True;
1954 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
sewardj496a58d2005-03-20 18:44:44 +00001955 if (!isIRAtom(e->Iex.CCall.args[i]))
sewardjcf787902004-11-03 09:08:33 +00001956 return False;
1957 return True;
sewardja98bf492005-02-07 01:39:17 +00001958 case Iex_Mux0X: return toBool (
sewardj496a58d2005-03-20 18:44:44 +00001959 isIRAtom(e->Iex.Mux0X.cond)
1960 && isIRAtom(e->Iex.Mux0X.expr0)
1961 && isIRAtom(e->Iex.Mux0X.exprX));
sewardjcf787902004-11-03 09:08:33 +00001962 default: vpanic("isFlatIRStmt(e)");
1963 }
1964 /*notreached*/
1965 vassert(0);
sewardjaf1ceca2005-06-30 23:31:27 +00001966 case Ist_Store:
1967 return toBool( isIRAtom(st->Ist.Store.addr)
1968 && isIRAtom(st->Ist.Store.data) );
sewardjcf787902004-11-03 09:08:33 +00001969 case Ist_Dirty:
1970 di = st->Ist.Dirty.details;
sewardj496a58d2005-03-20 18:44:44 +00001971 if (!isIRAtom(di->guard))
sewardjcf787902004-11-03 09:08:33 +00001972 return False;
1973 for (i = 0; di->args[i]; i++)
sewardj496a58d2005-03-20 18:44:44 +00001974 if (!isIRAtom(di->args[i]))
sewardjcf787902004-11-03 09:08:33 +00001975 return False;
sewardj496a58d2005-03-20 18:44:44 +00001976 if (di->mAddr && !isIRAtom(di->mAddr))
sewardjcf787902004-11-03 09:08:33 +00001977 return False;
1978 return True;
sewardjd2445f62005-03-21 00:15:53 +00001979 case Ist_NoOp:
sewardjf1689312005-03-16 18:19:10 +00001980 case Ist_IMark:
sewardj3e838932005-01-07 12:09:15 +00001981 case Ist_MFence:
1982 return True;
sewardjcf787902004-11-03 09:08:33 +00001983 case Ist_Exit:
sewardj496a58d2005-03-20 18:44:44 +00001984 return isIRAtom(st->Ist.Exit.guard);
sewardjcf787902004-11-03 09:08:33 +00001985 default:
1986 vpanic("isFlatIRStmt(st)");
1987 }
1988}
1989
1990
1991/*---------------------------------------------------------------*/
sewardje539a402004-07-14 18:24:17 +00001992/*--- Sanity checking ---*/
1993/*---------------------------------------------------------------*/
1994
1995/* Checks:
1996
1997 Everything is type-consistent. No ill-typed anything.
sewardj35439212004-07-14 22:36:10 +00001998 The target address at the end of the BB is a 32- or 64-
1999 bit expression, depending on the guest's word size.
sewardje539a402004-07-14 18:24:17 +00002000
2001 Each temp is assigned only once, before its uses.
sewardjc13e2ed2004-10-31 21:44:54 +00002002*/
2003
2004static inline Int countArgs ( IRExpr** args )
2005{
2006 Int i;
2007 for (i = 0; args[i]; i++)
2008 ;
2009 return i;
2010}
sewardje539a402004-07-14 18:24:17 +00002011
sewardj35439212004-07-14 22:36:10 +00002012static
2013__attribute((noreturn))
sewardja98bf492005-02-07 01:39:17 +00002014void sanityCheckFail ( IRBB* bb, IRStmt* stmt, HChar* what )
sewardje539a402004-07-14 18:24:17 +00002015{
sewardj35439212004-07-14 22:36:10 +00002016 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
2017 ppIRBB(bb);
2018 if (stmt) {
2019 vex_printf("\nIN STATEMENT:\n\n");
2020 ppIRStmt(stmt);
2021 }
2022 vex_printf("\n\nERROR = %s\n\n", what );
2023 vpanic("sanityCheckFail: exiting due to bad IR");
2024}
2025
sewardj2d3f77c2004-09-22 23:49:09 +00002026static Bool saneIRArray ( IRArray* arr )
2027{
2028 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
2029 return False;
sewardjba999312004-11-15 15:21:17 +00002030 if (arr->elemTy == Ity_I1)
sewardj2d3f77c2004-09-22 23:49:09 +00002031 return False;
2032 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
2033 return False;
2034 return True;
2035}
2036
sewardj8ea867b2004-10-30 19:03:02 +00002037static Bool saneIRCallee ( IRCallee* cee )
2038{
2039 if (cee->name == NULL)
2040 return False;
2041 if (cee->addr == 0)
2042 return False;
sewardj77352542004-10-30 20:39:01 +00002043 if (cee->regparms < 0 || cee->regparms > 3)
sewardj8ea867b2004-10-30 19:03:02 +00002044 return False;
2045 return True;
2046}
2047
sewardj49bfe672004-11-15 15:46:26 +00002048static Bool saneIRConst ( IRConst* con )
2049{
2050 switch (con->tag) {
2051 case Ico_U1:
sewardja98bf492005-02-07 01:39:17 +00002052 return toBool( con->Ico.U1 == True || con->Ico.U1 == False );
sewardj49bfe672004-11-15 15:46:26 +00002053 default:
2054 /* Is there anything we can meaningfully check? I don't
2055 think so. */
2056 return True;
2057 }
2058}
sewardj35439212004-07-14 22:36:10 +00002059
2060/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
2061 range ones. Report any which are read and for which the current
2062 def_count is zero. */
2063
2064static
sewardj17442fe2004-09-20 14:54:28 +00002065void useBeforeDef_Temp ( IRBB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
2066{
2067 if (tmp < 0 || tmp >= bb->tyenv->types_used)
2068 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
2069 if (def_counts[tmp] < 1)
2070 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
2071}
2072
2073static
sewardj35439212004-07-14 22:36:10 +00002074void useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
2075{
2076 Int i;
2077 switch (expr->tag) {
2078 case Iex_Get:
2079 break;
sewardjbb53f8c2004-08-14 11:50:01 +00002080 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00002081 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
sewardjbb53f8c2004-08-14 11:50:01 +00002082 break;
sewardj17442fe2004-09-20 14:54:28 +00002083 case Iex_Tmp:
2084 useBeforeDef_Temp(bb,stmt,expr->Iex.Tmp.tmp,def_counts);
sewardj35439212004-07-14 22:36:10 +00002085 break;
sewardj40c80262006-02-08 19:30:46 +00002086 case Iex_Qop:
2087 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg1,def_counts);
2088 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg2,def_counts);
2089 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg3,def_counts);
2090 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg4,def_counts);
2091 break;
sewardjb183b852006-02-03 16:08:03 +00002092 case Iex_Triop:
2093 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg1,def_counts);
2094 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg2,def_counts);
2095 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg3,def_counts);
2096 break;
sewardj35439212004-07-14 22:36:10 +00002097 case Iex_Binop:
2098 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
2099 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
2100 break;
2101 case Iex_Unop:
2102 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
2103 break;
sewardjaf1ceca2005-06-30 23:31:27 +00002104 case Iex_Load:
2105 useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
sewardj35439212004-07-14 22:36:10 +00002106 break;
2107 case Iex_Const:
2108 break;
2109 case Iex_CCall:
2110 for (i = 0; expr->Iex.CCall.args[i]; i++)
2111 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
2112 break;
sewardj4042c7e2004-07-18 01:28:30 +00002113 case Iex_Mux0X:
2114 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
2115 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
2116 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
sewardjeeb9ef82004-07-15 12:39:03 +00002117 break;
2118 default:
2119 vpanic("useBeforeDef_Expr");
sewardj35439212004-07-14 22:36:10 +00002120 }
2121}
2122
2123static
2124void useBeforeDef_Stmt ( IRBB* bb, IRStmt* stmt, Int* def_counts )
2125{
sewardj17442fe2004-09-20 14:54:28 +00002126 Int i;
2127 IRDirty* d;
sewardj35439212004-07-14 22:36:10 +00002128 switch (stmt->tag) {
sewardjf1689312005-03-16 18:19:10 +00002129 case Ist_IMark:
2130 break;
sewardj5a9ffab2005-05-12 17:55:01 +00002131 case Ist_AbiHint:
2132 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
2133 break;
sewardj35439212004-07-14 22:36:10 +00002134 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00002135 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00002136 break;
sewardjd1725d12004-08-12 20:46:53 +00002137 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +00002138 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
sewardj2d3f77c2004-09-22 23:49:09 +00002139 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
sewardjd1725d12004-08-12 20:46:53 +00002140 break;
sewardj35439212004-07-14 22:36:10 +00002141 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00002142 useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00002143 break;
sewardjaf1ceca2005-06-30 23:31:27 +00002144 case Ist_Store:
2145 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
2146 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00002147 break;
sewardj17442fe2004-09-20 14:54:28 +00002148 case Ist_Dirty:
2149 d = stmt->Ist.Dirty.details;
2150 for (i = 0; d->args[i] != NULL; i++)
2151 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
2152 if (d->mFx != Ifx_None)
2153 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
2154 break;
sewardjd2445f62005-03-21 00:15:53 +00002155 case Ist_NoOp:
sewardj3e838932005-01-07 12:09:15 +00002156 case Ist_MFence:
2157 break;
sewardj35439212004-07-14 22:36:10 +00002158 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00002159 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
sewardj35439212004-07-14 22:36:10 +00002160 break;
2161 default:
2162 vpanic("useBeforeDef_Stmt");
2163 }
2164}
2165
sewardj6efd4a12004-07-15 03:54:23 +00002166static
2167void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
2168{
2169 Int i;
sewardj40c80262006-02-08 19:30:46 +00002170 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
sewardj6efd4a12004-07-15 03:54:23 +00002171 IRTypeEnv* tyenv = bb->tyenv;
2172 switch (expr->tag) {
2173 case Iex_Get:
2174 case Iex_Tmp:
2175 break;
sewardjbb53f8c2004-08-14 11:50:01 +00002176 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00002177 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
2178 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
2179 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00002180 if (!saneIRArray(expr->Iex.GetI.descr))
2181 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
sewardjbb53f8c2004-08-14 11:50:01 +00002182 break;
sewardj40c80262006-02-08 19:30:46 +00002183 case Iex_Qop: {
2184 IRType ttarg1, ttarg2, ttarg3, ttarg4;
2185 tcExpr(bb,stmt, expr->Iex.Qop.arg1, gWordTy );
2186 tcExpr(bb,stmt, expr->Iex.Qop.arg2, gWordTy );
2187 tcExpr(bb,stmt, expr->Iex.Qop.arg3, gWordTy );
2188 tcExpr(bb,stmt, expr->Iex.Qop.arg4, gWordTy );
2189 typeOfPrimop(expr->Iex.Qop.op,
2190 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
2191 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
2192 || t_arg3 == Ity_INVALID || t_arg4 == Ity_INVALID) {
2193 vex_printf(" op name: " );
2194 ppIROp(expr->Iex.Qop.op);
2195 vex_printf("\n");
2196 sanityCheckFail(bb,stmt,
2197 "Iex.Qop: wrong arity op\n"
2198 "... name of op precedes BB printout\n");
2199 }
2200 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg1);
2201 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg2);
2202 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg3);
2203 ttarg4 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg4);
2204 if (t_arg1 != ttarg1 || t_arg2 != ttarg2
2205 || t_arg3 != ttarg3 || t_arg4 != ttarg4) {
2206 vex_printf(" op name: ");
2207 ppIROp(expr->Iex.Qop.op);
2208 vex_printf("\n");
2209 vex_printf(" op type is (");
2210 ppIRType(t_arg1);
2211 vex_printf(",");
2212 ppIRType(t_arg2);
2213 vex_printf(",");
2214 ppIRType(t_arg3);
2215 vex_printf(",");
2216 ppIRType(t_arg4);
2217 vex_printf(") -> ");
2218 ppIRType (t_dst);
2219 vex_printf("\narg tys are (");
2220 ppIRType(ttarg1);
2221 vex_printf(",");
2222 ppIRType(ttarg2);
2223 vex_printf(",");
2224 ppIRType(ttarg3);
2225 vex_printf(",");
2226 ppIRType(ttarg4);
2227 vex_printf(")\n");
2228 sanityCheckFail(bb,stmt,
2229 "Iex.Qop: arg tys don't match op tys\n"
2230 "... additional details precede BB printout\n");
2231 }
2232 break;
2233 }
sewardjb183b852006-02-03 16:08:03 +00002234 case Iex_Triop: {
2235 IRType ttarg1, ttarg2, ttarg3;
2236 tcExpr(bb,stmt, expr->Iex.Triop.arg1, gWordTy );
2237 tcExpr(bb,stmt, expr->Iex.Triop.arg2, gWordTy );
2238 tcExpr(bb,stmt, expr->Iex.Triop.arg3, gWordTy );
sewardj40c80262006-02-08 19:30:46 +00002239 typeOfPrimop(expr->Iex.Triop.op,
2240 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardjb183b852006-02-03 16:08:03 +00002241 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
sewardj40c80262006-02-08 19:30:46 +00002242 || t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) {
sewardjb183b852006-02-03 16:08:03 +00002243 vex_printf(" op name: " );
2244 ppIROp(expr->Iex.Triop.op);
2245 vex_printf("\n");
2246 sanityCheckFail(bb,stmt,
2247 "Iex.Triop: wrong arity op\n"
2248 "... name of op precedes BB printout\n");
2249 }
2250 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg1);
2251 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg2);
2252 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg3);
2253 if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
2254 vex_printf(" op name: ");
2255 ppIROp(expr->Iex.Triop.op);
2256 vex_printf("\n");
2257 vex_printf(" op type is (");
2258 ppIRType(t_arg1);
2259 vex_printf(",");
2260 ppIRType(t_arg2);
2261 vex_printf(",");
2262 ppIRType(t_arg3);
2263 vex_printf(") -> ");
2264 ppIRType (t_dst);
2265 vex_printf("\narg tys are (");
2266 ppIRType(ttarg1);
2267 vex_printf(",");
2268 ppIRType(ttarg2);
2269 vex_printf(",");
2270 ppIRType(ttarg3);
2271 vex_printf(")\n");
2272 sanityCheckFail(bb,stmt,
2273 "Iex.Triop: arg tys don't match op tys\n"
2274 "... additional details precede BB printout\n");
2275 }
2276 break;
2277 }
sewardj6d2638e2004-07-15 09:38:27 +00002278 case Iex_Binop: {
2279 IRType ttarg1, ttarg2;
sewardj6efd4a12004-07-15 03:54:23 +00002280 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
2281 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
sewardj40c80262006-02-08 19:30:46 +00002282 typeOfPrimop(expr->Iex.Binop.op,
2283 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardjb183b852006-02-03 16:08:03 +00002284 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
sewardj40c80262006-02-08 19:30:46 +00002285 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) {
sewardj8f3debf2004-09-08 23:42:23 +00002286 vex_printf(" op name: " );
2287 ppIROp(expr->Iex.Binop.op);
2288 vex_printf("\n");
2289 sanityCheckFail(bb,stmt,
2290 "Iex.Binop: wrong arity op\n"
2291 "... name of op precedes BB printout\n");
2292 }
sewardj6d2638e2004-07-15 09:38:27 +00002293 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
2294 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
2295 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
2296 vex_printf(" op name: ");
2297 ppIROp(expr->Iex.Binop.op);
2298 vex_printf("\n");
2299 vex_printf(" op type is (");
2300 ppIRType(t_arg1);
2301 vex_printf(",");
2302 ppIRType(t_arg2);
2303 vex_printf(") -> ");
2304 ppIRType (t_dst);
2305 vex_printf("\narg tys are (");
2306 ppIRType(ttarg1);
2307 vex_printf(",");
2308 ppIRType(ttarg2);
2309 vex_printf(")\n");
2310 sanityCheckFail(bb,stmt,
2311 "Iex.Binop: arg tys don't match op tys\n"
2312 "... additional details precede BB printout\n");
sewardj695cff92004-10-13 14:50:14 +00002313 }
sewardj6efd4a12004-07-15 03:54:23 +00002314 break;
sewardj6d2638e2004-07-15 09:38:27 +00002315 }
sewardj6efd4a12004-07-15 03:54:23 +00002316 case Iex_Unop:
2317 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
sewardj40c80262006-02-08 19:30:46 +00002318 typeOfPrimop(expr->Iex.Binop.op,
2319 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
sewardjb183b852006-02-03 16:08:03 +00002320 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
sewardj40c80262006-02-08 19:30:46 +00002321 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
sewardj6efd4a12004-07-15 03:54:23 +00002322 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
2323 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
2324 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
2325 break;
sewardjaf1ceca2005-06-30 23:31:27 +00002326 case Iex_Load:
2327 tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
2328 if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
2329 sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
2330 if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
2331 sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
sewardj6efd4a12004-07-15 03:54:23 +00002332 break;
2333 case Iex_CCall:
sewardjc13e2ed2004-10-31 21:44:54 +00002334 if (!saneIRCallee(expr->Iex.CCall.cee))
2335 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
sewardjcf787902004-11-03 09:08:33 +00002336 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
sewardjc13e2ed2004-10-31 21:44:54 +00002337 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
sewardj43c56462004-11-06 12:17:57 +00002338 for (i = 0; expr->Iex.CCall.args[i]; i++) {
2339 if (i >= 32)
2340 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
sewardj6efd4a12004-07-15 03:54:23 +00002341 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
sewardj43c56462004-11-06 12:17:57 +00002342 }
sewardjba999312004-11-15 15:21:17 +00002343 if (expr->Iex.CCall.retty == Ity_I1)
2344 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00002345 for (i = 0; expr->Iex.CCall.args[i]; i++)
sewardjba999312004-11-15 15:21:17 +00002346 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
2347 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00002348 break;
2349 case Iex_Const:
sewardj49bfe672004-11-15 15:46:26 +00002350 if (!saneIRConst(expr->Iex.Const.con))
2351 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
sewardj6efd4a12004-07-15 03:54:23 +00002352 break;
sewardj4042c7e2004-07-18 01:28:30 +00002353 case Iex_Mux0X:
2354 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
2355 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
2356 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
2357 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
2358 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
2359 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
2360 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
2361 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
sewardjeeb9ef82004-07-15 12:39:03 +00002362 break;
2363 default:
sewardj6efd4a12004-07-15 03:54:23 +00002364 vpanic("tcExpr");
2365 }
2366}
2367
2368
2369static
2370void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
2371{
sewardj17442fe2004-09-20 14:54:28 +00002372 Int i;
2373 IRDirty* d;
sewardj6efd4a12004-07-15 03:54:23 +00002374 IRTypeEnv* tyenv = bb->tyenv;
2375 switch (stmt->tag) {
sewardjf1689312005-03-16 18:19:10 +00002376 case Ist_IMark:
2377 /* Somewhat heuristic, but rule out totally implausible
2378 instruction sizes. */
2379 if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20)
2380 sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible");
2381 break;
sewardj5a9ffab2005-05-12 17:55:01 +00002382 case Ist_AbiHint:
2383 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
2384 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
2385 "not :: guest word type");
2386 break;
sewardj6efd4a12004-07-15 03:54:23 +00002387 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00002388 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
sewardjba999312004-11-15 15:21:17 +00002389 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
2390 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
sewardj2d3f77c2004-09-22 23:49:09 +00002391 break;
sewardjd1725d12004-08-12 20:46:53 +00002392 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +00002393 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
sewardjeeac8412004-11-02 00:26:55 +00002394 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
sewardjba999312004-11-15 15:21:17 +00002395 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
2396 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
sewardj6d076362004-09-23 11:06:17 +00002397 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data)
2398 != stmt->Ist.PutI.descr->elemTy)
2399 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
sewardjeeac8412004-11-02 00:26:55 +00002400 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
2401 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00002402 if (!saneIRArray(stmt->Ist.PutI.descr))
2403 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
2404 break;
sewardj6efd4a12004-07-15 03:54:23 +00002405 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00002406 tcExpr( bb, stmt, stmt->Ist.Tmp.data, gWordTy );
sewardj17442fe2004-09-20 14:54:28 +00002407 if (typeOfIRTemp(tyenv, stmt->Ist.Tmp.tmp)
sewardj6d076362004-09-23 11:06:17 +00002408 != typeOfIRExpr(tyenv, stmt->Ist.Tmp.data))
sewardj6d2638e2004-07-15 09:38:27 +00002409 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
sewardj6efd4a12004-07-15 03:54:23 +00002410 break;
sewardjaf1ceca2005-06-30 23:31:27 +00002411 case Ist_Store:
2412 tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
2413 tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
2414 if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
2415 sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type");
2416 if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
2417 sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1");
2418 if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
2419 sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness");
sewardj6efd4a12004-07-15 03:54:23 +00002420 break;
sewardj17442fe2004-09-20 14:54:28 +00002421 case Ist_Dirty:
2422 /* Mostly check for various kinds of ill-formed dirty calls. */
2423 d = stmt->Ist.Dirty.details;
sewardj8ea867b2004-10-30 19:03:02 +00002424 if (d->cee == NULL) goto bad_dirty;
2425 if (!saneIRCallee(d->cee)) goto bad_dirty;
sewardjcf787902004-11-03 09:08:33 +00002426 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00002427 if (d->mFx == Ifx_None) {
2428 if (d->mAddr != NULL || d->mSize != 0)
2429 goto bad_dirty;
2430 } else {
2431 if (d->mAddr == NULL || d->mSize == 0)
2432 goto bad_dirty;
2433 }
2434 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
2435 goto bad_dirty;
sewardjc5fc7aa2004-10-27 23:00:55 +00002436 if (d->nFxState == 0 && d->needsBBP)
2437 goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00002438 for (i = 0; i < d->nFxState; i++) {
2439 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
2440 if (d->fxState[i].size <= 0) goto bad_dirty;
2441 }
2442 /* check types, minimally */
sewardjb8385d82004-11-02 01:34:15 +00002443 if (d->guard == NULL) goto bad_dirty;
sewardj49bfe672004-11-15 15:46:26 +00002444 tcExpr( bb, stmt, d->guard, gWordTy );
sewardjba999312004-11-15 15:21:17 +00002445 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
2446 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
sewardj92d168d2004-11-15 14:22:12 +00002447 if (d->tmp != IRTemp_INVALID
sewardjba999312004-11-15 15:21:17 +00002448 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
2449 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00002450 for (i = 0; d->args[i] != NULL; i++) {
sewardj43c56462004-11-06 12:17:57 +00002451 if (i >= 32)
2452 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
sewardjba999312004-11-15 15:21:17 +00002453 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
2454 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00002455 }
2456 break;
2457 bad_dirty:
2458 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
sewardjd2445f62005-03-21 00:15:53 +00002459 case Ist_NoOp:
sewardj3e838932005-01-07 12:09:15 +00002460 case Ist_MFence:
2461 break;
sewardj6efd4a12004-07-15 03:54:23 +00002462 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00002463 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
2464 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
2465 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
sewardj49bfe672004-11-15 15:46:26 +00002466 if (!saneIRConst(stmt->Ist.Exit.dst))
2467 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
sewardj6efd4a12004-07-15 03:54:23 +00002468 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
2469 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
2470 break;
2471 default:
2472 vpanic("tcStmt");
2473 }
2474}
2475
sewardjb9230752004-12-29 19:25:06 +00002476void sanityCheckIRBB ( IRBB* bb, HChar* caller,
2477 Bool require_flat, IRType guest_word_size )
sewardj35439212004-07-14 22:36:10 +00002478{
2479 Int i;
2480 IRStmt* stmt;
2481 Int n_temps = bb->tyenv->types_used;
2482 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
2483
sewardjb9230752004-12-29 19:25:06 +00002484 if (0)
2485 vex_printf("sanityCheck: %s\n", caller);
2486
sewardj35439212004-07-14 22:36:10 +00002487 vassert(guest_word_size == Ity_I32
sewardj695cff92004-10-13 14:50:14 +00002488 || guest_word_size == Ity_I64);
sewardj35439212004-07-14 22:36:10 +00002489
sewardjd7cb8532004-08-17 23:59:23 +00002490 if (bb->stmts_used < 0 || bb->stmts_size < 8
2491 || bb->stmts_used > bb->stmts_size)
2492 /* this BB is so strange we can't even print it */
2493 vpanic("sanityCheckIRBB: stmts array limits wierd");
2494
sewardj6d2638e2004-07-15 09:38:27 +00002495 /* Ensure each temp has a plausible type. */
2496 for (i = 0; i < n_temps; i++) {
sewardj17442fe2004-09-20 14:54:28 +00002497 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
sewardj496a58d2005-03-20 18:44:44 +00002498 if (!isPlausibleIRType(ty)) {
sewardj6d2638e2004-07-15 09:38:27 +00002499 vex_printf("Temp t%d declared with implausible type 0x%x\n",
2500 i, (UInt)ty);
2501 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
2502 }
2503 }
sewardj35439212004-07-14 22:36:10 +00002504
sewardjb9230752004-12-29 19:25:06 +00002505 /* Check for flatness, if required. */
2506 if (require_flat) {
2507 for (i = 0; i < bb->stmts_used; i++) {
2508 stmt = bb->stmts[i];
2509 if (!stmt)
sewardjd2445f62005-03-21 00:15:53 +00002510 sanityCheckFail(bb, stmt, "IRStmt: is NULL");
sewardjb9230752004-12-29 19:25:06 +00002511 if (!isFlatIRStmt(stmt))
2512 sanityCheckFail(bb, stmt, "IRStmt: is not flat");
2513 }
sewardj496a58d2005-03-20 18:44:44 +00002514 if (!isIRAtom(bb->next))
sewardjb9230752004-12-29 19:25:06 +00002515 sanityCheckFail(bb, NULL, "bb->next is not an atom");
2516 }
2517
sewardj35439212004-07-14 22:36:10 +00002518 /* Count the defs of each temp. Only one def is allowed.
2519 Also, check that each used temp has already been defd. */
sewardj6d2638e2004-07-15 09:38:27 +00002520
2521 for (i = 0; i < n_temps; i++)
2522 def_counts[i] = 0;
2523
sewardjd7cb8532004-08-17 23:59:23 +00002524 for (i = 0; i < bb->stmts_used; i++) {
2525 stmt = bb->stmts[i];
sewardj35439212004-07-14 22:36:10 +00002526 useBeforeDef_Stmt(bb,stmt,def_counts);
sewardj17442fe2004-09-20 14:54:28 +00002527
sewardj35439212004-07-14 22:36:10 +00002528 if (stmt->tag == Ist_Tmp) {
2529 if (stmt->Ist.Tmp.tmp < 0 || stmt->Ist.Tmp.tmp >= n_temps)
sewardj17442fe2004-09-20 14:54:28 +00002530 sanityCheckFail(bb, stmt,
2531 "IRStmt.Tmp: destination tmp is out of range");
sewardj35439212004-07-14 22:36:10 +00002532 def_counts[stmt->Ist.Tmp.tmp]++;
2533 if (def_counts[stmt->Ist.Tmp.tmp] > 1)
sewardj17442fe2004-09-20 14:54:28 +00002534 sanityCheckFail(bb, stmt,
sewardjcf787902004-11-03 09:08:33 +00002535 "IRStmt.Tmp: destination tmp is assigned more than once");
sewardj17442fe2004-09-20 14:54:28 +00002536 }
2537 else
2538 if (stmt->tag == Ist_Dirty
sewardj92d168d2004-11-15 14:22:12 +00002539 && stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
sewardj17442fe2004-09-20 14:54:28 +00002540 IRDirty* d = stmt->Ist.Dirty.details;
2541 if (d->tmp < 0 || d->tmp >= n_temps)
2542 sanityCheckFail(bb, stmt,
2543 "IRStmt.Dirty: destination tmp is out of range");
2544 def_counts[d->tmp]++;
2545 if (def_counts[d->tmp] > 1)
2546 sanityCheckFail(bb, stmt,
2547 "IRStmt.Dirty: destination tmp is assigned more than once");
sewardj35439212004-07-14 22:36:10 +00002548 }
2549 }
2550
sewardj6efd4a12004-07-15 03:54:23 +00002551 /* Typecheck everything. */
sewardjd7cb8532004-08-17 23:59:23 +00002552 for (i = 0; i < bb->stmts_used; i++)
sewardj39e3f242004-08-18 16:54:52 +00002553 if (bb->stmts[i])
2554 tcStmt( bb, bb->stmts[i], guest_word_size );
sewardj6efd4a12004-07-15 03:54:23 +00002555 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
2556 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
sewardje539a402004-07-14 18:24:17 +00002557}
2558
sewardj4345f7a2004-09-22 19:49:27 +00002559/*---------------------------------------------------------------*/
2560/*--- Misc helper functions ---*/
2561/*---------------------------------------------------------------*/
2562
2563Bool eqIRConst ( IRConst* c1, IRConst* c2 )
2564{
2565 if (c1->tag != c2->tag)
2566 return False;
2567
2568 switch (c1->tag) {
sewardja98bf492005-02-07 01:39:17 +00002569 case Ico_U1: return toBool( (1 & c1->Ico.U1) == (1 & c2->Ico.U1) );
2570 case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 );
2571 case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 );
2572 case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 );
2573 case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 );
2574 case Ico_F64: return toBool( c1->Ico.F64 == c2->Ico.F64 );
sewardj4345f7a2004-09-22 19:49:27 +00002575 default: vpanic("eqIRConst");
2576 }
2577}
2578
sewardje98dcf22004-10-04 09:15:11 +00002579Bool eqIRArray ( IRArray* descr1, IRArray* descr2 )
2580{
sewardja98bf492005-02-07 01:39:17 +00002581 return toBool( descr1->base == descr2->base
2582 && descr1->elemTy == descr2->elemTy
2583 && descr1->nElems == descr2->nElems );
sewardje98dcf22004-10-04 09:15:11 +00002584}
2585
sewardj2d3f77c2004-09-22 23:49:09 +00002586Int sizeofIRType ( IRType ty )
2587{
2588 switch (ty) {
sewardjc9a43662004-11-30 18:51:59 +00002589 case Ity_I8: return 1;
2590 case Ity_I16: return 2;
2591 case Ity_I32: return 4;
2592 case Ity_I64: return 8;
2593 case Ity_F32: return 4;
2594 case Ity_F64: return 8;
2595 case Ity_V128: return 16;
sewardj2d3f77c2004-09-22 23:49:09 +00002596 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
2597 vpanic("sizeofIRType");
2598 }
2599}
2600
sewardj49651f42004-10-28 22:11:04 +00002601IRExpr* mkIRExpr_HWord ( HWord hw )
2602{
sewardjf9655262004-10-31 20:02:16 +00002603 vassert(sizeof(void*) == sizeof(HWord));
sewardj49651f42004-10-28 22:11:04 +00002604 if (sizeof(HWord) == 4)
2605 return IRExpr_Const(IRConst_U32((UInt)hw));
2606 if (sizeof(HWord) == 8)
sewardjf9655262004-10-31 20:02:16 +00002607 return IRExpr_Const(IRConst_U64((ULong)hw));
sewardj49651f42004-10-28 22:11:04 +00002608 vpanic("mkIRExpr_HWord");
2609}
sewardj6efd4a12004-07-15 03:54:23 +00002610
sewardj2d49b432005-02-01 00:37:06 +00002611IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002612 IRExpr** args )
2613{
2614 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00002615 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00002616 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00002617 d->args = args;
sewardjf9655262004-10-31 20:02:16 +00002618 return d;
2619}
2620
2621IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
sewardj2d49b432005-02-01 00:37:06 +00002622 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002623 IRExpr** args )
2624{
2625 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00002626 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00002627 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00002628 d->args = args;
2629 d->tmp = dst;
sewardjf9655262004-10-31 20:02:16 +00002630 return d;
2631}
2632
2633IRExpr* mkIRExprCCall ( IRType retty,
sewardj2d49b432005-02-01 00:37:06 +00002634 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002635 IRExpr** args )
2636{
2637 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
2638 retty, args );
2639}
2640
sewardj496a58d2005-03-20 18:44:44 +00002641Bool eqIRAtom ( IRExpr* a1, IRExpr* a2 )
2642{
2643 vassert(isIRAtom(a1));
2644 vassert(isIRAtom(a2));
2645 if (a1->tag == Iex_Tmp && a2->tag == Iex_Tmp)
2646 return toBool(a1->Iex.Tmp.tmp == a2->Iex.Tmp.tmp);
2647 if (a1->tag == Iex_Const && a2->tag == Iex_Const)
2648 return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
2649 return False;
2650}
2651
sewardje539a402004-07-14 18:24:17 +00002652/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +00002653/*--- end ir/irdefs.c ---*/
sewardj887a11a2004-07-05 17:26:47 +00002654/*---------------------------------------------------------------*/