blob: 1308c64e514f820edf1ec84cbcce2e0ee1e38f96 [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 ---*/
sewardjec6ad592004-06-20 12:26:53 +00005/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
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
13 Copyright (C) 2004 OpenWorks, LLP.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; Version 2 dated June 1991 of the
18 license.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
23 for damages. See the GNU General Public License for more details.
24
25 Neither the names of the U.S. Department of Energy nor the
26 University of California nor the names of its contributors may be
27 used to endorse or promote products derived from this software
28 without prior written permission.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 USA.
34*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex_basictypes.h"
37#include "libvex_ir.h"
38#include "libvex.h"
sewardjec6ad592004-06-20 12:26:53 +000039
sewardjc0ee2ed2004-07-27 10:29:41 +000040#include "main/vex_util.h"
41
sewardjec6ad592004-06-20 12:26:53 +000042
43/*---------------------------------------------------------------*/
44/*--- Printing the IR ---*/
45/*---------------------------------------------------------------*/
46
sewardj35421a32004-07-05 13:12:34 +000047void ppIRType ( IRType ty )
sewardjec6ad592004-06-20 12:26:53 +000048{
sewardje3d0d2e2004-06-27 10:42:44 +000049 switch (ty) {
sewardj6efd4a12004-07-15 03:54:23 +000050 case Ity_INVALID: vex_printf("Ity_INVALID"); break;
sewardjba999312004-11-15 15:21:17 +000051 case Ity_I1: vex_printf( "I1"); break;
sewardj6efd4a12004-07-15 03:54:23 +000052 case Ity_I8: vex_printf( "I8"); break;
53 case Ity_I16: vex_printf( "I16"); break;
54 case Ity_I32: vex_printf( "I32"); break;
55 case Ity_I64: vex_printf( "I64"); break;
sewardjd1725d12004-08-12 20:46:53 +000056 case Ity_F32: vex_printf( "F32"); break;
57 case Ity_F64: vex_printf( "F64"); break;
sewardjc9a43662004-11-30 18:51:59 +000058 case Ity_V128: vex_printf( "V128"); break;
sewardj6d2638e2004-07-15 09:38:27 +000059 default: vex_printf("ty = 0x%x\n", (Int)ty);
60 vpanic("ppIRType");
sewardjec6ad592004-06-20 12:26:53 +000061 }
62}
63
sewardj35421a32004-07-05 13:12:34 +000064void ppIRConst ( IRConst* con )
sewardjec6ad592004-06-20 12:26:53 +000065{
sewardj2d3f77c2004-09-22 23:49:09 +000066 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +000067 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break;
sewardj2d3f77c2004-09-22 23:49:09 +000068 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break;
69 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break;
70 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break;
71 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break;
sewardj695cff92004-10-13 14:50:14 +000072 case Ico_F64: vex_printf( "F64{0x%llx}", *(ULong*)(&con->Ico.F64));
73 break;
sewardj2d3f77c2004-09-22 23:49:09 +000074 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
sewardj1e6ad742004-12-02 16:16:11 +000075 case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break;
sewardj2d3f77c2004-09-22 23:49:09 +000076 default: vpanic("ppIRConst");
77 }
78}
79
sewardj8ea867b2004-10-30 19:03:02 +000080void ppIRCallee ( IRCallee* ce )
81{
82 vex_printf("%s", ce->name);
sewardj77352542004-10-30 20:39:01 +000083 if (ce->regparms > 0)
sewardj43c56462004-11-06 12:17:57 +000084 vex_printf("[rp=%d]", ce->regparms);
85 if (ce->mcx_mask > 0)
86 vex_printf("[mcx=0x%x]", ce->mcx_mask);
sewardj8ea867b2004-10-30 19:03:02 +000087 vex_printf("{%p}", (void*)ce->addr);
88}
89
sewardj2d3f77c2004-09-22 23:49:09 +000090void ppIRArray ( IRArray* arr )
91{
sewardj0bfea7f2004-10-04 07:15:48 +000092 vex_printf("(%d:%dx", arr->base, arr->nElems);
sewardj2d3f77c2004-09-22 23:49:09 +000093 ppIRType(arr->elemTy);
sewardj0bfea7f2004-10-04 07:15:48 +000094 vex_printf(")");
sewardje3d0d2e2004-06-27 10:42:44 +000095}
96
sewardj35421a32004-07-05 13:12:34 +000097void ppIRTemp ( IRTemp tmp )
sewardje3d0d2e2004-06-27 10:42:44 +000098{
sewardj92d168d2004-11-15 14:22:12 +000099 if (tmp == IRTemp_INVALID)
100 vex_printf("IRTemp_INVALID");
sewardjfbcaf332004-07-08 01:46:01 +0000101 else
sewardj41f43bc2004-07-08 14:23:22 +0000102 vex_printf( "t%d", (Int)tmp);
sewardje3d0d2e2004-06-27 10:42:44 +0000103}
104
sewardj35421a32004-07-05 13:12:34 +0000105void ppIROp ( IROp op )
sewardje3d0d2e2004-06-27 10:42:44 +0000106{
sewardj41f43bc2004-07-08 14:23:22 +0000107 Char* str;
108 IROp base;
109 switch (op) {
110 case Iop_Add8 ... Iop_Add64:
111 str = "Add"; base = Iop_Add8; break;
112 case Iop_Sub8 ... Iop_Sub64:
113 str = "Sub"; base = Iop_Sub8; break;
114 case Iop_Mul8 ... Iop_Mul64:
115 str = "Mul"; base = Iop_Mul8; break;
116 case Iop_Or8 ... Iop_Or64:
117 str = "Or"; base = Iop_Or8; break;
118 case Iop_And8 ... Iop_And64:
119 str = "And"; base = Iop_And8; break;
120 case Iop_Xor8 ... Iop_Xor64:
121 str = "Xor"; base = Iop_Xor8; break;
122 case Iop_Shl8 ... Iop_Shl64:
123 str = "Shl"; base = Iop_Shl8; break;
124 case Iop_Shr8 ... Iop_Shr64:
125 str = "Shr"; base = Iop_Shr8; break;
126 case Iop_Sar8 ... Iop_Sar64:
127 str = "Sar"; base = Iop_Sar8; break;
sewardje90ad6a2004-07-10 19:02:10 +0000128 case Iop_CmpEQ8 ... Iop_CmpEQ64:
129 str = "CmpEQ"; base = Iop_CmpEQ8; break;
130 case Iop_CmpNE8 ... Iop_CmpNE64:
131 str = "CmpNE"; base = Iop_CmpNE8; break;
sewardj41f43bc2004-07-08 14:23:22 +0000132 case Iop_Not8 ... Iop_Not64:
133 str = "Not"; base = Iop_Not8; break;
134 /* other cases must explicitly "return;" */
sewardj9690d922004-07-14 01:39:17 +0000135 case Iop_8Uto16: vex_printf("8Uto16"); return;
136 case Iop_8Uto32: vex_printf("8Uto32"); return;
137 case Iop_16Uto32: vex_printf("16Uto32"); return;
138 case Iop_8Sto16: vex_printf("8Sto16"); return;
139 case Iop_8Sto32: vex_printf("8Sto32"); return;
140 case Iop_16Sto32: vex_printf("16Sto32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000141 case Iop_32Sto64: vex_printf("32Sto64"); return;
sewardje5427e82004-09-11 19:43:51 +0000142 case Iop_32Uto64: vex_printf("32Uto64"); return;
sewardja2384712004-07-29 14:36:40 +0000143 case Iop_32to8: vex_printf("32to8"); return;
sewardj6e797c52004-10-13 15:20:17 +0000144
145 case Iop_Not1: vex_printf("Not1"); return;
sewardj9690d922004-07-14 01:39:17 +0000146 case Iop_32to1: vex_printf("32to1"); return;
147 case Iop_1Uto8: vex_printf("1Uto8"); return;
sewardj84ff0652004-08-23 16:16:08 +0000148 case Iop_1Uto32: vex_printf("1Uto32"); return;
sewardjfd332772004-11-09 16:01:40 +0000149 case Iop_1Sto8: vex_printf("1Sto8"); return;
sewardj8eda6302004-11-05 01:55:46 +0000150 case Iop_1Sto16: vex_printf("1Sto16"); return;
sewardj415d9352004-11-04 15:20:15 +0000151 case Iop_1Sto32: vex_printf("1Sto32"); return;
sewardjb5874aa2004-11-04 16:57:50 +0000152 case Iop_1Sto64: vex_printf("1Sto64"); return;
sewardj9690d922004-07-14 01:39:17 +0000153
154 case Iop_MullS8: vex_printf("MullS8"); return;
155 case Iop_MullS16: vex_printf("MullS16"); return;
156 case Iop_MullS32: vex_printf("MullS32"); return;
157 case Iop_MullU8: vex_printf("MullU8"); return;
158 case Iop_MullU16: vex_printf("MullU16"); return;
159 case Iop_MullU32: vex_printf("MullU32"); return;
160
sewardjce646f22004-08-31 23:55:54 +0000161 case Iop_Clz32: vex_printf("Clz32"); return;
162 case Iop_Ctz32: vex_printf("Ctz32"); return;
163
sewardj84ff0652004-08-23 16:16:08 +0000164 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
165 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
166 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
167 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
168
sewardj9690d922004-07-14 01:39:17 +0000169 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
170 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
171
sewardjb81f8b32004-07-30 10:17:50 +0000172 case Iop_16HIto8: vex_printf("16HIto8"); return;
173 case Iop_16to8: vex_printf("16to8"); return;
174 case Iop_8HLto16: vex_printf("8HLto16"); return;
175
sewardj8c7f1ab2004-07-29 20:31:09 +0000176 case Iop_32HIto16: vex_printf("32HIto16"); return;
177 case Iop_32to16: vex_printf("32to16"); return;
178 case Iop_16HLto32: vex_printf("16HLto32"); return;
179
sewardj9690d922004-07-14 01:39:17 +0000180 case Iop_64HIto32: vex_printf("64HIto32"); return;
sewardj8c7f1ab2004-07-29 20:31:09 +0000181 case Iop_64to32: vex_printf("64to32"); return;
sewardj9690d922004-07-14 01:39:17 +0000182 case Iop_32HLto64: vex_printf("32HLto64"); return;
183
sewardjcfded9a2004-09-09 11:44:16 +0000184 case Iop_AddF64: vex_printf("AddF64"); return;
185 case Iop_SubF64: vex_printf("SubF64"); return;
186 case Iop_MulF64: vex_printf("MulF64"); return;
187 case Iop_DivF64: vex_printf("DivF64"); return;
sewardj46de4072004-09-11 19:23:24 +0000188
sewardj442d0be2004-10-15 22:57:13 +0000189 case Iop_ScaleF64: vex_printf("ScaleF64"); return;
190 case Iop_AtanF64: vex_printf("AtanF64"); return;
191 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return;
192 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return;
193 case Iop_PRemF64: vex_printf("PRemF64"); return;
194 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return;
195 case Iop_PRem1F64: vex_printf("PRem1F64"); return;
196 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
197 case Iop_NegF64: vex_printf("NegF64"); return;
198 case Iop_SqrtF64: vex_printf("SqrtF64"); return;
sewardj46de4072004-09-11 19:23:24 +0000199
sewardj883b00b2004-09-11 09:30:24 +0000200 case Iop_AbsF64: vex_printf("AbsF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000201 case Iop_SinF64: vex_printf("SinF64"); return;
202 case Iop_CosF64: vex_printf("CosF64"); return;
sewardj99016a72004-10-15 22:09:17 +0000203 case Iop_TanF64: vex_printf("TanF64"); return;
sewardj06c32a02004-09-12 12:07:34 +0000204 case Iop_2xm1F64: vex_printf("2xm1F64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000205
sewardj46de4072004-09-11 19:23:24 +0000206 case Iop_CmpF64: vex_printf("CmpF64"); return;
207
sewardj3bca9062004-12-04 14:36:09 +0000208 case Iop_F64toI16: vex_printf("F64toI16"); return;
209 case Iop_F64toI32: vex_printf("F64toI32"); return;
210 case Iop_F64toI64: vex_printf("F64toI64"); return;
211
212 case Iop_I16toF64: vex_printf("I16toF64"); return;
sewardj89cd0932004-09-08 18:23:25 +0000213 case Iop_I32toF64: vex_printf("I32toF64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000214 case Iop_I64toF64: vex_printf("I64toF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000215
sewardj89cd0932004-09-08 18:23:25 +0000216 case Iop_F32toF64: vex_printf("F32toF64"); return;
217 case Iop_F64toF32: vex_printf("F64toF32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000218
sewardj3bca9062004-12-04 14:36:09 +0000219 case Iop_RoundF64: vex_printf("RoundF64"); return;
220
sewardj17442fe2004-09-20 14:54:28 +0000221 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
222 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
sewardjfd226452004-12-07 19:02:18 +0000223 case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return;
224 case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
sewardj17442fe2004-09-20 14:54:28 +0000225
sewardj1e6ad742004-12-02 16:16:11 +0000226 case Iop_Add32Fx4: vex_printf("Add32Fx4"); return;
227 case Iop_Add32F0x4: vex_printf("Add32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000228 case Iop_Add64Fx2: vex_printf("Add64Fx2"); return;
229 case Iop_Add64F0x2: vex_printf("Add64F0x2"); return;
sewardj1e6ad742004-12-02 16:16:11 +0000230
sewardj176a59c2004-12-03 20:08:31 +0000231 case Iop_Div32Fx4: vex_printf("Div32Fx4"); return;
232 case Iop_Div32F0x4: vex_printf("Div32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000233 case Iop_Div64Fx2: vex_printf("Div64Fx2"); return;
234 case Iop_Div64F0x2: vex_printf("Div64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000235
236 case Iop_Max32Fx4: vex_printf("Max32Fx4"); return;
237 case Iop_Max32F0x4: vex_printf("Max32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000238 case Iop_Max64Fx2: vex_printf("Max64Fx2"); return;
239 case Iop_Max64F0x2: vex_printf("Max64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000240
241 case Iop_Min32Fx4: vex_printf("Min32Fx4"); return;
242 case Iop_Min32F0x4: vex_printf("Min32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000243 case Iop_Min64Fx2: vex_printf("Min64Fx2"); return;
244 case Iop_Min64F0x2: vex_printf("Min64F0x2"); return;
sewardj176a59c2004-12-03 20:08:31 +0000245
sewardj9636b442004-12-04 01:38:37 +0000246 case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return;
247 case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000248 case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return;
249 case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return;
sewardj9636b442004-12-04 01:38:37 +0000250
sewardj0bd7ce62004-12-05 02:47:40 +0000251 case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return;
252 case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000253 case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return;
254 case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return;
sewardj0bd7ce62004-12-05 02:47:40 +0000255
sewardjc1e7dfc2004-12-05 19:29:45 +0000256 case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return;
257 case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000258 case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return;
259 case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000260
sewardj636ad762004-12-07 11:16:04 +0000261 case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return;
262 case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return;
263 case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return;
264 case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000265
266 case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return;
267 case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000268 case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return;
269 case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return;
sewardjc1e7dfc2004-12-05 19:29:45 +0000270
sewardj1e6ad742004-12-02 16:16:11 +0000271 case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return;
272 case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return;
273 case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return;
274 case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return;
sewardj636ad762004-12-07 11:16:04 +0000275 case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return;
276 case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return;
277 case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return;
278 case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return;
sewardj1e6ad742004-12-02 16:16:11 +0000279
280 case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return;
281 case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return;
282 case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return;
283 case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return;
sewardj636ad762004-12-07 11:16:04 +0000284 case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return;
285 case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return;
286 case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return;
287 case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return;
sewardjc9a43662004-11-30 18:51:59 +0000288
289 case Iop_64HLto128: vex_printf("64HLto128"); return;
290 case Iop_128to64: vex_printf("128to64"); return;
291 case Iop_128HIto64: vex_printf("128HIto64"); return;
292
sewardj129b3d92004-12-05 15:42:05 +0000293 case Iop_32Uto128: vex_printf("32Uto128"); return;
sewardj636ad762004-12-07 11:16:04 +0000294 case Iop_64Uto128: vex_printf("64Uto128"); return;
sewardj129b3d92004-12-05 15:42:05 +0000295 case Iop_Set128lo32: vex_printf("Set128lo32"); return;
sewardj008754b2004-12-08 14:37:10 +0000296 case Iop_Set128lo64: vex_printf("Set128lo64"); return;
sewardj129b3d92004-12-05 15:42:05 +0000297
sewardj164f9272004-12-09 00:39:32 +0000298 case Iop_And128: vex_printf("And128"); return;
299 case Iop_Or128: vex_printf("Or128"); return;
300 case Iop_Xor128: vex_printf("Xor128"); return;
301
302 case Iop_Add8x16: vex_printf("Add8x16"); return;
303 case Iop_Add16x8: vex_printf("Add16x8"); return;
304 case Iop_Add32x4: vex_printf("Add32x4"); return;
305 case Iop_Add64x2: vex_printf("Add64x2"); return;
306 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
307 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
308 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
309 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
310
311 case Iop_Sub8x16: vex_printf("Sub8x16"); return;
312 case Iop_Sub16x8: vex_printf("Sub16x8"); return;
313 case Iop_Sub32x4: vex_printf("Sub32x4"); return;
314 case Iop_Sub64x2: vex_printf("Sub64x2"); return;
315 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
316 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
317 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
318 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
319
320 case Iop_Mul16x8: vex_printf("Mul16x8"); return;
321 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
322 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
323
324 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
325 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
326
327 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
328 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
329 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
330 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
331
332 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return;
333 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return;
334 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return;
335 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
336 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
337 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
338
339 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
340 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
341 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
342 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
343 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
344 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
345 case Iop_SarN16x8: vex_printf("SarN16x8"); return;
346 case Iop_SarN32x4: vex_printf("SarN32x4"); return;
347
348 case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return;
349 case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return;
350 case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return;
351
352 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
353 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
354 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
355 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
356 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
357 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
358 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
359 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
360
sewardjc9a43662004-11-30 18:51:59 +0000361 default: vpanic("ppIROp(1)");
sewardj41f43bc2004-07-08 14:23:22 +0000362 }
363
364 switch (op - base) {
365 case 0: vex_printf(str); vex_printf("8"); break;
366 case 1: vex_printf(str); vex_printf("16"); break;
367 case 2: vex_printf(str); vex_printf("32"); break;
368 case 3: vex_printf(str); vex_printf("64"); break;
369 default: vpanic("ppIROp(2)");
370 }
sewardje3d0d2e2004-06-27 10:42:44 +0000371}
372
sewardj35421a32004-07-05 13:12:34 +0000373void ppIRExpr ( IRExpr* e )
sewardje3d0d2e2004-06-27 10:42:44 +0000374{
sewardje87b4842004-07-10 12:23:30 +0000375 Int i;
sewardje3d0d2e2004-06-27 10:42:44 +0000376 switch (e->tag) {
sewardj443cd9d2004-07-18 23:06:45 +0000377 case Iex_Binder:
378 vex_printf("BIND-%d", e->Iex.Binder.binder);
379 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000380 case Iex_Get:
sewardjc9a43662004-11-30 18:51:59 +0000381 vex_printf( "GET:" );
sewardjfbcaf332004-07-08 01:46:01 +0000382 ppIRType(e->Iex.Get.ty);
sewardjc9a43662004-11-30 18:51:59 +0000383 vex_printf("(%d)", e->Iex.Get.offset);
sewardjec6ad592004-06-20 12:26:53 +0000384 break;
sewardjbb53f8c2004-08-14 11:50:01 +0000385 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +0000386 vex_printf( "GETI" );
387 ppIRArray(e->Iex.GetI.descr);
388 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000389 ppIRExpr(e->Iex.GetI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000390 vex_printf(",%d]", e->Iex.GetI.bias);
sewardjbb53f8c2004-08-14 11:50:01 +0000391 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000392 case Iex_Tmp:
sewardj35421a32004-07-05 13:12:34 +0000393 ppIRTemp(e->Iex.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +0000394 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000395 case Iex_Binop:
sewardj35421a32004-07-05 13:12:34 +0000396 ppIROp(e->Iex.Binop.op);
397 vex_printf( "(" );
398 ppIRExpr(e->Iex.Binop.arg1);
399 vex_printf( "," );
400 ppIRExpr(e->Iex.Binop.arg2);
401 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000402 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000403 case Iex_Unop:
sewardj35421a32004-07-05 13:12:34 +0000404 ppIROp(e->Iex.Unop.op);
405 vex_printf( "(" );
406 ppIRExpr(e->Iex.Unop.arg);
407 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000408 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000409 case Iex_LDle:
sewardje05c42c2004-07-08 20:25:10 +0000410 vex_printf( "LDle:" );
sewardj35421a32004-07-05 13:12:34 +0000411 ppIRType(e->Iex.LDle.ty);
sewardje05c42c2004-07-08 20:25:10 +0000412 vex_printf( "(" );
sewardj35421a32004-07-05 13:12:34 +0000413 ppIRExpr(e->Iex.LDle.addr);
414 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000415 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000416 case Iex_Const:
sewardj35421a32004-07-05 13:12:34 +0000417 ppIRConst(e->Iex.Const.con);
sewardjec6ad592004-06-20 12:26:53 +0000418 break;
sewardje87b4842004-07-10 12:23:30 +0000419 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000420 ppIRCallee(e->Iex.CCall.cee);
421 vex_printf("(");
sewardje87b4842004-07-10 12:23:30 +0000422 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
423 ppIRExpr(e->Iex.CCall.args[i]);
424 if (e->Iex.CCall.args[i+1] != NULL)
425 vex_printf(",");
426 }
427 vex_printf("):");
428 ppIRType(e->Iex.CCall.retty);
429 break;
sewardj4042c7e2004-07-18 01:28:30 +0000430 case Iex_Mux0X:
431 vex_printf("Mux0X(");
432 ppIRExpr(e->Iex.Mux0X.cond);
sewardjeeb9ef82004-07-15 12:39:03 +0000433 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000434 ppIRExpr(e->Iex.Mux0X.expr0);
sewardjeeb9ef82004-07-15 12:39:03 +0000435 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000436 ppIRExpr(e->Iex.Mux0X.exprX);
sewardjeeb9ef82004-07-15 12:39:03 +0000437 vex_printf(")");
438 break;
sewardjec6ad592004-06-20 12:26:53 +0000439 default:
sewardj35421a32004-07-05 13:12:34 +0000440 vpanic("ppIExpr");
sewardjec6ad592004-06-20 12:26:53 +0000441 }
442}
443
sewardj17442fe2004-09-20 14:54:28 +0000444void ppIREffect ( IREffect fx )
445{
446 switch (fx) {
447 case Ifx_None: vex_printf("noFX"); return;
448 case Ifx_Read: vex_printf("RdFX"); return;
449 case Ifx_Write: vex_printf("WrFX"); return;
450 case Ifx_Modify: vex_printf("MoFX"); return;
451 default: vpanic("ppIREffect");
452 }
453}
454
455void ppIRDirty ( IRDirty* d )
456{
457 Int i;
sewardj92d168d2004-11-15 14:22:12 +0000458 if (d->tmp != IRTemp_INVALID) {
sewardj4b861de2004-11-03 15:24:42 +0000459 ppIRTemp(d->tmp);
460 vex_printf(" = ");
461 }
sewardjb8385d82004-11-02 01:34:15 +0000462 vex_printf("DIRTY ");
463 ppIRExpr(d->guard);
sewardjc5fc7aa2004-10-27 23:00:55 +0000464 if (d->needsBBP)
465 vex_printf(" NeedsBBP");
sewardj17442fe2004-09-20 14:54:28 +0000466 if (d->mFx != Ifx_None) {
sewardj49651f42004-10-28 22:11:04 +0000467 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000468 ppIREffect(d->mFx);
469 vex_printf("-mem(");
470 ppIRExpr(d->mAddr);
sewardj49651f42004-10-28 22:11:04 +0000471 vex_printf(",%d)", d->mSize);
sewardj17442fe2004-09-20 14:54:28 +0000472 }
473 for (i = 0; i < d->nFxState; i++) {
sewardj49651f42004-10-28 22:11:04 +0000474 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000475 ppIREffect(d->fxState[i].fx);
sewardj49651f42004-10-28 22:11:04 +0000476 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
sewardj17442fe2004-09-20 14:54:28 +0000477 }
sewardjc5fc7aa2004-10-27 23:00:55 +0000478 vex_printf(" ::: ");
sewardj8ea867b2004-10-30 19:03:02 +0000479 ppIRCallee(d->cee);
480 vex_printf("(");
sewardj17442fe2004-09-20 14:54:28 +0000481 for (i = 0; d->args[i] != NULL; i++) {
482 ppIRExpr(d->args[i]);
483 if (d->args[i+1] != NULL) {
484 vex_printf(",");
485 }
486 }
487 vex_printf(")");
488}
489
sewardj893aada2004-11-29 19:57:54 +0000490void ppIRJumpKind ( IRJumpKind kind )
491{
492 switch (kind) {
493 case Ijk_Boring: vex_printf("Boring"); break;
494 case Ijk_Call: vex_printf("Call"); break;
495 case Ijk_Ret: vex_printf("Return"); break;
496 case Ijk_ClientReq: vex_printf("ClientReq"); break;
497 case Ijk_Syscall: vex_printf("Syscall"); break;
498 case Ijk_Yield: vex_printf("Yield"); break;
499 case Ijk_EmWarn: vex_printf("EmWarn"); break;
500 default: vpanic("ppIRJumpKind");
501 }
502}
503
sewardj35421a32004-07-05 13:12:34 +0000504void ppIRStmt ( IRStmt* s )
sewardjec6ad592004-06-20 12:26:53 +0000505{
sewardj17442fe2004-09-20 14:54:28 +0000506 switch (s->tag) {
507 case Ist_Put:
508 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
sewardj6d076362004-09-23 11:06:17 +0000509 ppIRExpr(s->Ist.Put.data);
sewardj17442fe2004-09-20 14:54:28 +0000510 break;
511 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +0000512 vex_printf( "PUTI" );
513 ppIRArray(s->Ist.PutI.descr);
514 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000515 ppIRExpr(s->Ist.PutI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000516 vex_printf(",%d] = ", s->Ist.PutI.bias);
517 ppIRExpr(s->Ist.PutI.data);
sewardj17442fe2004-09-20 14:54:28 +0000518 break;
519 case Ist_Tmp:
520 ppIRTemp(s->Ist.Tmp.tmp);
521 vex_printf( " = " );
sewardj6d076362004-09-23 11:06:17 +0000522 ppIRExpr(s->Ist.Tmp.data);
sewardj17442fe2004-09-20 14:54:28 +0000523 break;
524 case Ist_STle:
525 vex_printf( "STle(");
526 ppIRExpr(s->Ist.STle.addr);
527 vex_printf( ") = ");
528 ppIRExpr(s->Ist.STle.data);
529 break;
530 case Ist_Dirty:
531 ppIRDirty(s->Ist.Dirty.details);
532 break;
533 case Ist_Exit:
534 vex_printf( "if (" );
sewardj0276d4b2004-11-15 15:30:21 +0000535 ppIRExpr(s->Ist.Exit.guard);
sewardj893aada2004-11-29 19:57:54 +0000536 vex_printf( ") goto {");
537 ppIRJumpKind(s->Ist.Exit.jk);
538 vex_printf("} ");
sewardj17442fe2004-09-20 14:54:28 +0000539 ppIRConst(s->Ist.Exit.dst);
540 break;
541 default:
542 vpanic("ppIRStmt");
543 }
sewardjec6ad592004-06-20 12:26:53 +0000544}
545
sewardj35421a32004-07-05 13:12:34 +0000546void ppIRTypeEnv ( IRTypeEnv* env ) {
sewardjc97096c2004-06-30 09:28:04 +0000547 UInt i;
sewardje539a402004-07-14 18:24:17 +0000548 for (i = 0; i < env->types_used; i++) {
sewardjc97096c2004-06-30 09:28:04 +0000549 if (i % 8 == 0)
sewardj35421a32004-07-05 13:12:34 +0000550 vex_printf( " ");
sewardje539a402004-07-14 18:24:17 +0000551 ppIRTemp(i);
sewardj35421a32004-07-05 13:12:34 +0000552 vex_printf( ":");
sewardje539a402004-07-14 18:24:17 +0000553 ppIRType(env->types[i]);
sewardjc97096c2004-06-30 09:28:04 +0000554 if (i % 8 == 7)
sewardj35421a32004-07-05 13:12:34 +0000555 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000556 else
sewardj35421a32004-07-05 13:12:34 +0000557 vex_printf( " ");
sewardjc97096c2004-06-30 09:28:04 +0000558 }
sewardje539a402004-07-14 18:24:17 +0000559 if (env->types_used > 0 && env->types_used % 8 != 7)
sewardj35421a32004-07-05 13:12:34 +0000560 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000561}
562
sewardj35421a32004-07-05 13:12:34 +0000563void ppIRBB ( IRBB* bb )
sewardjec6ad592004-06-20 12:26:53 +0000564{
sewardjd7cb8532004-08-17 23:59:23 +0000565 Int i;
sewardj35439212004-07-14 22:36:10 +0000566 vex_printf("IRBB {\n");
sewardj35421a32004-07-05 13:12:34 +0000567 ppIRTypeEnv(bb->tyenv);
sewardj35439212004-07-14 22:36:10 +0000568 vex_printf("\n");
sewardjd7cb8532004-08-17 23:59:23 +0000569 for (i = 0; i < bb->stmts_used; i++) {
sewardj39e3f242004-08-18 16:54:52 +0000570 if (bb->stmts[i]) {
571 vex_printf( " ");
572 ppIRStmt(bb->stmts[i]);
573 }
sewardj35421a32004-07-05 13:12:34 +0000574 vex_printf( "\n");
sewardjec6ad592004-06-20 12:26:53 +0000575 }
sewardje539a402004-07-14 18:24:17 +0000576 vex_printf( " goto {");
577 ppIRJumpKind(bb->jumpkind);
578 vex_printf( "} ");
579 ppIRExpr( bb->next );
sewardj35439212004-07-14 22:36:10 +0000580 vex_printf( "\n}\n");
sewardjec6ad592004-06-20 12:26:53 +0000581}
582
583
584/*---------------------------------------------------------------*/
585/*--- Constructors ---*/
586/*---------------------------------------------------------------*/
587
sewardjc97096c2004-06-30 09:28:04 +0000588
589/* Constructors -- IRConst */
590
sewardjba999312004-11-15 15:21:17 +0000591IRConst* IRConst_U1 ( Bool bit )
sewardjb8e75862004-08-19 17:58:45 +0000592{
593 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjba999312004-11-15 15:21:17 +0000594 c->tag = Ico_U1;
595 c->Ico.U1 = bit;
sewardj4b861de2004-11-03 15:24:42 +0000596 /* call me paranoid; I don't care :-) */
597 vassert(bit == False || bit == True);
sewardjb8e75862004-08-19 17:58:45 +0000598 return c;
599}
sewardjc97096c2004-06-30 09:28:04 +0000600IRConst* IRConst_U8 ( UChar u8 )
601{
sewardj35421a32004-07-05 13:12:34 +0000602 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000603 c->tag = Ico_U8;
604 c->Ico.U8 = u8;
605 return c;
606}
607IRConst* IRConst_U16 ( UShort u16 )
608{
sewardj35421a32004-07-05 13:12:34 +0000609 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000610 c->tag = Ico_U16;
611 c->Ico.U16 = u16;
612 return c;
613}
614IRConst* IRConst_U32 ( UInt u32 )
615{
sewardj35421a32004-07-05 13:12:34 +0000616 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000617 c->tag = Ico_U32;
618 c->Ico.U32 = u32;
619 return c;
620}
621IRConst* IRConst_U64 ( ULong u64 )
622{
sewardj35421a32004-07-05 13:12:34 +0000623 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000624 c->tag = Ico_U64;
625 c->Ico.U64 = u64;
626 return c;
627}
sewardja58ea662004-08-15 03:12:41 +0000628IRConst* IRConst_F64 ( Double f64 )
629{
630 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
631 c->tag = Ico_F64;
632 c->Ico.F64 = f64;
633 return c;
634}
sewardj17442fe2004-09-20 14:54:28 +0000635IRConst* IRConst_F64i ( ULong f64i )
sewardj207557a2004-08-27 12:00:18 +0000636{
sewardj17442fe2004-09-20 14:54:28 +0000637 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
638 c->tag = Ico_F64i;
639 c->Ico.F64i = f64i;
sewardj207557a2004-08-27 12:00:18 +0000640 return c;
641}
sewardj1e6ad742004-12-02 16:16:11 +0000642IRConst* IRConst_V128 ( UShort con )
643{
644 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
645 c->tag = Ico_V128;
646 c->Ico.V128 = con;
647 return c;
648}
sewardjc97096c2004-06-30 09:28:04 +0000649
sewardj8ea867b2004-10-30 19:03:02 +0000650/* Constructors -- IRCallee */
651
sewardjf9655262004-10-31 20:02:16 +0000652IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr )
sewardj8ea867b2004-10-30 19:03:02 +0000653{
654 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
sewardj77352542004-10-30 20:39:01 +0000655 ce->regparms = regparms;
656 ce->name = name;
657 ce->addr = addr;
sewardj43c56462004-11-06 12:17:57 +0000658 ce->mcx_mask = 0;
sewardj77352542004-10-30 20:39:01 +0000659 vassert(regparms >= 0 && regparms <= 3);
sewardj8ea867b2004-10-30 19:03:02 +0000660 vassert(name != NULL);
661 vassert(addr != 0);
662 return ce;
663}
664
665
666/* Constructors -- IRArray */
sewardje3d0d2e2004-06-27 10:42:44 +0000667
sewardj2d3f77c2004-09-22 23:49:09 +0000668IRArray* mkIRArray ( Int base, IRType elemTy, Int nElems )
669{
670 IRArray* arr = LibVEX_Alloc(sizeof(IRArray));
671 arr->base = base;
672 arr->elemTy = elemTy;
673 arr->nElems = nElems;
674 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
sewardjba999312004-11-15 15:21:17 +0000675 vassert(!(arr->elemTy == Ity_I1));
sewardj2d3f77c2004-09-22 23:49:09 +0000676 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
677 return arr;
678}
679
680
681/* Constructors -- IRExpr */
682
sewardj443cd9d2004-07-18 23:06:45 +0000683IRExpr* IRExpr_Binder ( Int binder ) {
684 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
685 e->tag = Iex_Binder;
686 e->Iex.Binder.binder = binder;
687 return e;
688}
sewardjfbcaf332004-07-08 01:46:01 +0000689IRExpr* IRExpr_Get ( Int off, IRType ty ) {
sewardj35421a32004-07-05 13:12:34 +0000690 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000691 e->tag = Iex_Get;
692 e->Iex.Get.offset = off;
sewardjfbcaf332004-07-08 01:46:01 +0000693 e->Iex.Get.ty = ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000694 return e;
695}
sewardjeeac8412004-11-02 00:26:55 +0000696IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ) {
sewardj2d3f77c2004-09-22 23:49:09 +0000697 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
698 e->tag = Iex_GetI;
699 e->Iex.GetI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000700 e->Iex.GetI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000701 e->Iex.GetI.bias = bias;
sewardjd1725d12004-08-12 20:46:53 +0000702 return e;
703}
sewardjc97096c2004-06-30 09:28:04 +0000704IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
sewardj35421a32004-07-05 13:12:34 +0000705 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000706 e->tag = Iex_Tmp;
707 e->Iex.Tmp.tmp = tmp;
708 return e;
709}
sewardjc97096c2004-06-30 09:28:04 +0000710IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
sewardj35421a32004-07-05 13:12:34 +0000711 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000712 e->tag = Iex_Binop;
713 e->Iex.Binop.op = op;
714 e->Iex.Binop.arg1 = arg1;
715 e->Iex.Binop.arg2 = arg2;
716 return e;
717}
sewardjc97096c2004-06-30 09:28:04 +0000718IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
sewardj35421a32004-07-05 13:12:34 +0000719 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000720 e->tag = Iex_Unop;
721 e->Iex.Unop.op = op;
722 e->Iex.Unop.arg = arg;
723 return e;
724}
sewardjc97096c2004-06-30 09:28:04 +0000725IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
sewardj35421a32004-07-05 13:12:34 +0000726 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000727 e->tag = Iex_LDle;
728 e->Iex.LDle.ty = ty;
729 e->Iex.LDle.addr = addr;
730 return e;
731}
sewardjc97096c2004-06-30 09:28:04 +0000732IRExpr* IRExpr_Const ( IRConst* con ) {
sewardj35421a32004-07-05 13:12:34 +0000733 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000734 e->tag = Iex_Const;
735 e->Iex.Const.con = con;
736 return e;
sewardjec6ad592004-06-20 12:26:53 +0000737}
sewardj8ea867b2004-10-30 19:03:02 +0000738IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
sewardje87b4842004-07-10 12:23:30 +0000739 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
740 e->tag = Iex_CCall;
sewardj8ea867b2004-10-30 19:03:02 +0000741 e->Iex.CCall.cee = cee;
sewardje87b4842004-07-10 12:23:30 +0000742 e->Iex.CCall.retty = retty;
743 e->Iex.CCall.args = args;
744 return e;
745}
sewardj4042c7e2004-07-18 01:28:30 +0000746IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
sewardjeeb9ef82004-07-15 12:39:03 +0000747 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardj4042c7e2004-07-18 01:28:30 +0000748 e->tag = Iex_Mux0X;
749 e->Iex.Mux0X.cond = cond;
750 e->Iex.Mux0X.expr0 = expr0;
751 e->Iex.Mux0X.exprX = exprX;
sewardjeeb9ef82004-07-15 12:39:03 +0000752 return e;
753}
sewardjec6ad592004-06-20 12:26:53 +0000754
sewardjec6ad592004-06-20 12:26:53 +0000755
sewardjc5fc7aa2004-10-27 23:00:55 +0000756/* Constructors for NULL-terminated IRExpr expression vectors,
757 suitable for use as arg lists in clean/dirty helper calls. */
758
759IRExpr** mkIRExprVec_0 ( void ) {
760 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
761 vec[0] = NULL;
762 return vec;
763}
764IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
765 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
766 vec[0] = arg1;
767 vec[1] = NULL;
768 return vec;
769}
770IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
771 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
772 vec[0] = arg1;
773 vec[1] = arg2;
774 vec[2] = NULL;
775 return vec;
776}
sewardjf9655262004-10-31 20:02:16 +0000777IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
778 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
779 vec[0] = arg1;
780 vec[1] = arg2;
781 vec[2] = arg3;
782 vec[3] = NULL;
783 return vec;
784}
785IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2,
786 IRExpr* arg3, IRExpr* arg4 ) {
787 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
788 vec[0] = arg1;
789 vec[1] = arg2;
790 vec[2] = arg3;
791 vec[3] = arg4;
792 vec[4] = NULL;
793 return vec;
794}
sewardjf32c67d2004-11-08 13:10:44 +0000795IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2,
796 IRExpr* arg3, IRExpr* arg4, IRExpr* arg5 ) {
797 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
798 vec[0] = arg1;
799 vec[1] = arg2;
800 vec[2] = arg3;
801 vec[3] = arg4;
802 vec[4] = arg5;
803 vec[5] = NULL;
804 return vec;
805}
sewardjc5fc7aa2004-10-27 23:00:55 +0000806
807
sewardj17442fe2004-09-20 14:54:28 +0000808/* Constructors -- IRDirty */
809
sewardjc5fc7aa2004-10-27 23:00:55 +0000810IRDirty* emptyIRDirty ( void ) {
sewardj17442fe2004-09-20 14:54:28 +0000811 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
sewardj8ea867b2004-10-30 19:03:02 +0000812 d->cee = NULL;
sewardjb8385d82004-11-02 01:34:15 +0000813 d->guard = NULL;
sewardj17442fe2004-09-20 14:54:28 +0000814 d->args = NULL;
sewardj92d168d2004-11-15 14:22:12 +0000815 d->tmp = IRTemp_INVALID;
sewardj17442fe2004-09-20 14:54:28 +0000816 d->mFx = Ifx_None;
817 d->mAddr = NULL;
818 d->mSize = 0;
sewardjc5fc7aa2004-10-27 23:00:55 +0000819 d->needsBBP = False;
sewardj17442fe2004-09-20 14:54:28 +0000820 d->nFxState = 0;
821 return d;
822}
823
824
sewardjec6ad592004-06-20 12:26:53 +0000825/* Constructors -- IRStmt */
sewardje3d0d2e2004-06-27 10:42:44 +0000826
sewardj6d076362004-09-23 11:06:17 +0000827IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000828 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000829 s->tag = Ist_Put;
830 s->Ist.Put.offset = off;
sewardj6d076362004-09-23 11:06:17 +0000831 s->Ist.Put.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000832 return s;
sewardjec6ad592004-06-20 12:26:53 +0000833}
sewardjeeac8412004-11-02 00:26:55 +0000834IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix,
sewardj2d3f77c2004-09-22 23:49:09 +0000835 Int bias, IRExpr* data ) {
836 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
837 s->tag = Ist_PutI;
838 s->Ist.PutI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000839 s->Ist.PutI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000840 s->Ist.PutI.bias = bias;
841 s->Ist.PutI.data = data;
sewardjd1725d12004-08-12 20:46:53 +0000842 return s;
843}
sewardj6d076362004-09-23 11:06:17 +0000844IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000845 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000846 s->tag = Ist_Tmp;
847 s->Ist.Tmp.tmp = tmp;
sewardj6d076362004-09-23 11:06:17 +0000848 s->Ist.Tmp.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000849 return s;
sewardjec6ad592004-06-20 12:26:53 +0000850}
sewardj6d076362004-09-23 11:06:17 +0000851IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000852 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000853 s->tag = Ist_STle;
854 s->Ist.STle.addr = addr;
sewardj6d076362004-09-23 11:06:17 +0000855 s->Ist.STle.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000856 return s;
sewardjec6ad592004-06-20 12:26:53 +0000857}
sewardj17442fe2004-09-20 14:54:28 +0000858IRStmt* IRStmt_Dirty ( IRDirty* d )
859{
860 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
861 s->tag = Ist_Dirty;
862 s->Ist.Dirty.details = d;
863 return s;
864}
sewardj893aada2004-11-29 19:57:54 +0000865IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
sewardj0276d4b2004-11-15 15:30:21 +0000866 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
867 s->tag = Ist_Exit;
868 s->Ist.Exit.guard = guard;
sewardj893aada2004-11-29 19:57:54 +0000869 s->Ist.Exit.jk = jk;
sewardj0276d4b2004-11-15 15:30:21 +0000870 s->Ist.Exit.dst = dst;
sewardj64e1d652004-07-12 14:00:46 +0000871 return s;
872}
sewardje3d0d2e2004-06-27 10:42:44 +0000873
sewardj695cff92004-10-13 14:50:14 +0000874
875/* Constructors -- IRTypeEnv */
876
877IRTypeEnv* emptyIRTypeEnv ( void )
878{
879 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
880 env->types = LibVEX_Alloc(8 * sizeof(IRType));
881 env->types_size = 8;
882 env->types_used = 0;
883 return env;
884}
885
886
887/* Constructors -- IRBB */
sewardje3d0d2e2004-06-27 10:42:44 +0000888
sewardjd7cb8532004-08-17 23:59:23 +0000889IRBB* emptyIRBB ( void )
890{
891 IRBB* bb = LibVEX_Alloc(sizeof(IRBB));
892 bb->tyenv = emptyIRTypeEnv();
893 bb->stmts_used = 0;
894 bb->stmts_size = 8;
895 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
896 bb->next = NULL;
897 bb->jumpkind = Ijk_Boring;
sewardje3d0d2e2004-06-27 10:42:44 +0000898 return bb;
sewardjec6ad592004-06-20 12:26:53 +0000899}
900
sewardj695cff92004-10-13 14:50:14 +0000901
902/*---------------------------------------------------------------*/
903/*--- (Deep) copy constructors. These make complete copies ---*/
904/*--- the original, which can be modified without affecting ---*/
905/*--- the original. ---*/
906/*---------------------------------------------------------------*/
907
908/* Copying IR Expr vectors (for call args). */
909
910/* Shallow copy of an IRExpr vector */
911
912IRExpr** sopyIRExprVec ( IRExpr** vec )
sewardjd7cb8532004-08-17 23:59:23 +0000913{
sewardj695cff92004-10-13 14:50:14 +0000914 Int i;
915 IRExpr** newvec;
916 for (i = 0; vec[i]; i++)
917 ;
918 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
919 for (i = 0; vec[i]; i++)
920 newvec[i] = vec[i];
921 newvec[i] = NULL;
922 return newvec;
923}
924
925/* Deep copy of an IRExpr vector */
926
927IRExpr** dopyIRExprVec ( IRExpr** vec )
928{
929 Int i;
930 IRExpr** newvec = sopyIRExprVec( vec );
931 for (i = 0; newvec[i]; i++)
932 newvec[i] = dopyIRExpr(newvec[i]);
933 return newvec;
934}
935
936/* Deep copy constructors for all heap-allocated IR types follow. */
937
938IRConst* dopyIRConst ( IRConst* c )
939{
940 switch (c->tag) {
sewardjba999312004-11-15 15:21:17 +0000941 case Ico_U1: return IRConst_U1(c->Ico.U1);
sewardj695cff92004-10-13 14:50:14 +0000942 case Ico_U8: return IRConst_U8(c->Ico.U8);
943 case Ico_U16: return IRConst_U16(c->Ico.U16);
944 case Ico_U32: return IRConst_U32(c->Ico.U32);
945 case Ico_U64: return IRConst_U64(c->Ico.U64);
946 case Ico_F64: return IRConst_F64(c->Ico.F64);
947 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
sewardj1e6ad742004-12-02 16:16:11 +0000948 case Ico_V128: return IRConst_V128(c->Ico.V128);
sewardj695cff92004-10-13 14:50:14 +0000949 default: vpanic("dopyIRConst");
sewardjd7cb8532004-08-17 23:59:23 +0000950 }
sewardj695cff92004-10-13 14:50:14 +0000951}
952
sewardj8ea867b2004-10-30 19:03:02 +0000953IRCallee* dopyIRCallee ( IRCallee* ce )
954{
sewardj43c56462004-11-06 12:17:57 +0000955 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
956 ce2->mcx_mask = ce->mcx_mask;
957 return ce2;
sewardj8ea867b2004-10-30 19:03:02 +0000958}
959
sewardj695cff92004-10-13 14:50:14 +0000960IRArray* dopyIRArray ( IRArray* d )
961{
962 return mkIRArray(d->base, d->elemTy, d->nElems);
963}
964
965IRExpr* dopyIRExpr ( IRExpr* e )
966{
967 switch (e->tag) {
968 case Iex_Get:
969 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
970 case Iex_GetI:
971 return IRExpr_GetI(dopyIRArray(e->Iex.GetI.descr),
sewardjeeac8412004-11-02 00:26:55 +0000972 dopyIRExpr(e->Iex.GetI.ix),
sewardj695cff92004-10-13 14:50:14 +0000973 e->Iex.GetI.bias);
974 case Iex_Tmp:
975 return IRExpr_Tmp(e->Iex.Tmp.tmp);
976 case Iex_Binop:
977 return IRExpr_Binop(e->Iex.Binop.op,
978 dopyIRExpr(e->Iex.Binop.arg1),
979 dopyIRExpr(e->Iex.Binop.arg2));
980 case Iex_Unop:
981 return IRExpr_Unop(e->Iex.Unop.op,
982 dopyIRExpr(e->Iex.Unop.arg));
983 case Iex_LDle:
984 return IRExpr_LDle(e->Iex.LDle.ty,
985 dopyIRExpr(e->Iex.LDle.addr));
986 case Iex_Const:
987 return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
988 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000989 return IRExpr_CCall(dopyIRCallee(e->Iex.CCall.cee),
sewardj695cff92004-10-13 14:50:14 +0000990 e->Iex.CCall.retty,
991 dopyIRExprVec(e->Iex.CCall.args));
992
993 case Iex_Mux0X:
994 return IRExpr_Mux0X(dopyIRExpr(e->Iex.Mux0X.cond),
995 dopyIRExpr(e->Iex.Mux0X.expr0),
996 dopyIRExpr(e->Iex.Mux0X.exprX));
997 default:
998 vpanic("dopyIRExpr");
999 }
1000}
1001
1002IRDirty* dopyIRDirty ( IRDirty* d )
1003{
1004 Int i;
1005 IRDirty* d2 = emptyIRDirty();
sewardj8ea867b2004-10-30 19:03:02 +00001006 d2->cee = dopyIRCallee(d->cee);
sewardjb8385d82004-11-02 01:34:15 +00001007 d2->guard = dopyIRExpr(d->guard);
sewardj695cff92004-10-13 14:50:14 +00001008 d2->args = dopyIRExprVec(d->args);
1009 d2->tmp = d->tmp;
1010 d2->mFx = d->mFx;
1011 d2->mAddr = d->mAddr==NULL ? NULL : dopyIRExpr(d->mAddr);
1012 d2->mSize = d->mSize;
sewardjc5fc7aa2004-10-27 23:00:55 +00001013 d2->needsBBP = d->needsBBP;
sewardj695cff92004-10-13 14:50:14 +00001014 d2->nFxState = d->nFxState;
1015 for (i = 0; i < d2->nFxState; i++)
1016 d2->fxState[i] = d->fxState[i];
1017 return d2;
1018}
1019
1020IRStmt* dopyIRStmt ( IRStmt* s )
1021{
1022 switch (s->tag) {
1023 case Ist_Put:
1024 return IRStmt_Put(s->Ist.Put.offset,
1025 dopyIRExpr(s->Ist.Put.data));
1026 case Ist_PutI:
1027 return IRStmt_PutI(dopyIRArray(s->Ist.PutI.descr),
sewardjeeac8412004-11-02 00:26:55 +00001028 dopyIRExpr(s->Ist.PutI.ix),
sewardj695cff92004-10-13 14:50:14 +00001029 s->Ist.PutI.bias,
1030 dopyIRExpr(s->Ist.PutI.data));
1031 case Ist_Tmp:
1032 return IRStmt_Tmp(s->Ist.Tmp.tmp,
1033 dopyIRExpr(s->Ist.Tmp.data));
1034 case Ist_STle:
1035 return IRStmt_STle(dopyIRExpr(s->Ist.STle.addr),
1036 dopyIRExpr(s->Ist.STle.data));
1037 case Ist_Dirty:
1038 return IRStmt_Dirty(dopyIRDirty(s->Ist.Dirty.details));
1039 case Ist_Exit:
sewardj893aada2004-11-29 19:57:54 +00001040 return IRStmt_Exit(dopyIRExpr(s->Ist.Exit.guard),
1041 s->Ist.Exit.jk,
sewardj695cff92004-10-13 14:50:14 +00001042 dopyIRConst(s->Ist.Exit.dst));
1043 default:
1044 vpanic("dopyIRStmt");
1045 }
1046}
1047
1048IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* src )
1049{
1050 Int i;
1051 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
1052 dst->types_size = src->types_size;
1053 dst->types_used = src->types_used;
1054 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
1055 for (i = 0; i < src->types_used; i++)
1056 dst->types[i] = src->types[i];
1057 return dst;
1058}
1059
1060IRBB* dopyIRBB ( IRBB* bb )
1061{
1062 Int i;
1063 IRStmt** sts2;
1064 IRBB* bb2 = emptyIRBB();
1065 bb2->tyenv = dopyIRTypeEnv(bb->tyenv);
1066 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
1067 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
1068 for (i = 0; i < bb2->stmts_used; i++)
1069 sts2[i] = bb->stmts[i]==NULL ? NULL : dopyIRStmt(bb->stmts[i]);
1070 bb2->stmts = sts2;
1071 bb2->next = dopyIRExpr(bb->next);
1072 bb2->jumpkind = bb->jumpkind;
1073 return bb2;
sewardjd7cb8532004-08-17 23:59:23 +00001074}
1075
sewardjec6ad592004-06-20 12:26:53 +00001076
sewardjc97096c2004-06-30 09:28:04 +00001077/*---------------------------------------------------------------*/
sewardj6efd4a12004-07-15 03:54:23 +00001078/*--- Primop types ---*/
1079/*---------------------------------------------------------------*/
1080
1081static
1082void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
1083{
1084# define UNARY(_td,_ta1) \
1085 *t_dst = (_td); *t_arg1 = (_ta1); break
1086# define BINARY(_td,_ta1,_ta2) \
1087 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
1088# define COMPARISON(_ta) \
sewardjba999312004-11-15 15:21:17 +00001089 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
sewardj6efd4a12004-07-15 03:54:23 +00001090
1091 *t_dst = Ity_INVALID;
1092 *t_arg1 = Ity_INVALID;
1093 *t_arg2 = Ity_INVALID;
1094 switch (op) {
sewardj17442fe2004-09-20 14:54:28 +00001095 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
1096 case Iop_Or8: case Iop_And8: case Iop_Xor8:
sewardj6efd4a12004-07-15 03:54:23 +00001097 BINARY(Ity_I8,Ity_I8,Ity_I8);
1098
sewardj17442fe2004-09-20 14:54:28 +00001099 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
1100 case Iop_Or16: case Iop_And16: case Iop_Xor16:
sewardj6efd4a12004-07-15 03:54:23 +00001101 BINARY(Ity_I16,Ity_I16,Ity_I16);
1102
sewardj17442fe2004-09-20 14:54:28 +00001103 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
1104 case Iop_Or32: case Iop_And32: case Iop_Xor32:
sewardj6efd4a12004-07-15 03:54:23 +00001105 BINARY(Ity_I32,Ity_I32,Ity_I32);
1106
sewardj17442fe2004-09-20 14:54:28 +00001107 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
1108 case Iop_Or64: case Iop_And64: case Iop_Xor64:
sewardj6efd4a12004-07-15 03:54:23 +00001109 BINARY(Ity_I64,Ity_I64,Ity_I64);
1110
1111 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
1112 BINARY(Ity_I8,Ity_I8,Ity_I8);
1113 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
1114 BINARY(Ity_I16,Ity_I16,Ity_I8);
1115 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
1116 BINARY(Ity_I32,Ity_I32,Ity_I8);
1117 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
1118 BINARY(Ity_I64,Ity_I64,Ity_I8);
1119
sewardj86b133b2004-11-15 13:54:26 +00001120 case Iop_Not8: UNARY(Ity_I8,Ity_I8);
1121 case Iop_Not16: UNARY(Ity_I16,Ity_I16);
1122 case Iop_Not32: UNARY(Ity_I32,Ity_I32);
1123 case Iop_Not64: UNARY(Ity_I64,Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +00001124
1125 case Iop_CmpEQ8: case Iop_CmpNE8:
1126 COMPARISON(Ity_I8);
1127 case Iop_CmpEQ16: case Iop_CmpNE16:
1128 COMPARISON(Ity_I16);
1129 case Iop_CmpEQ32: case Iop_CmpNE32:
sewardj17442fe2004-09-20 14:54:28 +00001130 case Iop_CmpLT32S: case Iop_CmpLE32S:
1131 case Iop_CmpLT32U: case Iop_CmpLE32U:
sewardj6efd4a12004-07-15 03:54:23 +00001132 COMPARISON(Ity_I32);
1133 case Iop_CmpEQ64: case Iop_CmpNE64:
1134 COMPARISON(Ity_I64);
1135
sewardjb81f8b32004-07-30 10:17:50 +00001136 case Iop_MullU8: case Iop_MullS8:
1137 BINARY(Ity_I16,Ity_I8,Ity_I8);
1138 case Iop_MullU16: case Iop_MullS16:
1139 BINARY(Ity_I32,Ity_I16,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +00001140 case Iop_MullU32: case Iop_MullS32:
1141 BINARY(Ity_I64,Ity_I32,Ity_I32);
1142
sewardj17442fe2004-09-20 14:54:28 +00001143 case Iop_Clz32: case Iop_Ctz32:
sewardjce646f22004-08-31 23:55:54 +00001144 UNARY(Ity_I32,Ity_I32);
1145
sewardj17442fe2004-09-20 14:54:28 +00001146 case Iop_DivModU64to32: case Iop_DivModS64to32:
sewardj6d2638e2004-07-15 09:38:27 +00001147 BINARY(Ity_I64,Ity_I64,Ity_I32);
1148
sewardjb81f8b32004-07-30 10:17:50 +00001149 case Iop_16HIto8: case Iop_16to8:
1150 UNARY(Ity_I8,Ity_I16);
1151 case Iop_8HLto16:
1152 BINARY(Ity_I16,Ity_I8,Ity_I8);
1153
sewardj8c7f1ab2004-07-29 20:31:09 +00001154 case Iop_32HIto16: case Iop_32to16:
1155 UNARY(Ity_I16,Ity_I32);
1156 case Iop_16HLto32:
1157 BINARY(Ity_I32,Ity_I16,Ity_I16);
1158
1159 case Iop_64HIto32: case Iop_64to32:
sewardj6d2638e2004-07-15 09:38:27 +00001160 UNARY(Ity_I32, Ity_I64);
1161 case Iop_32HLto64:
1162 BINARY(Ity_I64,Ity_I32,Ity_I32);
1163
sewardjba999312004-11-15 15:21:17 +00001164 case Iop_Not1: UNARY(Ity_I1,Ity_I1);
1165 case Iop_1Uto8: UNARY(Ity_I8,Ity_I1);
1166 case Iop_1Sto8: UNARY(Ity_I8,Ity_I1);
1167 case Iop_1Sto16: UNARY(Ity_I16,Ity_I1);
1168 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I32,Ity_I1);
1169 case Iop_1Sto64: UNARY(Ity_I64,Ity_I1);
1170 case Iop_32to1: UNARY(Ity_I1,Ity_I32);
sewardj47341042004-09-19 11:55:46 +00001171
sewardj17442fe2004-09-20 14:54:28 +00001172 case Iop_8Uto32: case Iop_8Sto32:
1173 UNARY(Ity_I32,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001174
sewardj17442fe2004-09-20 14:54:28 +00001175 case Iop_8Uto16: case Iop_8Sto16:
1176 UNARY(Ity_I16,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001177
sewardj17442fe2004-09-20 14:54:28 +00001178 case Iop_16Uto32: case Iop_16Sto32:
1179 UNARY(Ity_I32,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +00001180
sewardj17442fe2004-09-20 14:54:28 +00001181 case Iop_32Sto64: case Iop_32Uto64:
1182 UNARY(Ity_I64,Ity_I32);
1183
1184 case Iop_32to8: UNARY(Ity_I8,Ity_I32);
1185
sewardj442d0be2004-10-15 22:57:13 +00001186 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
sewardj17442fe2004-09-20 14:54:28 +00001187 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
1188 case Iop_AddF64: case Iop_SubF64: case Iop_MulF64: case Iop_DivF64:
sewardja58ea662004-08-15 03:12:41 +00001189 BINARY(Ity_F64,Ity_F64,Ity_F64);
sewardj442d0be2004-10-15 22:57:13 +00001190 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
sewardjbdc7d212004-09-09 02:46:40 +00001191 case Iop_CmpF64:
1192 BINARY(Ity_I32,Ity_F64,Ity_F64);
sewardj883b00b2004-09-11 09:30:24 +00001193 case Iop_NegF64: case Iop_AbsF64: case Iop_SqrtF64:
sewardj99016a72004-10-15 22:09:17 +00001194 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: case Iop_2xm1F64:
sewardjcfded9a2004-09-09 11:44:16 +00001195 UNARY(Ity_F64,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001196
sewardj3bca9062004-12-04 14:36:09 +00001197 case Iop_ReinterpI64asF64: UNARY(Ity_F64, Ity_I64);
sewardj17442fe2004-09-20 14:54:28 +00001198 case Iop_ReinterpF64asI64: UNARY(Ity_I64, Ity_F64);
sewardjfd226452004-12-07 19:02:18 +00001199 case Iop_ReinterpI32asF32: UNARY(Ity_F32, Ity_I32);
1200 case Iop_ReinterpF32asI32: UNARY(Ity_I32, Ity_F32);
sewardj8f3debf2004-09-08 23:42:23 +00001201
sewardj3bca9062004-12-04 14:36:09 +00001202 case Iop_F64toI16: BINARY(Ity_I16, Ity_I32,Ity_F64);
1203 case Iop_F64toI32: BINARY(Ity_I32, Ity_I32,Ity_F64);
1204 case Iop_F64toI64: BINARY(Ity_I64, Ity_I32,Ity_F64);
1205
1206 case Iop_I16toF64: UNARY(Ity_F64, Ity_I16);
1207 case Iop_I32toF64: UNARY(Ity_F64, Ity_I32);
sewardj4cb918d2004-12-03 19:43:31 +00001208 case Iop_I64toF64: BINARY(Ity_F64, Ity_I32,Ity_I64);
1209
sewardj3bca9062004-12-04 14:36:09 +00001210 case Iop_F32toF64: UNARY(Ity_F64, Ity_F32);
1211 case Iop_F64toF32: BINARY(Ity_F32, Ity_I32,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001212
sewardj3bca9062004-12-04 14:36:09 +00001213 case Iop_RoundF64: BINARY(Ity_F64, Ity_I32,Ity_F64);
sewardjbb53f8c2004-08-14 11:50:01 +00001214
sewardjc9a43662004-11-30 18:51:59 +00001215 case Iop_64HLto128: BINARY(Ity_V128, Ity_I64,Ity_I64);
1216 case Iop_128to64: case Iop_128HIto64:
1217 UNARY(Ity_I64, Ity_V128);
1218
sewardj129b3d92004-12-05 15:42:05 +00001219 case Iop_32Uto128: UNARY(Ity_V128, Ity_I32);
sewardj636ad762004-12-07 11:16:04 +00001220 case Iop_64Uto128: UNARY(Ity_V128, Ity_I64);
sewardj129b3d92004-12-05 15:42:05 +00001221 case Iop_Set128lo32: BINARY(Ity_V128, Ity_V128,Ity_I32);
sewardj008754b2004-12-08 14:37:10 +00001222 case Iop_Set128lo64: BINARY(Ity_V128, Ity_V128,Ity_I64);
sewardj129b3d92004-12-05 15:42:05 +00001223
sewardj1e6ad742004-12-02 16:16:11 +00001224 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001225 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
sewardj1e6ad742004-12-02 16:16:11 +00001226 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001227 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
sewardj1e6ad742004-12-02 16:16:11 +00001228 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001229 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001230 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001231 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001232 case Iop_Add32Fx4: case Iop_Add32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001233 case Iop_Add64Fx2: case Iop_Add64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001234 case Iop_Div32Fx4: case Iop_Div32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001235 case Iop_Div64Fx2: case Iop_Div64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001236 case Iop_Max32Fx4: case Iop_Max32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001237 case Iop_Max64Fx2: case Iop_Max64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001238 case Iop_Min32Fx4: case Iop_Min32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001239 case Iop_Min64Fx2: case Iop_Min64F0x2:
sewardj9636b442004-12-04 01:38:37 +00001240 case Iop_Mul32Fx4: case Iop_Mul32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001241 case Iop_Mul64Fx2: case Iop_Mul64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001242 case Iop_Sub32Fx4: case Iop_Sub32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001243 case Iop_Sub64Fx2: case Iop_Sub64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001244 case Iop_And128: case Iop_Or128: case Iop_Xor128:
sewardj164f9272004-12-09 00:39:32 +00001245 case Iop_Add8x16: case Iop_Add16x8:
1246 case Iop_Add32x4: case Iop_Add64x2:
1247 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8:
1248 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8:
1249 case Iop_Sub8x16: case Iop_Sub16x8:
1250 case Iop_Sub32x4: case Iop_Sub64x2:
1251 case Iop_QSub8Ux16: case Iop_QSub16Ux8:
1252 case Iop_QSub8Sx16: case Iop_QSub16Sx8:
1253 case Iop_Mul16x8:
1254 case Iop_MulHi16Ux8:
1255 case Iop_MulHi16Sx8:
1256 case Iop_Avg8Ux16:
1257 case Iop_Avg16Ux8:
1258 case Iop_Max16Sx8:
1259 case Iop_Max8Ux16:
1260 case Iop_Min16Sx8:
1261 case Iop_Min8Ux16:
1262 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
1263 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
1264 case Iop_QNarrow16Ux8:
1265 case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4:
1266 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
1267 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
1268 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
1269 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
sewardjc9a43662004-11-30 18:51:59 +00001270 BINARY(Ity_V128, Ity_V128,Ity_V128);
1271
sewardj0bd7ce62004-12-05 02:47:40 +00001272 case Iop_Recip32Fx4: case Iop_Recip32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001273 case Iop_Recip64Fx2: case Iop_Recip64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001274 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001275 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001276 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001277 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2:
sewardj0bd7ce62004-12-05 02:47:40 +00001278 UNARY(Ity_V128, Ity_V128);
1279
sewardj164f9272004-12-09 00:39:32 +00001280 case Iop_ShlN16x8: case Iop_ShlN32x4: case Iop_ShlN64x2:
1281 case Iop_ShrN16x8: case Iop_ShrN32x4: case Iop_ShrN64x2:
1282 case Iop_SarN16x8: case Iop_SarN32x4:
1283 BINARY(Ity_V128, Ity_V128, Ity_I8);
1284
sewardj6efd4a12004-07-15 03:54:23 +00001285 default:
1286 ppIROp(op);
1287 vpanic("typeOfPrimop");
1288 }
1289# undef UNARY
1290# undef BINARY
1291# undef COMPARISON
1292}
1293
1294
1295/*---------------------------------------------------------------*/
sewardj695cff92004-10-13 14:50:14 +00001296/*--- Helper functions for the IR -- IR Basic Blocks ---*/
sewardjc97096c2004-06-30 09:28:04 +00001297/*---------------------------------------------------------------*/
1298
sewardj695cff92004-10-13 14:50:14 +00001299void addStmtToIRBB ( IRBB* bb, IRStmt* st )
sewardjd7cb8532004-08-17 23:59:23 +00001300{
1301 Int i;
sewardj695cff92004-10-13 14:50:14 +00001302 if (bb->stmts_used == bb->stmts_size) {
1303 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1304 for (i = 0; i < bb->stmts_size; i++)
1305 stmts2[i] = bb->stmts[i];
1306 bb->stmts = stmts2;
1307 bb->stmts_size *= 2;
1308 }
1309 vassert(bb->stmts_used < bb->stmts_size);
1310 bb->stmts[bb->stmts_used] = st;
1311 bb->stmts_used++;
sewardjd7cb8532004-08-17 23:59:23 +00001312}
1313
sewardj695cff92004-10-13 14:50:14 +00001314
1315/*---------------------------------------------------------------*/
1316/*--- Helper functions for the IR -- IR Type Environments ---*/
1317/*---------------------------------------------------------------*/
1318
sewardjd7cb8532004-08-17 23:59:23 +00001319/* Allocate a new IRTemp, given its type. */
sewardje3d0d2e2004-06-27 10:42:44 +00001320
sewardje539a402004-07-14 18:24:17 +00001321IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
sewardjc97096c2004-06-30 09:28:04 +00001322{
sewardj35421a32004-07-05 13:12:34 +00001323 vassert(env);
sewardje539a402004-07-14 18:24:17 +00001324 vassert(env->types_used >= 0);
1325 vassert(env->types_size >= 0);
1326 vassert(env->types_used <= env->types_size);
1327 if (env->types_used < env->types_size) {
1328 env->types[env->types_used] = ty;
1329 return env->types_used++;
sewardjc97096c2004-06-30 09:28:04 +00001330 } else {
1331 Int i;
sewardje539a402004-07-14 18:24:17 +00001332 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
1333 IRType* new_types
1334 = LibVEX_Alloc(new_size * sizeof(IRType));
1335 for (i = 0; i < env->types_used; i++)
1336 new_types[i] = env->types[i];
1337 env->types = new_types;
1338 env->types_size = new_size;
1339 return newIRTemp(env, ty);
sewardjc97096c2004-06-30 09:28:04 +00001340 }
1341}
1342
1343
sewardj17442fe2004-09-20 14:54:28 +00001344/*---------------------------------------------------------------*/
1345/*--- Helper functions for the IR -- finding types of exprs ---*/
1346/*---------------------------------------------------------------*/
1347
sewardjedeb4c42004-09-21 23:39:25 +00001348inline
sewardj17442fe2004-09-20 14:54:28 +00001349IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
sewardjc97096c2004-06-30 09:28:04 +00001350{
sewardje539a402004-07-14 18:24:17 +00001351 vassert(tmp >= 0);
1352 vassert(tmp < env->types_used);
1353 return env->types[tmp];
sewardjc97096c2004-06-30 09:28:04 +00001354}
1355
1356
sewardj6efd4a12004-07-15 03:54:23 +00001357IRType typeOfIRConst ( IRConst* con )
1358{
1359 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +00001360 case Ico_U1: return Ity_I1;
sewardj207557a2004-08-27 12:00:18 +00001361 case Ico_U8: return Ity_I8;
1362 case Ico_U16: return Ity_I16;
1363 case Ico_U32: return Ity_I32;
1364 case Ico_U64: return Ity_I64;
1365 case Ico_F64: return Ity_F64;
sewardj17442fe2004-09-20 14:54:28 +00001366 case Ico_F64i: return Ity_F64;
sewardj1e6ad742004-12-02 16:16:11 +00001367 case Ico_V128: return Ity_V128;
sewardj6efd4a12004-07-15 03:54:23 +00001368 default: vpanic("typeOfIRConst");
1369 }
1370}
1371
sewardjc97096c2004-06-30 09:28:04 +00001372IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
1373{
sewardj6efd4a12004-07-15 03:54:23 +00001374 IRType t_dst, t_arg1, t_arg2;
sewardjedeb4c42004-09-21 23:39:25 +00001375 start:
sewardjc97096c2004-06-30 09:28:04 +00001376 switch (e->tag) {
sewardje05c42c2004-07-08 20:25:10 +00001377 case Iex_LDle:
1378 return e->Iex.LDle.ty;
sewardjfbcaf332004-07-08 01:46:01 +00001379 case Iex_Get:
1380 return e->Iex.Get.ty;
sewardjbb53f8c2004-08-14 11:50:01 +00001381 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +00001382 return e->Iex.GetI.descr->elemTy;
sewardjc97096c2004-06-30 09:28:04 +00001383 case Iex_Tmp:
sewardj17442fe2004-09-20 14:54:28 +00001384 return typeOfIRTemp(tyenv, e->Iex.Tmp.tmp);
sewardjc97096c2004-06-30 09:28:04 +00001385 case Iex_Const:
sewardj695cff92004-10-13 14:50:14 +00001386 return typeOfIRConst(e->Iex.Const.con);
sewardjc97096c2004-06-30 09:28:04 +00001387 case Iex_Binop:
sewardj6efd4a12004-07-15 03:54:23 +00001388 typeOfPrimop(e->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1389 return t_dst;
1390 case Iex_Unop:
1391 typeOfPrimop(e->Iex.Unop.op, &t_dst, &t_arg1, &t_arg2);
1392 return t_dst;
1393 case Iex_CCall:
1394 return e->Iex.CCall.retty;
sewardj4042c7e2004-07-18 01:28:30 +00001395 case Iex_Mux0X:
sewardjedeb4c42004-09-21 23:39:25 +00001396 e = e->Iex.Mux0X.expr0;
1397 goto start;
1398 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
sewardj443cd9d2004-07-18 23:06:45 +00001399 case Iex_Binder:
1400 vpanic("typeOfIRExpr: Binder is not a valid expression");
sewardjc97096c2004-06-30 09:28:04 +00001401 default:
sewardj6efd4a12004-07-15 03:54:23 +00001402 ppIRExpr(e);
1403 vpanic("typeOfIRExpr");
sewardjc97096c2004-06-30 09:28:04 +00001404 }
sewardjc97096c2004-06-30 09:28:04 +00001405}
sewardj887a11a2004-07-05 17:26:47 +00001406
sewardj6d2638e2004-07-15 09:38:27 +00001407/* Is this any value actually in the enumeration 'IRType' ? */
1408Bool isPlausibleType ( IRType ty )
1409{
1410 switch (ty) {
sewardjba999312004-11-15 15:21:17 +00001411 case Ity_INVALID: case Ity_I1:
sewardj6d2638e2004-07-15 09:38:27 +00001412 case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64:
sewardjbb53f8c2004-08-14 11:50:01 +00001413 case Ity_F32: case Ity_F64:
sewardjc9a43662004-11-30 18:51:59 +00001414 case Ity_V128:
sewardj6d2638e2004-07-15 09:38:27 +00001415 return True;
1416 default:
1417 return False;
1418 }
1419}
1420
sewardj6efd4a12004-07-15 03:54:23 +00001421
sewardj887a11a2004-07-05 17:26:47 +00001422/*---------------------------------------------------------------*/
sewardjcf787902004-11-03 09:08:33 +00001423/*--- Sanity checking -- FLATNESS ---*/
1424/*---------------------------------------------------------------*/
1425
1426/* Check that the canonical flatness constraints hold on an
1427 IRStmt. The only place where any expression is allowed to be
1428 non-atomic is the RHS of IRStmt_Tmp. */
1429
1430/* Relies on:
1431 inline static Bool isAtom ( IRExpr* e ) {
1432 return e->tag == Iex_Tmp || e->tag == Iex_Const;
1433 }
1434*/
1435
1436Bool isFlatIRStmt ( IRStmt* st )
1437{
1438 Int i;
1439 IRExpr* e;
1440 IRDirty* di;
1441
1442 switch (st->tag) {
1443 case Ist_Put:
1444 return isAtom(st->Ist.Put.data);
1445 case Ist_PutI:
1446 return isAtom(st->Ist.PutI.ix) && isAtom(st->Ist.PutI.data);
1447 case Ist_Tmp:
1448 /* This is the only interesting case. The RHS can be any
1449 expression, *but* all its subexpressions *must* be
1450 atoms. */
1451 e = st->Ist.Tmp.data;
1452 switch (e->tag) {
1453 case Iex_Binder: return True;
1454 case Iex_Get: return True;
1455 case Iex_GetI: return isAtom(e->Iex.GetI.ix);
1456 case Iex_Tmp: return True;
1457 case Iex_Binop: return isAtom(e->Iex.Binop.arg1)
1458 && isAtom(e->Iex.Binop.arg2);
1459 case Iex_Unop: return isAtom(e->Iex.Unop.arg);
1460 case Iex_LDle: return isAtom(e->Iex.LDle.addr);
1461 case Iex_Const: return True;
1462 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
1463 if (!isAtom(e->Iex.CCall.args[i]))
1464 return False;
1465 return True;
1466 case Iex_Mux0X: return isAtom(e->Iex.Mux0X.cond)
1467 && isAtom(e->Iex.Mux0X.expr0)
1468 && isAtom(e->Iex.Mux0X.exprX);
1469 default: vpanic("isFlatIRStmt(e)");
1470 }
1471 /*notreached*/
1472 vassert(0);
1473 case Ist_STle:
1474 return isAtom(st->Ist.STle.addr) && isAtom(st->Ist.STle.data);
1475 case Ist_Dirty:
1476 di = st->Ist.Dirty.details;
1477 if (!isAtom(di->guard))
1478 return False;
1479 for (i = 0; di->args[i]; i++)
1480 if (!isAtom(di->args[i]))
1481 return False;
1482 if (di->mAddr && !isAtom(di->mAddr))
1483 return False;
1484 return True;
1485 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001486 return isAtom(st->Ist.Exit.guard);
sewardjcf787902004-11-03 09:08:33 +00001487 default:
1488 vpanic("isFlatIRStmt(st)");
1489 }
1490}
1491
1492
1493/*---------------------------------------------------------------*/
sewardje539a402004-07-14 18:24:17 +00001494/*--- Sanity checking ---*/
1495/*---------------------------------------------------------------*/
1496
1497/* Checks:
1498
1499 Everything is type-consistent. No ill-typed anything.
sewardj35439212004-07-14 22:36:10 +00001500 The target address at the end of the BB is a 32- or 64-
1501 bit expression, depending on the guest's word size.
sewardje539a402004-07-14 18:24:17 +00001502
1503 Each temp is assigned only once, before its uses.
sewardjc13e2ed2004-10-31 21:44:54 +00001504*/
1505
1506static inline Int countArgs ( IRExpr** args )
1507{
1508 Int i;
1509 for (i = 0; args[i]; i++)
1510 ;
1511 return i;
1512}
sewardje539a402004-07-14 18:24:17 +00001513
sewardj35439212004-07-14 22:36:10 +00001514static
1515__attribute((noreturn))
1516void sanityCheckFail ( IRBB* bb, IRStmt* stmt, Char* what )
sewardje539a402004-07-14 18:24:17 +00001517{
sewardj35439212004-07-14 22:36:10 +00001518 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
1519 ppIRBB(bb);
1520 if (stmt) {
1521 vex_printf("\nIN STATEMENT:\n\n");
1522 ppIRStmt(stmt);
1523 }
1524 vex_printf("\n\nERROR = %s\n\n", what );
1525 vpanic("sanityCheckFail: exiting due to bad IR");
1526}
1527
sewardj2d3f77c2004-09-22 23:49:09 +00001528static Bool saneIRArray ( IRArray* arr )
1529{
1530 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
1531 return False;
sewardjba999312004-11-15 15:21:17 +00001532 if (arr->elemTy == Ity_I1)
sewardj2d3f77c2004-09-22 23:49:09 +00001533 return False;
1534 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
1535 return False;
1536 return True;
1537}
1538
sewardj8ea867b2004-10-30 19:03:02 +00001539static Bool saneIRCallee ( IRCallee* cee )
1540{
1541 if (cee->name == NULL)
1542 return False;
1543 if (cee->addr == 0)
1544 return False;
sewardj77352542004-10-30 20:39:01 +00001545 if (cee->regparms < 0 || cee->regparms > 3)
sewardj8ea867b2004-10-30 19:03:02 +00001546 return False;
1547 return True;
1548}
1549
sewardj49bfe672004-11-15 15:46:26 +00001550static Bool saneIRConst ( IRConst* con )
1551{
1552 switch (con->tag) {
1553 case Ico_U1:
1554 return con->Ico.U1 == True || con->Ico.U1 == False;
1555 default:
1556 /* Is there anything we can meaningfully check? I don't
1557 think so. */
1558 return True;
1559 }
1560}
sewardj35439212004-07-14 22:36:10 +00001561
1562/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
1563 range ones. Report any which are read and for which the current
1564 def_count is zero. */
1565
1566static
sewardj17442fe2004-09-20 14:54:28 +00001567void useBeforeDef_Temp ( IRBB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
1568{
1569 if (tmp < 0 || tmp >= bb->tyenv->types_used)
1570 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
1571 if (def_counts[tmp] < 1)
1572 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
1573}
1574
1575static
sewardj35439212004-07-14 22:36:10 +00001576void useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
1577{
1578 Int i;
1579 switch (expr->tag) {
1580 case Iex_Get:
1581 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001582 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001583 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
sewardjbb53f8c2004-08-14 11:50:01 +00001584 break;
sewardj17442fe2004-09-20 14:54:28 +00001585 case Iex_Tmp:
1586 useBeforeDef_Temp(bb,stmt,expr->Iex.Tmp.tmp,def_counts);
sewardj35439212004-07-14 22:36:10 +00001587 break;
1588 case Iex_Binop:
1589 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
1590 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
1591 break;
1592 case Iex_Unop:
1593 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
1594 break;
1595 case Iex_LDle:
1596 useBeforeDef_Expr(bb,stmt,expr->Iex.LDle.addr,def_counts);
1597 break;
1598 case Iex_Const:
1599 break;
1600 case Iex_CCall:
1601 for (i = 0; expr->Iex.CCall.args[i]; i++)
1602 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
1603 break;
sewardj4042c7e2004-07-18 01:28:30 +00001604 case Iex_Mux0X:
1605 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
1606 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
1607 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
sewardjeeb9ef82004-07-15 12:39:03 +00001608 break;
1609 default:
1610 vpanic("useBeforeDef_Expr");
sewardj35439212004-07-14 22:36:10 +00001611 }
1612}
1613
1614static
1615void useBeforeDef_Stmt ( IRBB* bb, IRStmt* stmt, Int* def_counts )
1616{
sewardj17442fe2004-09-20 14:54:28 +00001617 Int i;
1618 IRDirty* d;
sewardj35439212004-07-14 22:36:10 +00001619 switch (stmt->tag) {
1620 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001621 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001622 break;
sewardjd1725d12004-08-12 20:46:53 +00001623 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +00001624 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
sewardj2d3f77c2004-09-22 23:49:09 +00001625 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
sewardjd1725d12004-08-12 20:46:53 +00001626 break;
sewardj35439212004-07-14 22:36:10 +00001627 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001628 useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001629 break;
1630 case Ist_STle:
1631 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.addr,def_counts);
1632 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.data,def_counts);
1633 break;
sewardj17442fe2004-09-20 14:54:28 +00001634 case Ist_Dirty:
1635 d = stmt->Ist.Dirty.details;
1636 for (i = 0; d->args[i] != NULL; i++)
1637 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
1638 if (d->mFx != Ifx_None)
1639 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
1640 break;
sewardj35439212004-07-14 22:36:10 +00001641 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001642 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
sewardj35439212004-07-14 22:36:10 +00001643 break;
1644 default:
1645 vpanic("useBeforeDef_Stmt");
1646 }
1647}
1648
sewardj6efd4a12004-07-15 03:54:23 +00001649static
1650void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
1651{
1652 Int i;
1653 IRType t_dst, t_arg1, t_arg2;
1654 IRTypeEnv* tyenv = bb->tyenv;
1655 switch (expr->tag) {
1656 case Iex_Get:
1657 case Iex_Tmp:
1658 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001659 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001660 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
1661 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
1662 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001663 if (!saneIRArray(expr->Iex.GetI.descr))
1664 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
sewardjbb53f8c2004-08-14 11:50:01 +00001665 break;
sewardj6d2638e2004-07-15 09:38:27 +00001666 case Iex_Binop: {
1667 IRType ttarg1, ttarg2;
sewardj6efd4a12004-07-15 03:54:23 +00001668 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
1669 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
1670 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
sewardj8f3debf2004-09-08 23:42:23 +00001671 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID) {
1672 vex_printf(" op name: " );
1673 ppIROp(expr->Iex.Binop.op);
1674 vex_printf("\n");
1675 sanityCheckFail(bb,stmt,
1676 "Iex.Binop: wrong arity op\n"
1677 "... name of op precedes BB printout\n");
1678 }
sewardj6d2638e2004-07-15 09:38:27 +00001679 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
1680 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
1681 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
1682 vex_printf(" op name: ");
1683 ppIROp(expr->Iex.Binop.op);
1684 vex_printf("\n");
1685 vex_printf(" op type is (");
1686 ppIRType(t_arg1);
1687 vex_printf(",");
1688 ppIRType(t_arg2);
1689 vex_printf(") -> ");
1690 ppIRType (t_dst);
1691 vex_printf("\narg tys are (");
1692 ppIRType(ttarg1);
1693 vex_printf(",");
1694 ppIRType(ttarg2);
1695 vex_printf(")\n");
1696 sanityCheckFail(bb,stmt,
1697 "Iex.Binop: arg tys don't match op tys\n"
1698 "... additional details precede BB printout\n");
sewardj695cff92004-10-13 14:50:14 +00001699 }
sewardj6efd4a12004-07-15 03:54:23 +00001700 break;
sewardj6d2638e2004-07-15 09:38:27 +00001701 }
sewardj6efd4a12004-07-15 03:54:23 +00001702 case Iex_Unop:
1703 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
1704 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1705 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID)
1706 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
1707 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
1708 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
1709 break;
1710 case Iex_LDle:
1711 tcExpr(bb,stmt, expr->Iex.LDle.addr, gWordTy);
1712 if (typeOfIRExpr(tyenv, expr->Iex.LDle.addr) != gWordTy)
1713 sanityCheckFail(bb,stmt,"Iex.LDle.addr: not :: guest word type");
1714 break;
1715 case Iex_CCall:
sewardjc13e2ed2004-10-31 21:44:54 +00001716 if (!saneIRCallee(expr->Iex.CCall.cee))
1717 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
sewardjcf787902004-11-03 09:08:33 +00001718 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
sewardjc13e2ed2004-10-31 21:44:54 +00001719 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
sewardj43c56462004-11-06 12:17:57 +00001720 for (i = 0; expr->Iex.CCall.args[i]; i++) {
1721 if (i >= 32)
1722 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
sewardj6efd4a12004-07-15 03:54:23 +00001723 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
sewardj43c56462004-11-06 12:17:57 +00001724 }
sewardjba999312004-11-15 15:21:17 +00001725 if (expr->Iex.CCall.retty == Ity_I1)
1726 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001727 for (i = 0; expr->Iex.CCall.args[i]; i++)
sewardjba999312004-11-15 15:21:17 +00001728 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
1729 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001730 break;
1731 case Iex_Const:
sewardj49bfe672004-11-15 15:46:26 +00001732 if (!saneIRConst(expr->Iex.Const.con))
1733 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
sewardj6efd4a12004-07-15 03:54:23 +00001734 break;
sewardj4042c7e2004-07-18 01:28:30 +00001735 case Iex_Mux0X:
1736 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
1737 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
1738 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
1739 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
1740 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
1741 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
1742 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
1743 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
sewardjeeb9ef82004-07-15 12:39:03 +00001744 break;
1745 default:
sewardj6efd4a12004-07-15 03:54:23 +00001746 vpanic("tcExpr");
1747 }
1748}
1749
1750
1751static
1752void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
1753{
sewardj17442fe2004-09-20 14:54:28 +00001754 Int i;
1755 IRDirty* d;
sewardj6efd4a12004-07-15 03:54:23 +00001756 IRTypeEnv* tyenv = bb->tyenv;
1757 switch (stmt->tag) {
1758 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001759 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001760 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
1761 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
sewardj2d3f77c2004-09-22 23:49:09 +00001762 break;
sewardjd1725d12004-08-12 20:46:53 +00001763 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +00001764 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
sewardjeeac8412004-11-02 00:26:55 +00001765 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001766 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
1767 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
sewardj6d076362004-09-23 11:06:17 +00001768 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data)
1769 != stmt->Ist.PutI.descr->elemTy)
1770 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
sewardjeeac8412004-11-02 00:26:55 +00001771 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
1772 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001773 if (!saneIRArray(stmt->Ist.PutI.descr))
1774 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
1775 break;
sewardj6efd4a12004-07-15 03:54:23 +00001776 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001777 tcExpr( bb, stmt, stmt->Ist.Tmp.data, gWordTy );
sewardj17442fe2004-09-20 14:54:28 +00001778 if (typeOfIRTemp(tyenv, stmt->Ist.Tmp.tmp)
sewardj6d076362004-09-23 11:06:17 +00001779 != typeOfIRExpr(tyenv, stmt->Ist.Tmp.data))
sewardj6d2638e2004-07-15 09:38:27 +00001780 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
sewardj6efd4a12004-07-15 03:54:23 +00001781 break;
1782 case Ist_STle:
1783 tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
1784 tcExpr( bb, stmt, stmt->Ist.STle.data, gWordTy );
1785 if (typeOfIRExpr(tyenv, stmt->Ist.STle.addr) != gWordTy)
1786 sanityCheckFail(bb,stmt,"IRStmt.STle.addr: not :: guest word type");
sewardjba999312004-11-15 15:21:17 +00001787 if (typeOfIRExpr(tyenv, stmt->Ist.STle.data) == Ity_I1)
1788 sanityCheckFail(bb,stmt,"IRStmt.STle.data: cannot STle :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001789 break;
sewardj17442fe2004-09-20 14:54:28 +00001790 case Ist_Dirty:
1791 /* Mostly check for various kinds of ill-formed dirty calls. */
1792 d = stmt->Ist.Dirty.details;
sewardj8ea867b2004-10-30 19:03:02 +00001793 if (d->cee == NULL) goto bad_dirty;
1794 if (!saneIRCallee(d->cee)) goto bad_dirty;
sewardjcf787902004-11-03 09:08:33 +00001795 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001796 if (d->mFx == Ifx_None) {
1797 if (d->mAddr != NULL || d->mSize != 0)
1798 goto bad_dirty;
1799 } else {
1800 if (d->mAddr == NULL || d->mSize == 0)
1801 goto bad_dirty;
1802 }
1803 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
1804 goto bad_dirty;
sewardjc5fc7aa2004-10-27 23:00:55 +00001805 if (d->nFxState == 0 && d->needsBBP)
1806 goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001807 for (i = 0; i < d->nFxState; i++) {
1808 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
1809 if (d->fxState[i].size <= 0) goto bad_dirty;
1810 }
1811 /* check types, minimally */
sewardjb8385d82004-11-02 01:34:15 +00001812 if (d->guard == NULL) goto bad_dirty;
sewardj49bfe672004-11-15 15:46:26 +00001813 tcExpr( bb, stmt, d->guard, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001814 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
1815 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
sewardj92d168d2004-11-15 14:22:12 +00001816 if (d->tmp != IRTemp_INVALID
sewardjba999312004-11-15 15:21:17 +00001817 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
1818 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001819 for (i = 0; d->args[i] != NULL; i++) {
sewardj43c56462004-11-06 12:17:57 +00001820 if (i >= 32)
1821 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
sewardjba999312004-11-15 15:21:17 +00001822 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
1823 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001824 }
1825 break;
1826 bad_dirty:
1827 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
1828
sewardj6efd4a12004-07-15 03:54:23 +00001829 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001830 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
1831 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
1832 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
sewardj49bfe672004-11-15 15:46:26 +00001833 if (!saneIRConst(stmt->Ist.Exit.dst))
1834 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
sewardj6efd4a12004-07-15 03:54:23 +00001835 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
1836 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
1837 break;
1838 default:
1839 vpanic("tcStmt");
1840 }
1841}
1842
sewardj35439212004-07-14 22:36:10 +00001843void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
1844{
1845 Int i;
1846 IRStmt* stmt;
1847 Int n_temps = bb->tyenv->types_used;
1848 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
1849
1850 vassert(guest_word_size == Ity_I32
sewardj695cff92004-10-13 14:50:14 +00001851 || guest_word_size == Ity_I64);
sewardj35439212004-07-14 22:36:10 +00001852
sewardjd7cb8532004-08-17 23:59:23 +00001853 if (bb->stmts_used < 0 || bb->stmts_size < 8
1854 || bb->stmts_used > bb->stmts_size)
1855 /* this BB is so strange we can't even print it */
1856 vpanic("sanityCheckIRBB: stmts array limits wierd");
1857
sewardj6d2638e2004-07-15 09:38:27 +00001858 /* Ensure each temp has a plausible type. */
1859 for (i = 0; i < n_temps; i++) {
sewardj17442fe2004-09-20 14:54:28 +00001860 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
sewardj6d2638e2004-07-15 09:38:27 +00001861 if (!isPlausibleType(ty)) {
1862 vex_printf("Temp t%d declared with implausible type 0x%x\n",
1863 i, (UInt)ty);
1864 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
1865 }
1866 }
sewardj35439212004-07-14 22:36:10 +00001867
1868 /* Count the defs of each temp. Only one def is allowed.
1869 Also, check that each used temp has already been defd. */
sewardj6d2638e2004-07-15 09:38:27 +00001870
1871 for (i = 0; i < n_temps; i++)
1872 def_counts[i] = 0;
1873
sewardjd7cb8532004-08-17 23:59:23 +00001874 for (i = 0; i < bb->stmts_used; i++) {
1875 stmt = bb->stmts[i];
sewardj39e3f242004-08-18 16:54:52 +00001876 if (!stmt)
1877 continue;
sewardj35439212004-07-14 22:36:10 +00001878 useBeforeDef_Stmt(bb,stmt,def_counts);
sewardj17442fe2004-09-20 14:54:28 +00001879
sewardj35439212004-07-14 22:36:10 +00001880 if (stmt->tag == Ist_Tmp) {
1881 if (stmt->Ist.Tmp.tmp < 0 || stmt->Ist.Tmp.tmp >= n_temps)
sewardj17442fe2004-09-20 14:54:28 +00001882 sanityCheckFail(bb, stmt,
1883 "IRStmt.Tmp: destination tmp is out of range");
sewardj35439212004-07-14 22:36:10 +00001884 def_counts[stmt->Ist.Tmp.tmp]++;
1885 if (def_counts[stmt->Ist.Tmp.tmp] > 1)
sewardj17442fe2004-09-20 14:54:28 +00001886 sanityCheckFail(bb, stmt,
sewardjcf787902004-11-03 09:08:33 +00001887 "IRStmt.Tmp: destination tmp is assigned more than once");
sewardj17442fe2004-09-20 14:54:28 +00001888 }
1889 else
1890 if (stmt->tag == Ist_Dirty
sewardj92d168d2004-11-15 14:22:12 +00001891 && stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
sewardj17442fe2004-09-20 14:54:28 +00001892 IRDirty* d = stmt->Ist.Dirty.details;
1893 if (d->tmp < 0 || d->tmp >= n_temps)
1894 sanityCheckFail(bb, stmt,
1895 "IRStmt.Dirty: destination tmp is out of range");
1896 def_counts[d->tmp]++;
1897 if (def_counts[d->tmp] > 1)
1898 sanityCheckFail(bb, stmt,
1899 "IRStmt.Dirty: destination tmp is assigned more than once");
sewardj35439212004-07-14 22:36:10 +00001900 }
1901 }
1902
sewardj6efd4a12004-07-15 03:54:23 +00001903 /* Typecheck everything. */
sewardjd7cb8532004-08-17 23:59:23 +00001904 for (i = 0; i < bb->stmts_used; i++)
sewardj39e3f242004-08-18 16:54:52 +00001905 if (bb->stmts[i])
1906 tcStmt( bb, bb->stmts[i], guest_word_size );
sewardj6efd4a12004-07-15 03:54:23 +00001907 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
1908 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
sewardje539a402004-07-14 18:24:17 +00001909}
1910
sewardj4345f7a2004-09-22 19:49:27 +00001911/*---------------------------------------------------------------*/
1912/*--- Misc helper functions ---*/
1913/*---------------------------------------------------------------*/
1914
1915Bool eqIRConst ( IRConst* c1, IRConst* c2 )
1916{
1917 if (c1->tag != c2->tag)
1918 return False;
1919
1920 switch (c1->tag) {
sewardjba999312004-11-15 15:21:17 +00001921 case Ico_U1: return (1 & c1->Ico.U1) == (1 & c2->Ico.U1);
sewardj4345f7a2004-09-22 19:49:27 +00001922 case Ico_U8: return c1->Ico.U8 == c2->Ico.U8;
1923 case Ico_U16: return c1->Ico.U16 == c2->Ico.U16;
1924 case Ico_U32: return c1->Ico.U32 == c2->Ico.U32;
1925 case Ico_U64: return c1->Ico.U64 == c2->Ico.U64;
1926 case Ico_F64: return c1->Ico.F64 == c2->Ico.F64;
1927 default: vpanic("eqIRConst");
1928 }
1929}
1930
sewardje98dcf22004-10-04 09:15:11 +00001931Bool eqIRArray ( IRArray* descr1, IRArray* descr2 )
1932{
1933 return descr1->base == descr2->base
1934 && descr1->elemTy == descr2->elemTy
1935 && descr1->nElems == descr2->nElems;
1936}
1937
sewardj2d3f77c2004-09-22 23:49:09 +00001938Int sizeofIRType ( IRType ty )
1939{
1940 switch (ty) {
sewardjc9a43662004-11-30 18:51:59 +00001941 case Ity_I8: return 1;
1942 case Ity_I16: return 2;
1943 case Ity_I32: return 4;
1944 case Ity_I64: return 8;
1945 case Ity_F32: return 4;
1946 case Ity_F64: return 8;
1947 case Ity_V128: return 16;
sewardj2d3f77c2004-09-22 23:49:09 +00001948 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
1949 vpanic("sizeofIRType");
1950 }
1951}
1952
sewardj49651f42004-10-28 22:11:04 +00001953IRExpr* mkIRExpr_HWord ( HWord hw )
1954{
sewardjf9655262004-10-31 20:02:16 +00001955 vassert(sizeof(void*) == sizeof(HWord));
sewardj49651f42004-10-28 22:11:04 +00001956 if (sizeof(HWord) == 4)
1957 return IRExpr_Const(IRConst_U32((UInt)hw));
1958 if (sizeof(HWord) == 8)
sewardjf9655262004-10-31 20:02:16 +00001959 return IRExpr_Const(IRConst_U64((ULong)hw));
sewardj49651f42004-10-28 22:11:04 +00001960 vpanic("mkIRExpr_HWord");
1961}
sewardj6efd4a12004-07-15 03:54:23 +00001962
sewardjf9655262004-10-31 20:02:16 +00001963IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr,
1964 IRExpr** args )
1965{
1966 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001967 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001968 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001969 d->args = args;
sewardjf9655262004-10-31 20:02:16 +00001970 return d;
1971}
1972
1973IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1974 Int regparms, Char* name, void* addr,
1975 IRExpr** args )
1976{
1977 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001978 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001979 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001980 d->args = args;
1981 d->tmp = dst;
sewardjf9655262004-10-31 20:02:16 +00001982 return d;
1983}
1984
1985IRExpr* mkIRExprCCall ( IRType retty,
1986 Int regparms, Char* name, void* addr,
1987 IRExpr** args )
1988{
1989 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
1990 retty, args );
1991}
1992
sewardje539a402004-07-14 18:24:17 +00001993/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +00001994/*--- end ir/irdefs.c ---*/
sewardj887a11a2004-07-05 17:26:47 +00001995/*---------------------------------------------------------------*/