blob: 0f0306ca7eea51ca4f65c613d566960122302280 [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
sewardj70f676d2004-12-10 14:59:57 +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 case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
sewardj164f9272004-12-09 00:39:32 +0000302
303 case Iop_Add8x16: vex_printf("Add8x16"); return;
304 case Iop_Add16x8: vex_printf("Add16x8"); return;
305 case Iop_Add32x4: vex_printf("Add32x4"); return;
306 case Iop_Add64x2: vex_printf("Add64x2"); return;
307 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return;
308 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return;
309 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return;
310 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return;
311
312 case Iop_Sub8x16: vex_printf("Sub8x16"); return;
313 case Iop_Sub16x8: vex_printf("Sub16x8"); return;
314 case Iop_Sub32x4: vex_printf("Sub32x4"); return;
315 case Iop_Sub64x2: vex_printf("Sub64x2"); return;
316 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return;
317 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return;
318 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return;
319 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return;
320
321 case Iop_Mul16x8: vex_printf("Mul16x8"); return;
322 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return;
323 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return;
324
325 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return;
326 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return;
327
328 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return;
329 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return;
330 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return;
331 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return;
332
333 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return;
334 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return;
335 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return;
336 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return;
337 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return;
338 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return;
339
340 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return;
341 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return;
342 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return;
343 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return;
344 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return;
345 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return;
346 case Iop_SarN16x8: vex_printf("SarN16x8"); return;
347 case Iop_SarN32x4: vex_printf("SarN32x4"); return;
348
349 case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return;
350 case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return;
351 case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return;
352
353 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return;
354 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return;
355 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return;
356 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return;
357 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return;
358 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return;
359 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
360 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
361
sewardjc9a43662004-11-30 18:51:59 +0000362 default: vpanic("ppIROp(1)");
sewardj41f43bc2004-07-08 14:23:22 +0000363 }
364
365 switch (op - base) {
366 case 0: vex_printf(str); vex_printf("8"); break;
367 case 1: vex_printf(str); vex_printf("16"); break;
368 case 2: vex_printf(str); vex_printf("32"); break;
369 case 3: vex_printf(str); vex_printf("64"); break;
370 default: vpanic("ppIROp(2)");
371 }
sewardje3d0d2e2004-06-27 10:42:44 +0000372}
373
sewardj35421a32004-07-05 13:12:34 +0000374void ppIRExpr ( IRExpr* e )
sewardje3d0d2e2004-06-27 10:42:44 +0000375{
sewardje87b4842004-07-10 12:23:30 +0000376 Int i;
sewardje3d0d2e2004-06-27 10:42:44 +0000377 switch (e->tag) {
sewardj443cd9d2004-07-18 23:06:45 +0000378 case Iex_Binder:
379 vex_printf("BIND-%d", e->Iex.Binder.binder);
380 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000381 case Iex_Get:
sewardjc9a43662004-11-30 18:51:59 +0000382 vex_printf( "GET:" );
sewardjfbcaf332004-07-08 01:46:01 +0000383 ppIRType(e->Iex.Get.ty);
sewardjc9a43662004-11-30 18:51:59 +0000384 vex_printf("(%d)", e->Iex.Get.offset);
sewardjec6ad592004-06-20 12:26:53 +0000385 break;
sewardjbb53f8c2004-08-14 11:50:01 +0000386 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +0000387 vex_printf( "GETI" );
388 ppIRArray(e->Iex.GetI.descr);
389 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000390 ppIRExpr(e->Iex.GetI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000391 vex_printf(",%d]", e->Iex.GetI.bias);
sewardjbb53f8c2004-08-14 11:50:01 +0000392 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000393 case Iex_Tmp:
sewardj35421a32004-07-05 13:12:34 +0000394 ppIRTemp(e->Iex.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +0000395 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000396 case Iex_Binop:
sewardj35421a32004-07-05 13:12:34 +0000397 ppIROp(e->Iex.Binop.op);
398 vex_printf( "(" );
399 ppIRExpr(e->Iex.Binop.arg1);
400 vex_printf( "," );
401 ppIRExpr(e->Iex.Binop.arg2);
402 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000403 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000404 case Iex_Unop:
sewardj35421a32004-07-05 13:12:34 +0000405 ppIROp(e->Iex.Unop.op);
406 vex_printf( "(" );
407 ppIRExpr(e->Iex.Unop.arg);
408 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000409 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000410 case Iex_LDle:
sewardje05c42c2004-07-08 20:25:10 +0000411 vex_printf( "LDle:" );
sewardj35421a32004-07-05 13:12:34 +0000412 ppIRType(e->Iex.LDle.ty);
sewardje05c42c2004-07-08 20:25:10 +0000413 vex_printf( "(" );
sewardj35421a32004-07-05 13:12:34 +0000414 ppIRExpr(e->Iex.LDle.addr);
415 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000416 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000417 case Iex_Const:
sewardj35421a32004-07-05 13:12:34 +0000418 ppIRConst(e->Iex.Const.con);
sewardjec6ad592004-06-20 12:26:53 +0000419 break;
sewardje87b4842004-07-10 12:23:30 +0000420 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000421 ppIRCallee(e->Iex.CCall.cee);
422 vex_printf("(");
sewardje87b4842004-07-10 12:23:30 +0000423 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
424 ppIRExpr(e->Iex.CCall.args[i]);
425 if (e->Iex.CCall.args[i+1] != NULL)
426 vex_printf(",");
427 }
428 vex_printf("):");
429 ppIRType(e->Iex.CCall.retty);
430 break;
sewardj4042c7e2004-07-18 01:28:30 +0000431 case Iex_Mux0X:
432 vex_printf("Mux0X(");
433 ppIRExpr(e->Iex.Mux0X.cond);
sewardjeeb9ef82004-07-15 12:39:03 +0000434 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000435 ppIRExpr(e->Iex.Mux0X.expr0);
sewardjeeb9ef82004-07-15 12:39:03 +0000436 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000437 ppIRExpr(e->Iex.Mux0X.exprX);
sewardjeeb9ef82004-07-15 12:39:03 +0000438 vex_printf(")");
439 break;
sewardjec6ad592004-06-20 12:26:53 +0000440 default:
sewardj35421a32004-07-05 13:12:34 +0000441 vpanic("ppIExpr");
sewardjec6ad592004-06-20 12:26:53 +0000442 }
443}
444
sewardj17442fe2004-09-20 14:54:28 +0000445void ppIREffect ( IREffect fx )
446{
447 switch (fx) {
448 case Ifx_None: vex_printf("noFX"); return;
449 case Ifx_Read: vex_printf("RdFX"); return;
450 case Ifx_Write: vex_printf("WrFX"); return;
451 case Ifx_Modify: vex_printf("MoFX"); return;
452 default: vpanic("ppIREffect");
453 }
454}
455
456void ppIRDirty ( IRDirty* d )
457{
458 Int i;
sewardj92d168d2004-11-15 14:22:12 +0000459 if (d->tmp != IRTemp_INVALID) {
sewardj4b861de2004-11-03 15:24:42 +0000460 ppIRTemp(d->tmp);
461 vex_printf(" = ");
462 }
sewardjb8385d82004-11-02 01:34:15 +0000463 vex_printf("DIRTY ");
464 ppIRExpr(d->guard);
sewardjc5fc7aa2004-10-27 23:00:55 +0000465 if (d->needsBBP)
466 vex_printf(" NeedsBBP");
sewardj17442fe2004-09-20 14:54:28 +0000467 if (d->mFx != Ifx_None) {
sewardj49651f42004-10-28 22:11:04 +0000468 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000469 ppIREffect(d->mFx);
470 vex_printf("-mem(");
471 ppIRExpr(d->mAddr);
sewardj49651f42004-10-28 22:11:04 +0000472 vex_printf(",%d)", d->mSize);
sewardj17442fe2004-09-20 14:54:28 +0000473 }
474 for (i = 0; i < d->nFxState; i++) {
sewardj49651f42004-10-28 22:11:04 +0000475 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000476 ppIREffect(d->fxState[i].fx);
sewardj49651f42004-10-28 22:11:04 +0000477 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
sewardj17442fe2004-09-20 14:54:28 +0000478 }
sewardjc5fc7aa2004-10-27 23:00:55 +0000479 vex_printf(" ::: ");
sewardj8ea867b2004-10-30 19:03:02 +0000480 ppIRCallee(d->cee);
481 vex_printf("(");
sewardj17442fe2004-09-20 14:54:28 +0000482 for (i = 0; d->args[i] != NULL; i++) {
483 ppIRExpr(d->args[i]);
484 if (d->args[i+1] != NULL) {
485 vex_printf(",");
486 }
487 }
488 vex_printf(")");
489}
490
sewardj893aada2004-11-29 19:57:54 +0000491void ppIRJumpKind ( IRJumpKind kind )
492{
493 switch (kind) {
494 case Ijk_Boring: vex_printf("Boring"); break;
495 case Ijk_Call: vex_printf("Call"); break;
496 case Ijk_Ret: vex_printf("Return"); break;
497 case Ijk_ClientReq: vex_printf("ClientReq"); break;
498 case Ijk_Syscall: vex_printf("Syscall"); break;
499 case Ijk_Yield: vex_printf("Yield"); break;
500 case Ijk_EmWarn: vex_printf("EmWarn"); break;
501 default: vpanic("ppIRJumpKind");
502 }
503}
504
sewardj35421a32004-07-05 13:12:34 +0000505void ppIRStmt ( IRStmt* s )
sewardjec6ad592004-06-20 12:26:53 +0000506{
sewardj17442fe2004-09-20 14:54:28 +0000507 switch (s->tag) {
508 case Ist_Put:
509 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
sewardj6d076362004-09-23 11:06:17 +0000510 ppIRExpr(s->Ist.Put.data);
sewardj17442fe2004-09-20 14:54:28 +0000511 break;
512 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +0000513 vex_printf( "PUTI" );
514 ppIRArray(s->Ist.PutI.descr);
515 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000516 ppIRExpr(s->Ist.PutI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000517 vex_printf(",%d] = ", s->Ist.PutI.bias);
518 ppIRExpr(s->Ist.PutI.data);
sewardj17442fe2004-09-20 14:54:28 +0000519 break;
520 case Ist_Tmp:
521 ppIRTemp(s->Ist.Tmp.tmp);
522 vex_printf( " = " );
sewardj6d076362004-09-23 11:06:17 +0000523 ppIRExpr(s->Ist.Tmp.data);
sewardj17442fe2004-09-20 14:54:28 +0000524 break;
525 case Ist_STle:
526 vex_printf( "STle(");
527 ppIRExpr(s->Ist.STle.addr);
528 vex_printf( ") = ");
529 ppIRExpr(s->Ist.STle.data);
530 break;
531 case Ist_Dirty:
532 ppIRDirty(s->Ist.Dirty.details);
533 break;
534 case Ist_Exit:
535 vex_printf( "if (" );
sewardj0276d4b2004-11-15 15:30:21 +0000536 ppIRExpr(s->Ist.Exit.guard);
sewardj893aada2004-11-29 19:57:54 +0000537 vex_printf( ") goto {");
538 ppIRJumpKind(s->Ist.Exit.jk);
539 vex_printf("} ");
sewardj17442fe2004-09-20 14:54:28 +0000540 ppIRConst(s->Ist.Exit.dst);
541 break;
542 default:
543 vpanic("ppIRStmt");
544 }
sewardjec6ad592004-06-20 12:26:53 +0000545}
546
sewardj35421a32004-07-05 13:12:34 +0000547void ppIRTypeEnv ( IRTypeEnv* env ) {
sewardjc97096c2004-06-30 09:28:04 +0000548 UInt i;
sewardje539a402004-07-14 18:24:17 +0000549 for (i = 0; i < env->types_used; i++) {
sewardjc97096c2004-06-30 09:28:04 +0000550 if (i % 8 == 0)
sewardj35421a32004-07-05 13:12:34 +0000551 vex_printf( " ");
sewardje539a402004-07-14 18:24:17 +0000552 ppIRTemp(i);
sewardj35421a32004-07-05 13:12:34 +0000553 vex_printf( ":");
sewardje539a402004-07-14 18:24:17 +0000554 ppIRType(env->types[i]);
sewardjc97096c2004-06-30 09:28:04 +0000555 if (i % 8 == 7)
sewardj35421a32004-07-05 13:12:34 +0000556 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000557 else
sewardj35421a32004-07-05 13:12:34 +0000558 vex_printf( " ");
sewardjc97096c2004-06-30 09:28:04 +0000559 }
sewardje539a402004-07-14 18:24:17 +0000560 if (env->types_used > 0 && env->types_used % 8 != 7)
sewardj35421a32004-07-05 13:12:34 +0000561 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000562}
563
sewardj35421a32004-07-05 13:12:34 +0000564void ppIRBB ( IRBB* bb )
sewardjec6ad592004-06-20 12:26:53 +0000565{
sewardjd7cb8532004-08-17 23:59:23 +0000566 Int i;
sewardj35439212004-07-14 22:36:10 +0000567 vex_printf("IRBB {\n");
sewardj35421a32004-07-05 13:12:34 +0000568 ppIRTypeEnv(bb->tyenv);
sewardj35439212004-07-14 22:36:10 +0000569 vex_printf("\n");
sewardjd7cb8532004-08-17 23:59:23 +0000570 for (i = 0; i < bb->stmts_used; i++) {
sewardj39e3f242004-08-18 16:54:52 +0000571 if (bb->stmts[i]) {
572 vex_printf( " ");
573 ppIRStmt(bb->stmts[i]);
574 }
sewardj35421a32004-07-05 13:12:34 +0000575 vex_printf( "\n");
sewardjec6ad592004-06-20 12:26:53 +0000576 }
sewardje539a402004-07-14 18:24:17 +0000577 vex_printf( " goto {");
578 ppIRJumpKind(bb->jumpkind);
579 vex_printf( "} ");
580 ppIRExpr( bb->next );
sewardj35439212004-07-14 22:36:10 +0000581 vex_printf( "\n}\n");
sewardjec6ad592004-06-20 12:26:53 +0000582}
583
584
585/*---------------------------------------------------------------*/
586/*--- Constructors ---*/
587/*---------------------------------------------------------------*/
588
sewardjc97096c2004-06-30 09:28:04 +0000589
590/* Constructors -- IRConst */
591
sewardjba999312004-11-15 15:21:17 +0000592IRConst* IRConst_U1 ( Bool bit )
sewardjb8e75862004-08-19 17:58:45 +0000593{
594 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjba999312004-11-15 15:21:17 +0000595 c->tag = Ico_U1;
596 c->Ico.U1 = bit;
sewardj4b861de2004-11-03 15:24:42 +0000597 /* call me paranoid; I don't care :-) */
598 vassert(bit == False || bit == True);
sewardjb8e75862004-08-19 17:58:45 +0000599 return c;
600}
sewardjc97096c2004-06-30 09:28:04 +0000601IRConst* IRConst_U8 ( UChar u8 )
602{
sewardj35421a32004-07-05 13:12:34 +0000603 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000604 c->tag = Ico_U8;
605 c->Ico.U8 = u8;
606 return c;
607}
608IRConst* IRConst_U16 ( UShort u16 )
609{
sewardj35421a32004-07-05 13:12:34 +0000610 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000611 c->tag = Ico_U16;
612 c->Ico.U16 = u16;
613 return c;
614}
615IRConst* IRConst_U32 ( UInt u32 )
616{
sewardj35421a32004-07-05 13:12:34 +0000617 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000618 c->tag = Ico_U32;
619 c->Ico.U32 = u32;
620 return c;
621}
622IRConst* IRConst_U64 ( ULong u64 )
623{
sewardj35421a32004-07-05 13:12:34 +0000624 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000625 c->tag = Ico_U64;
626 c->Ico.U64 = u64;
627 return c;
628}
sewardja58ea662004-08-15 03:12:41 +0000629IRConst* IRConst_F64 ( Double f64 )
630{
631 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
632 c->tag = Ico_F64;
633 c->Ico.F64 = f64;
634 return c;
635}
sewardj17442fe2004-09-20 14:54:28 +0000636IRConst* IRConst_F64i ( ULong f64i )
sewardj207557a2004-08-27 12:00:18 +0000637{
sewardj17442fe2004-09-20 14:54:28 +0000638 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
639 c->tag = Ico_F64i;
640 c->Ico.F64i = f64i;
sewardj207557a2004-08-27 12:00:18 +0000641 return c;
642}
sewardj1e6ad742004-12-02 16:16:11 +0000643IRConst* IRConst_V128 ( UShort con )
644{
645 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
646 c->tag = Ico_V128;
647 c->Ico.V128 = con;
648 return c;
649}
sewardjc97096c2004-06-30 09:28:04 +0000650
sewardj8ea867b2004-10-30 19:03:02 +0000651/* Constructors -- IRCallee */
652
sewardjf9655262004-10-31 20:02:16 +0000653IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr )
sewardj8ea867b2004-10-30 19:03:02 +0000654{
655 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
sewardj77352542004-10-30 20:39:01 +0000656 ce->regparms = regparms;
657 ce->name = name;
658 ce->addr = addr;
sewardj43c56462004-11-06 12:17:57 +0000659 ce->mcx_mask = 0;
sewardj77352542004-10-30 20:39:01 +0000660 vassert(regparms >= 0 && regparms <= 3);
sewardj8ea867b2004-10-30 19:03:02 +0000661 vassert(name != NULL);
662 vassert(addr != 0);
663 return ce;
664}
665
666
667/* Constructors -- IRArray */
sewardje3d0d2e2004-06-27 10:42:44 +0000668
sewardj2d3f77c2004-09-22 23:49:09 +0000669IRArray* mkIRArray ( Int base, IRType elemTy, Int nElems )
670{
671 IRArray* arr = LibVEX_Alloc(sizeof(IRArray));
672 arr->base = base;
673 arr->elemTy = elemTy;
674 arr->nElems = nElems;
675 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
sewardjba999312004-11-15 15:21:17 +0000676 vassert(!(arr->elemTy == Ity_I1));
sewardj2d3f77c2004-09-22 23:49:09 +0000677 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
678 return arr;
679}
680
681
682/* Constructors -- IRExpr */
683
sewardj443cd9d2004-07-18 23:06:45 +0000684IRExpr* IRExpr_Binder ( Int binder ) {
685 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
686 e->tag = Iex_Binder;
687 e->Iex.Binder.binder = binder;
688 return e;
689}
sewardjfbcaf332004-07-08 01:46:01 +0000690IRExpr* IRExpr_Get ( Int off, IRType ty ) {
sewardj35421a32004-07-05 13:12:34 +0000691 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000692 e->tag = Iex_Get;
693 e->Iex.Get.offset = off;
sewardjfbcaf332004-07-08 01:46:01 +0000694 e->Iex.Get.ty = ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000695 return e;
696}
sewardjeeac8412004-11-02 00:26:55 +0000697IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ) {
sewardj2d3f77c2004-09-22 23:49:09 +0000698 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
699 e->tag = Iex_GetI;
700 e->Iex.GetI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000701 e->Iex.GetI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000702 e->Iex.GetI.bias = bias;
sewardjd1725d12004-08-12 20:46:53 +0000703 return e;
704}
sewardjc97096c2004-06-30 09:28:04 +0000705IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
sewardj35421a32004-07-05 13:12:34 +0000706 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000707 e->tag = Iex_Tmp;
708 e->Iex.Tmp.tmp = tmp;
709 return e;
710}
sewardjc97096c2004-06-30 09:28:04 +0000711IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
sewardj35421a32004-07-05 13:12:34 +0000712 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000713 e->tag = Iex_Binop;
714 e->Iex.Binop.op = op;
715 e->Iex.Binop.arg1 = arg1;
716 e->Iex.Binop.arg2 = arg2;
717 return e;
718}
sewardjc97096c2004-06-30 09:28:04 +0000719IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
sewardj35421a32004-07-05 13:12:34 +0000720 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000721 e->tag = Iex_Unop;
722 e->Iex.Unop.op = op;
723 e->Iex.Unop.arg = arg;
724 return e;
725}
sewardjc97096c2004-06-30 09:28:04 +0000726IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
sewardj35421a32004-07-05 13:12:34 +0000727 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000728 e->tag = Iex_LDle;
729 e->Iex.LDle.ty = ty;
730 e->Iex.LDle.addr = addr;
731 return e;
732}
sewardjc97096c2004-06-30 09:28:04 +0000733IRExpr* IRExpr_Const ( IRConst* con ) {
sewardj35421a32004-07-05 13:12:34 +0000734 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000735 e->tag = Iex_Const;
736 e->Iex.Const.con = con;
737 return e;
sewardjec6ad592004-06-20 12:26:53 +0000738}
sewardj8ea867b2004-10-30 19:03:02 +0000739IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
sewardje87b4842004-07-10 12:23:30 +0000740 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
741 e->tag = Iex_CCall;
sewardj8ea867b2004-10-30 19:03:02 +0000742 e->Iex.CCall.cee = cee;
sewardje87b4842004-07-10 12:23:30 +0000743 e->Iex.CCall.retty = retty;
744 e->Iex.CCall.args = args;
745 return e;
746}
sewardj4042c7e2004-07-18 01:28:30 +0000747IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
sewardjeeb9ef82004-07-15 12:39:03 +0000748 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardj4042c7e2004-07-18 01:28:30 +0000749 e->tag = Iex_Mux0X;
750 e->Iex.Mux0X.cond = cond;
751 e->Iex.Mux0X.expr0 = expr0;
752 e->Iex.Mux0X.exprX = exprX;
sewardjeeb9ef82004-07-15 12:39:03 +0000753 return e;
754}
sewardjec6ad592004-06-20 12:26:53 +0000755
sewardjec6ad592004-06-20 12:26:53 +0000756
sewardjc5fc7aa2004-10-27 23:00:55 +0000757/* Constructors for NULL-terminated IRExpr expression vectors,
758 suitable for use as arg lists in clean/dirty helper calls. */
759
760IRExpr** mkIRExprVec_0 ( void ) {
761 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
762 vec[0] = NULL;
763 return vec;
764}
765IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
766 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
767 vec[0] = arg1;
768 vec[1] = NULL;
769 return vec;
770}
771IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
772 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
773 vec[0] = arg1;
774 vec[1] = arg2;
775 vec[2] = NULL;
776 return vec;
777}
sewardjf9655262004-10-31 20:02:16 +0000778IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
779 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
780 vec[0] = arg1;
781 vec[1] = arg2;
782 vec[2] = arg3;
783 vec[3] = NULL;
784 return vec;
785}
786IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2,
787 IRExpr* arg3, IRExpr* arg4 ) {
788 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
789 vec[0] = arg1;
790 vec[1] = arg2;
791 vec[2] = arg3;
792 vec[3] = arg4;
793 vec[4] = NULL;
794 return vec;
795}
sewardjf32c67d2004-11-08 13:10:44 +0000796IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2,
797 IRExpr* arg3, IRExpr* arg4, IRExpr* arg5 ) {
798 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
799 vec[0] = arg1;
800 vec[1] = arg2;
801 vec[2] = arg3;
802 vec[3] = arg4;
803 vec[4] = arg5;
804 vec[5] = NULL;
805 return vec;
806}
sewardjc5fc7aa2004-10-27 23:00:55 +0000807
808
sewardj17442fe2004-09-20 14:54:28 +0000809/* Constructors -- IRDirty */
810
sewardjc5fc7aa2004-10-27 23:00:55 +0000811IRDirty* emptyIRDirty ( void ) {
sewardj17442fe2004-09-20 14:54:28 +0000812 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
sewardj8ea867b2004-10-30 19:03:02 +0000813 d->cee = NULL;
sewardjb8385d82004-11-02 01:34:15 +0000814 d->guard = NULL;
sewardj17442fe2004-09-20 14:54:28 +0000815 d->args = NULL;
sewardj92d168d2004-11-15 14:22:12 +0000816 d->tmp = IRTemp_INVALID;
sewardj17442fe2004-09-20 14:54:28 +0000817 d->mFx = Ifx_None;
818 d->mAddr = NULL;
819 d->mSize = 0;
sewardjc5fc7aa2004-10-27 23:00:55 +0000820 d->needsBBP = False;
sewardj17442fe2004-09-20 14:54:28 +0000821 d->nFxState = 0;
822 return d;
823}
824
825
sewardjec6ad592004-06-20 12:26:53 +0000826/* Constructors -- IRStmt */
sewardje3d0d2e2004-06-27 10:42:44 +0000827
sewardj6d076362004-09-23 11:06:17 +0000828IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000829 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000830 s->tag = Ist_Put;
831 s->Ist.Put.offset = off;
sewardj6d076362004-09-23 11:06:17 +0000832 s->Ist.Put.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000833 return s;
sewardjec6ad592004-06-20 12:26:53 +0000834}
sewardjeeac8412004-11-02 00:26:55 +0000835IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix,
sewardj2d3f77c2004-09-22 23:49:09 +0000836 Int bias, IRExpr* data ) {
837 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
838 s->tag = Ist_PutI;
839 s->Ist.PutI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000840 s->Ist.PutI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000841 s->Ist.PutI.bias = bias;
842 s->Ist.PutI.data = data;
sewardjd1725d12004-08-12 20:46:53 +0000843 return s;
844}
sewardj6d076362004-09-23 11:06:17 +0000845IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000846 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000847 s->tag = Ist_Tmp;
848 s->Ist.Tmp.tmp = tmp;
sewardj6d076362004-09-23 11:06:17 +0000849 s->Ist.Tmp.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000850 return s;
sewardjec6ad592004-06-20 12:26:53 +0000851}
sewardj6d076362004-09-23 11:06:17 +0000852IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000853 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000854 s->tag = Ist_STle;
855 s->Ist.STle.addr = addr;
sewardj6d076362004-09-23 11:06:17 +0000856 s->Ist.STle.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000857 return s;
sewardjec6ad592004-06-20 12:26:53 +0000858}
sewardj17442fe2004-09-20 14:54:28 +0000859IRStmt* IRStmt_Dirty ( IRDirty* d )
860{
861 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
862 s->tag = Ist_Dirty;
863 s->Ist.Dirty.details = d;
864 return s;
865}
sewardj893aada2004-11-29 19:57:54 +0000866IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
sewardj0276d4b2004-11-15 15:30:21 +0000867 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
868 s->tag = Ist_Exit;
869 s->Ist.Exit.guard = guard;
sewardj893aada2004-11-29 19:57:54 +0000870 s->Ist.Exit.jk = jk;
sewardj0276d4b2004-11-15 15:30:21 +0000871 s->Ist.Exit.dst = dst;
sewardj64e1d652004-07-12 14:00:46 +0000872 return s;
873}
sewardje3d0d2e2004-06-27 10:42:44 +0000874
sewardj695cff92004-10-13 14:50:14 +0000875
876/* Constructors -- IRTypeEnv */
877
878IRTypeEnv* emptyIRTypeEnv ( void )
879{
880 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
881 env->types = LibVEX_Alloc(8 * sizeof(IRType));
882 env->types_size = 8;
883 env->types_used = 0;
884 return env;
885}
886
887
888/* Constructors -- IRBB */
sewardje3d0d2e2004-06-27 10:42:44 +0000889
sewardjd7cb8532004-08-17 23:59:23 +0000890IRBB* emptyIRBB ( void )
891{
892 IRBB* bb = LibVEX_Alloc(sizeof(IRBB));
893 bb->tyenv = emptyIRTypeEnv();
894 bb->stmts_used = 0;
895 bb->stmts_size = 8;
896 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
897 bb->next = NULL;
898 bb->jumpkind = Ijk_Boring;
sewardje3d0d2e2004-06-27 10:42:44 +0000899 return bb;
sewardjec6ad592004-06-20 12:26:53 +0000900}
901
sewardj695cff92004-10-13 14:50:14 +0000902
903/*---------------------------------------------------------------*/
904/*--- (Deep) copy constructors. These make complete copies ---*/
905/*--- the original, which can be modified without affecting ---*/
906/*--- the original. ---*/
907/*---------------------------------------------------------------*/
908
909/* Copying IR Expr vectors (for call args). */
910
911/* Shallow copy of an IRExpr vector */
912
913IRExpr** sopyIRExprVec ( IRExpr** vec )
sewardjd7cb8532004-08-17 23:59:23 +0000914{
sewardj695cff92004-10-13 14:50:14 +0000915 Int i;
916 IRExpr** newvec;
917 for (i = 0; vec[i]; i++)
918 ;
919 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
920 for (i = 0; vec[i]; i++)
921 newvec[i] = vec[i];
922 newvec[i] = NULL;
923 return newvec;
924}
925
926/* Deep copy of an IRExpr vector */
927
928IRExpr** dopyIRExprVec ( IRExpr** vec )
929{
930 Int i;
931 IRExpr** newvec = sopyIRExprVec( vec );
932 for (i = 0; newvec[i]; i++)
933 newvec[i] = dopyIRExpr(newvec[i]);
934 return newvec;
935}
936
937/* Deep copy constructors for all heap-allocated IR types follow. */
938
939IRConst* dopyIRConst ( IRConst* c )
940{
941 switch (c->tag) {
sewardjba999312004-11-15 15:21:17 +0000942 case Ico_U1: return IRConst_U1(c->Ico.U1);
sewardj695cff92004-10-13 14:50:14 +0000943 case Ico_U8: return IRConst_U8(c->Ico.U8);
944 case Ico_U16: return IRConst_U16(c->Ico.U16);
945 case Ico_U32: return IRConst_U32(c->Ico.U32);
946 case Ico_U64: return IRConst_U64(c->Ico.U64);
947 case Ico_F64: return IRConst_F64(c->Ico.F64);
948 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
sewardj1e6ad742004-12-02 16:16:11 +0000949 case Ico_V128: return IRConst_V128(c->Ico.V128);
sewardj695cff92004-10-13 14:50:14 +0000950 default: vpanic("dopyIRConst");
sewardjd7cb8532004-08-17 23:59:23 +0000951 }
sewardj695cff92004-10-13 14:50:14 +0000952}
953
sewardj8ea867b2004-10-30 19:03:02 +0000954IRCallee* dopyIRCallee ( IRCallee* ce )
955{
sewardj43c56462004-11-06 12:17:57 +0000956 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
957 ce2->mcx_mask = ce->mcx_mask;
958 return ce2;
sewardj8ea867b2004-10-30 19:03:02 +0000959}
960
sewardj695cff92004-10-13 14:50:14 +0000961IRArray* dopyIRArray ( IRArray* d )
962{
963 return mkIRArray(d->base, d->elemTy, d->nElems);
964}
965
966IRExpr* dopyIRExpr ( IRExpr* e )
967{
968 switch (e->tag) {
969 case Iex_Get:
970 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
971 case Iex_GetI:
972 return IRExpr_GetI(dopyIRArray(e->Iex.GetI.descr),
sewardjeeac8412004-11-02 00:26:55 +0000973 dopyIRExpr(e->Iex.GetI.ix),
sewardj695cff92004-10-13 14:50:14 +0000974 e->Iex.GetI.bias);
975 case Iex_Tmp:
976 return IRExpr_Tmp(e->Iex.Tmp.tmp);
977 case Iex_Binop:
978 return IRExpr_Binop(e->Iex.Binop.op,
979 dopyIRExpr(e->Iex.Binop.arg1),
980 dopyIRExpr(e->Iex.Binop.arg2));
981 case Iex_Unop:
982 return IRExpr_Unop(e->Iex.Unop.op,
983 dopyIRExpr(e->Iex.Unop.arg));
984 case Iex_LDle:
985 return IRExpr_LDle(e->Iex.LDle.ty,
986 dopyIRExpr(e->Iex.LDle.addr));
987 case Iex_Const:
988 return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
989 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000990 return IRExpr_CCall(dopyIRCallee(e->Iex.CCall.cee),
sewardj695cff92004-10-13 14:50:14 +0000991 e->Iex.CCall.retty,
992 dopyIRExprVec(e->Iex.CCall.args));
993
994 case Iex_Mux0X:
995 return IRExpr_Mux0X(dopyIRExpr(e->Iex.Mux0X.cond),
996 dopyIRExpr(e->Iex.Mux0X.expr0),
997 dopyIRExpr(e->Iex.Mux0X.exprX));
998 default:
999 vpanic("dopyIRExpr");
1000 }
1001}
1002
1003IRDirty* dopyIRDirty ( IRDirty* d )
1004{
1005 Int i;
1006 IRDirty* d2 = emptyIRDirty();
sewardj8ea867b2004-10-30 19:03:02 +00001007 d2->cee = dopyIRCallee(d->cee);
sewardjb8385d82004-11-02 01:34:15 +00001008 d2->guard = dopyIRExpr(d->guard);
sewardj695cff92004-10-13 14:50:14 +00001009 d2->args = dopyIRExprVec(d->args);
1010 d2->tmp = d->tmp;
1011 d2->mFx = d->mFx;
1012 d2->mAddr = d->mAddr==NULL ? NULL : dopyIRExpr(d->mAddr);
1013 d2->mSize = d->mSize;
sewardjc5fc7aa2004-10-27 23:00:55 +00001014 d2->needsBBP = d->needsBBP;
sewardj695cff92004-10-13 14:50:14 +00001015 d2->nFxState = d->nFxState;
1016 for (i = 0; i < d2->nFxState; i++)
1017 d2->fxState[i] = d->fxState[i];
1018 return d2;
1019}
1020
1021IRStmt* dopyIRStmt ( IRStmt* s )
1022{
1023 switch (s->tag) {
1024 case Ist_Put:
1025 return IRStmt_Put(s->Ist.Put.offset,
1026 dopyIRExpr(s->Ist.Put.data));
1027 case Ist_PutI:
1028 return IRStmt_PutI(dopyIRArray(s->Ist.PutI.descr),
sewardjeeac8412004-11-02 00:26:55 +00001029 dopyIRExpr(s->Ist.PutI.ix),
sewardj695cff92004-10-13 14:50:14 +00001030 s->Ist.PutI.bias,
1031 dopyIRExpr(s->Ist.PutI.data));
1032 case Ist_Tmp:
1033 return IRStmt_Tmp(s->Ist.Tmp.tmp,
1034 dopyIRExpr(s->Ist.Tmp.data));
1035 case Ist_STle:
1036 return IRStmt_STle(dopyIRExpr(s->Ist.STle.addr),
1037 dopyIRExpr(s->Ist.STle.data));
1038 case Ist_Dirty:
1039 return IRStmt_Dirty(dopyIRDirty(s->Ist.Dirty.details));
1040 case Ist_Exit:
sewardj893aada2004-11-29 19:57:54 +00001041 return IRStmt_Exit(dopyIRExpr(s->Ist.Exit.guard),
1042 s->Ist.Exit.jk,
sewardj695cff92004-10-13 14:50:14 +00001043 dopyIRConst(s->Ist.Exit.dst));
1044 default:
1045 vpanic("dopyIRStmt");
1046 }
1047}
1048
1049IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* src )
1050{
1051 Int i;
1052 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
1053 dst->types_size = src->types_size;
1054 dst->types_used = src->types_used;
1055 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
1056 for (i = 0; i < src->types_used; i++)
1057 dst->types[i] = src->types[i];
1058 return dst;
1059}
1060
1061IRBB* dopyIRBB ( IRBB* bb )
1062{
1063 Int i;
1064 IRStmt** sts2;
1065 IRBB* bb2 = emptyIRBB();
1066 bb2->tyenv = dopyIRTypeEnv(bb->tyenv);
1067 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
1068 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
1069 for (i = 0; i < bb2->stmts_used; i++)
1070 sts2[i] = bb->stmts[i]==NULL ? NULL : dopyIRStmt(bb->stmts[i]);
1071 bb2->stmts = sts2;
1072 bb2->next = dopyIRExpr(bb->next);
1073 bb2->jumpkind = bb->jumpkind;
1074 return bb2;
sewardjd7cb8532004-08-17 23:59:23 +00001075}
1076
sewardjec6ad592004-06-20 12:26:53 +00001077
sewardjc97096c2004-06-30 09:28:04 +00001078/*---------------------------------------------------------------*/
sewardj6efd4a12004-07-15 03:54:23 +00001079/*--- Primop types ---*/
1080/*---------------------------------------------------------------*/
1081
1082static
1083void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
1084{
1085# define UNARY(_td,_ta1) \
1086 *t_dst = (_td); *t_arg1 = (_ta1); break
1087# define BINARY(_td,_ta1,_ta2) \
1088 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
1089# define COMPARISON(_ta) \
sewardjba999312004-11-15 15:21:17 +00001090 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
sewardj6efd4a12004-07-15 03:54:23 +00001091
1092 *t_dst = Ity_INVALID;
1093 *t_arg1 = Ity_INVALID;
1094 *t_arg2 = Ity_INVALID;
1095 switch (op) {
sewardj17442fe2004-09-20 14:54:28 +00001096 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
1097 case Iop_Or8: case Iop_And8: case Iop_Xor8:
sewardj6efd4a12004-07-15 03:54:23 +00001098 BINARY(Ity_I8,Ity_I8,Ity_I8);
1099
sewardj17442fe2004-09-20 14:54:28 +00001100 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
1101 case Iop_Or16: case Iop_And16: case Iop_Xor16:
sewardj6efd4a12004-07-15 03:54:23 +00001102 BINARY(Ity_I16,Ity_I16,Ity_I16);
1103
sewardj17442fe2004-09-20 14:54:28 +00001104 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
1105 case Iop_Or32: case Iop_And32: case Iop_Xor32:
sewardj6efd4a12004-07-15 03:54:23 +00001106 BINARY(Ity_I32,Ity_I32,Ity_I32);
1107
sewardj17442fe2004-09-20 14:54:28 +00001108 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
1109 case Iop_Or64: case Iop_And64: case Iop_Xor64:
sewardj6efd4a12004-07-15 03:54:23 +00001110 BINARY(Ity_I64,Ity_I64,Ity_I64);
1111
1112 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
1113 BINARY(Ity_I8,Ity_I8,Ity_I8);
1114 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
1115 BINARY(Ity_I16,Ity_I16,Ity_I8);
1116 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
1117 BINARY(Ity_I32,Ity_I32,Ity_I8);
1118 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
1119 BINARY(Ity_I64,Ity_I64,Ity_I8);
1120
sewardj86b133b2004-11-15 13:54:26 +00001121 case Iop_Not8: UNARY(Ity_I8,Ity_I8);
1122 case Iop_Not16: UNARY(Ity_I16,Ity_I16);
1123 case Iop_Not32: UNARY(Ity_I32,Ity_I32);
1124 case Iop_Not64: UNARY(Ity_I64,Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +00001125
1126 case Iop_CmpEQ8: case Iop_CmpNE8:
1127 COMPARISON(Ity_I8);
1128 case Iop_CmpEQ16: case Iop_CmpNE16:
1129 COMPARISON(Ity_I16);
1130 case Iop_CmpEQ32: case Iop_CmpNE32:
sewardj17442fe2004-09-20 14:54:28 +00001131 case Iop_CmpLT32S: case Iop_CmpLE32S:
1132 case Iop_CmpLT32U: case Iop_CmpLE32U:
sewardj6efd4a12004-07-15 03:54:23 +00001133 COMPARISON(Ity_I32);
1134 case Iop_CmpEQ64: case Iop_CmpNE64:
1135 COMPARISON(Ity_I64);
1136
sewardjb81f8b32004-07-30 10:17:50 +00001137 case Iop_MullU8: case Iop_MullS8:
1138 BINARY(Ity_I16,Ity_I8,Ity_I8);
1139 case Iop_MullU16: case Iop_MullS16:
1140 BINARY(Ity_I32,Ity_I16,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +00001141 case Iop_MullU32: case Iop_MullS32:
1142 BINARY(Ity_I64,Ity_I32,Ity_I32);
1143
sewardj17442fe2004-09-20 14:54:28 +00001144 case Iop_Clz32: case Iop_Ctz32:
sewardjce646f22004-08-31 23:55:54 +00001145 UNARY(Ity_I32,Ity_I32);
1146
sewardj17442fe2004-09-20 14:54:28 +00001147 case Iop_DivModU64to32: case Iop_DivModS64to32:
sewardj6d2638e2004-07-15 09:38:27 +00001148 BINARY(Ity_I64,Ity_I64,Ity_I32);
1149
sewardjb81f8b32004-07-30 10:17:50 +00001150 case Iop_16HIto8: case Iop_16to8:
1151 UNARY(Ity_I8,Ity_I16);
1152 case Iop_8HLto16:
1153 BINARY(Ity_I16,Ity_I8,Ity_I8);
1154
sewardj8c7f1ab2004-07-29 20:31:09 +00001155 case Iop_32HIto16: case Iop_32to16:
1156 UNARY(Ity_I16,Ity_I32);
1157 case Iop_16HLto32:
1158 BINARY(Ity_I32,Ity_I16,Ity_I16);
1159
1160 case Iop_64HIto32: case Iop_64to32:
sewardj6d2638e2004-07-15 09:38:27 +00001161 UNARY(Ity_I32, Ity_I64);
1162 case Iop_32HLto64:
1163 BINARY(Ity_I64,Ity_I32,Ity_I32);
1164
sewardjba999312004-11-15 15:21:17 +00001165 case Iop_Not1: UNARY(Ity_I1,Ity_I1);
1166 case Iop_1Uto8: UNARY(Ity_I8,Ity_I1);
1167 case Iop_1Sto8: UNARY(Ity_I8,Ity_I1);
1168 case Iop_1Sto16: UNARY(Ity_I16,Ity_I1);
1169 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I32,Ity_I1);
1170 case Iop_1Sto64: UNARY(Ity_I64,Ity_I1);
1171 case Iop_32to1: UNARY(Ity_I1,Ity_I32);
sewardj47341042004-09-19 11:55:46 +00001172
sewardj17442fe2004-09-20 14:54:28 +00001173 case Iop_8Uto32: case Iop_8Sto32:
1174 UNARY(Ity_I32,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001175
sewardj17442fe2004-09-20 14:54:28 +00001176 case Iop_8Uto16: case Iop_8Sto16:
1177 UNARY(Ity_I16,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001178
sewardj17442fe2004-09-20 14:54:28 +00001179 case Iop_16Uto32: case Iop_16Sto32:
1180 UNARY(Ity_I32,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +00001181
sewardj17442fe2004-09-20 14:54:28 +00001182 case Iop_32Sto64: case Iop_32Uto64:
1183 UNARY(Ity_I64,Ity_I32);
1184
1185 case Iop_32to8: UNARY(Ity_I8,Ity_I32);
1186
sewardj442d0be2004-10-15 22:57:13 +00001187 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
sewardj17442fe2004-09-20 14:54:28 +00001188 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
1189 case Iop_AddF64: case Iop_SubF64: case Iop_MulF64: case Iop_DivF64:
sewardja58ea662004-08-15 03:12:41 +00001190 BINARY(Ity_F64,Ity_F64,Ity_F64);
sewardj442d0be2004-10-15 22:57:13 +00001191 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
sewardjbdc7d212004-09-09 02:46:40 +00001192 case Iop_CmpF64:
1193 BINARY(Ity_I32,Ity_F64,Ity_F64);
sewardj883b00b2004-09-11 09:30:24 +00001194 case Iop_NegF64: case Iop_AbsF64: case Iop_SqrtF64:
sewardj99016a72004-10-15 22:09:17 +00001195 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: case Iop_2xm1F64:
sewardjcfded9a2004-09-09 11:44:16 +00001196 UNARY(Ity_F64,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001197
sewardj3bca9062004-12-04 14:36:09 +00001198 case Iop_ReinterpI64asF64: UNARY(Ity_F64, Ity_I64);
sewardj17442fe2004-09-20 14:54:28 +00001199 case Iop_ReinterpF64asI64: UNARY(Ity_I64, Ity_F64);
sewardjfd226452004-12-07 19:02:18 +00001200 case Iop_ReinterpI32asF32: UNARY(Ity_F32, Ity_I32);
1201 case Iop_ReinterpF32asI32: UNARY(Ity_I32, Ity_F32);
sewardj8f3debf2004-09-08 23:42:23 +00001202
sewardj3bca9062004-12-04 14:36:09 +00001203 case Iop_F64toI16: BINARY(Ity_I16, Ity_I32,Ity_F64);
1204 case Iop_F64toI32: BINARY(Ity_I32, Ity_I32,Ity_F64);
1205 case Iop_F64toI64: BINARY(Ity_I64, Ity_I32,Ity_F64);
1206
1207 case Iop_I16toF64: UNARY(Ity_F64, Ity_I16);
1208 case Iop_I32toF64: UNARY(Ity_F64, Ity_I32);
sewardj4cb918d2004-12-03 19:43:31 +00001209 case Iop_I64toF64: BINARY(Ity_F64, Ity_I32,Ity_I64);
1210
sewardj3bca9062004-12-04 14:36:09 +00001211 case Iop_F32toF64: UNARY(Ity_F64, Ity_F32);
1212 case Iop_F64toF32: BINARY(Ity_F32, Ity_I32,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001213
sewardj3bca9062004-12-04 14:36:09 +00001214 case Iop_RoundF64: BINARY(Ity_F64, Ity_I32,Ity_F64);
sewardjbb53f8c2004-08-14 11:50:01 +00001215
sewardjc9a43662004-11-30 18:51:59 +00001216 case Iop_64HLto128: BINARY(Ity_V128, Ity_I64,Ity_I64);
1217 case Iop_128to64: case Iop_128HIto64:
1218 UNARY(Ity_I64, Ity_V128);
1219
sewardj129b3d92004-12-05 15:42:05 +00001220 case Iop_32Uto128: UNARY(Ity_V128, Ity_I32);
sewardj636ad762004-12-07 11:16:04 +00001221 case Iop_64Uto128: UNARY(Ity_V128, Ity_I64);
sewardj129b3d92004-12-05 15:42:05 +00001222 case Iop_Set128lo32: BINARY(Ity_V128, Ity_V128,Ity_I32);
sewardj008754b2004-12-08 14:37:10 +00001223 case Iop_Set128lo64: BINARY(Ity_V128, Ity_V128,Ity_I64);
sewardj129b3d92004-12-05 15:42:05 +00001224
sewardj1e6ad742004-12-02 16:16:11 +00001225 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001226 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2:
sewardj1e6ad742004-12-02 16:16:11 +00001227 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
sewardj636ad762004-12-07 11:16:04 +00001228 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2:
sewardj1e6ad742004-12-02 16:16:11 +00001229 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001230 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001231 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001232 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001233 case Iop_Add32Fx4: case Iop_Add32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001234 case Iop_Add64Fx2: case Iop_Add64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001235 case Iop_Div32Fx4: case Iop_Div32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001236 case Iop_Div64Fx2: case Iop_Div64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001237 case Iop_Max32Fx4: case Iop_Max32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001238 case Iop_Max64Fx2: case Iop_Max64F0x2:
sewardj176a59c2004-12-03 20:08:31 +00001239 case Iop_Min32Fx4: case Iop_Min32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001240 case Iop_Min64Fx2: case Iop_Min64F0x2:
sewardj9636b442004-12-04 01:38:37 +00001241 case Iop_Mul32Fx4: case Iop_Mul32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001242 case Iop_Mul64Fx2: case Iop_Mul64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001243 case Iop_Sub32Fx4: case Iop_Sub32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001244 case Iop_Sub64Fx2: case Iop_Sub64F0x2:
sewardj1e6ad742004-12-02 16:16:11 +00001245 case Iop_And128: case Iop_Or128: case Iop_Xor128:
sewardj164f9272004-12-09 00:39:32 +00001246 case Iop_Add8x16: case Iop_Add16x8:
1247 case Iop_Add32x4: case Iop_Add64x2:
1248 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8:
1249 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8:
1250 case Iop_Sub8x16: case Iop_Sub16x8:
1251 case Iop_Sub32x4: case Iop_Sub64x2:
1252 case Iop_QSub8Ux16: case Iop_QSub16Ux8:
1253 case Iop_QSub8Sx16: case Iop_QSub16Sx8:
1254 case Iop_Mul16x8:
1255 case Iop_MulHi16Ux8:
1256 case Iop_MulHi16Sx8:
1257 case Iop_Avg8Ux16:
1258 case Iop_Avg16Ux8:
1259 case Iop_Max16Sx8:
1260 case Iop_Max8Ux16:
1261 case Iop_Min16Sx8:
1262 case Iop_Min8Ux16:
1263 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
1264 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
1265 case Iop_QNarrow16Ux8:
1266 case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4:
1267 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
1268 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
1269 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
1270 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
sewardjc9a43662004-11-30 18:51:59 +00001271 BINARY(Ity_V128, Ity_V128,Ity_V128);
1272
sewardj0bd7ce62004-12-05 02:47:40 +00001273 case Iop_Recip32Fx4: case Iop_Recip32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001274 case Iop_Recip64Fx2: case Iop_Recip64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001275 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001276 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
sewardjc1e7dfc2004-12-05 19:29:45 +00001277 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4:
sewardj636ad762004-12-07 11:16:04 +00001278 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2:
sewardj70f676d2004-12-10 14:59:57 +00001279 case Iop_CmpNEZ32x4:
sewardj0bd7ce62004-12-05 02:47:40 +00001280 UNARY(Ity_V128, Ity_V128);
1281
sewardj164f9272004-12-09 00:39:32 +00001282 case Iop_ShlN16x8: case Iop_ShlN32x4: case Iop_ShlN64x2:
1283 case Iop_ShrN16x8: case Iop_ShrN32x4: case Iop_ShrN64x2:
1284 case Iop_SarN16x8: case Iop_SarN32x4:
1285 BINARY(Ity_V128, Ity_V128, Ity_I8);
1286
sewardj6efd4a12004-07-15 03:54:23 +00001287 default:
1288 ppIROp(op);
1289 vpanic("typeOfPrimop");
1290 }
1291# undef UNARY
1292# undef BINARY
1293# undef COMPARISON
1294}
1295
1296
1297/*---------------------------------------------------------------*/
sewardj695cff92004-10-13 14:50:14 +00001298/*--- Helper functions for the IR -- IR Basic Blocks ---*/
sewardjc97096c2004-06-30 09:28:04 +00001299/*---------------------------------------------------------------*/
1300
sewardj695cff92004-10-13 14:50:14 +00001301void addStmtToIRBB ( IRBB* bb, IRStmt* st )
sewardjd7cb8532004-08-17 23:59:23 +00001302{
1303 Int i;
sewardj695cff92004-10-13 14:50:14 +00001304 if (bb->stmts_used == bb->stmts_size) {
1305 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1306 for (i = 0; i < bb->stmts_size; i++)
1307 stmts2[i] = bb->stmts[i];
1308 bb->stmts = stmts2;
1309 bb->stmts_size *= 2;
1310 }
1311 vassert(bb->stmts_used < bb->stmts_size);
1312 bb->stmts[bb->stmts_used] = st;
1313 bb->stmts_used++;
sewardjd7cb8532004-08-17 23:59:23 +00001314}
1315
sewardj695cff92004-10-13 14:50:14 +00001316
1317/*---------------------------------------------------------------*/
1318/*--- Helper functions for the IR -- IR Type Environments ---*/
1319/*---------------------------------------------------------------*/
1320
sewardjd7cb8532004-08-17 23:59:23 +00001321/* Allocate a new IRTemp, given its type. */
sewardje3d0d2e2004-06-27 10:42:44 +00001322
sewardje539a402004-07-14 18:24:17 +00001323IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
sewardjc97096c2004-06-30 09:28:04 +00001324{
sewardj35421a32004-07-05 13:12:34 +00001325 vassert(env);
sewardje539a402004-07-14 18:24:17 +00001326 vassert(env->types_used >= 0);
1327 vassert(env->types_size >= 0);
1328 vassert(env->types_used <= env->types_size);
1329 if (env->types_used < env->types_size) {
1330 env->types[env->types_used] = ty;
1331 return env->types_used++;
sewardjc97096c2004-06-30 09:28:04 +00001332 } else {
1333 Int i;
sewardje539a402004-07-14 18:24:17 +00001334 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
1335 IRType* new_types
1336 = LibVEX_Alloc(new_size * sizeof(IRType));
1337 for (i = 0; i < env->types_used; i++)
1338 new_types[i] = env->types[i];
1339 env->types = new_types;
1340 env->types_size = new_size;
1341 return newIRTemp(env, ty);
sewardjc97096c2004-06-30 09:28:04 +00001342 }
1343}
1344
1345
sewardj17442fe2004-09-20 14:54:28 +00001346/*---------------------------------------------------------------*/
1347/*--- Helper functions for the IR -- finding types of exprs ---*/
1348/*---------------------------------------------------------------*/
1349
sewardjedeb4c42004-09-21 23:39:25 +00001350inline
sewardj17442fe2004-09-20 14:54:28 +00001351IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
sewardjc97096c2004-06-30 09:28:04 +00001352{
sewardje539a402004-07-14 18:24:17 +00001353 vassert(tmp >= 0);
1354 vassert(tmp < env->types_used);
1355 return env->types[tmp];
sewardjc97096c2004-06-30 09:28:04 +00001356}
1357
1358
sewardj6efd4a12004-07-15 03:54:23 +00001359IRType typeOfIRConst ( IRConst* con )
1360{
1361 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +00001362 case Ico_U1: return Ity_I1;
sewardj207557a2004-08-27 12:00:18 +00001363 case Ico_U8: return Ity_I8;
1364 case Ico_U16: return Ity_I16;
1365 case Ico_U32: return Ity_I32;
1366 case Ico_U64: return Ity_I64;
1367 case Ico_F64: return Ity_F64;
sewardj17442fe2004-09-20 14:54:28 +00001368 case Ico_F64i: return Ity_F64;
sewardj1e6ad742004-12-02 16:16:11 +00001369 case Ico_V128: return Ity_V128;
sewardj6efd4a12004-07-15 03:54:23 +00001370 default: vpanic("typeOfIRConst");
1371 }
1372}
1373
sewardjc97096c2004-06-30 09:28:04 +00001374IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
1375{
sewardj6efd4a12004-07-15 03:54:23 +00001376 IRType t_dst, t_arg1, t_arg2;
sewardjedeb4c42004-09-21 23:39:25 +00001377 start:
sewardjc97096c2004-06-30 09:28:04 +00001378 switch (e->tag) {
sewardje05c42c2004-07-08 20:25:10 +00001379 case Iex_LDle:
1380 return e->Iex.LDle.ty;
sewardjfbcaf332004-07-08 01:46:01 +00001381 case Iex_Get:
1382 return e->Iex.Get.ty;
sewardjbb53f8c2004-08-14 11:50:01 +00001383 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +00001384 return e->Iex.GetI.descr->elemTy;
sewardjc97096c2004-06-30 09:28:04 +00001385 case Iex_Tmp:
sewardj17442fe2004-09-20 14:54:28 +00001386 return typeOfIRTemp(tyenv, e->Iex.Tmp.tmp);
sewardjc97096c2004-06-30 09:28:04 +00001387 case Iex_Const:
sewardj695cff92004-10-13 14:50:14 +00001388 return typeOfIRConst(e->Iex.Const.con);
sewardjc97096c2004-06-30 09:28:04 +00001389 case Iex_Binop:
sewardj6efd4a12004-07-15 03:54:23 +00001390 typeOfPrimop(e->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1391 return t_dst;
1392 case Iex_Unop:
1393 typeOfPrimop(e->Iex.Unop.op, &t_dst, &t_arg1, &t_arg2);
1394 return t_dst;
1395 case Iex_CCall:
1396 return e->Iex.CCall.retty;
sewardj4042c7e2004-07-18 01:28:30 +00001397 case Iex_Mux0X:
sewardjedeb4c42004-09-21 23:39:25 +00001398 e = e->Iex.Mux0X.expr0;
1399 goto start;
1400 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
sewardj443cd9d2004-07-18 23:06:45 +00001401 case Iex_Binder:
1402 vpanic("typeOfIRExpr: Binder is not a valid expression");
sewardjc97096c2004-06-30 09:28:04 +00001403 default:
sewardj6efd4a12004-07-15 03:54:23 +00001404 ppIRExpr(e);
1405 vpanic("typeOfIRExpr");
sewardjc97096c2004-06-30 09:28:04 +00001406 }
sewardjc97096c2004-06-30 09:28:04 +00001407}
sewardj887a11a2004-07-05 17:26:47 +00001408
sewardj6d2638e2004-07-15 09:38:27 +00001409/* Is this any value actually in the enumeration 'IRType' ? */
1410Bool isPlausibleType ( IRType ty )
1411{
1412 switch (ty) {
sewardjba999312004-11-15 15:21:17 +00001413 case Ity_INVALID: case Ity_I1:
sewardj6d2638e2004-07-15 09:38:27 +00001414 case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64:
sewardjbb53f8c2004-08-14 11:50:01 +00001415 case Ity_F32: case Ity_F64:
sewardjc9a43662004-11-30 18:51:59 +00001416 case Ity_V128:
sewardj6d2638e2004-07-15 09:38:27 +00001417 return True;
1418 default:
1419 return False;
1420 }
1421}
1422
sewardj6efd4a12004-07-15 03:54:23 +00001423
sewardj887a11a2004-07-05 17:26:47 +00001424/*---------------------------------------------------------------*/
sewardjcf787902004-11-03 09:08:33 +00001425/*--- Sanity checking -- FLATNESS ---*/
1426/*---------------------------------------------------------------*/
1427
1428/* Check that the canonical flatness constraints hold on an
1429 IRStmt. The only place where any expression is allowed to be
1430 non-atomic is the RHS of IRStmt_Tmp. */
1431
1432/* Relies on:
1433 inline static Bool isAtom ( IRExpr* e ) {
1434 return e->tag == Iex_Tmp || e->tag == Iex_Const;
1435 }
1436*/
1437
1438Bool isFlatIRStmt ( IRStmt* st )
1439{
1440 Int i;
1441 IRExpr* e;
1442 IRDirty* di;
1443
1444 switch (st->tag) {
1445 case Ist_Put:
1446 return isAtom(st->Ist.Put.data);
1447 case Ist_PutI:
1448 return isAtom(st->Ist.PutI.ix) && isAtom(st->Ist.PutI.data);
1449 case Ist_Tmp:
1450 /* This is the only interesting case. The RHS can be any
1451 expression, *but* all its subexpressions *must* be
1452 atoms. */
1453 e = st->Ist.Tmp.data;
1454 switch (e->tag) {
1455 case Iex_Binder: return True;
1456 case Iex_Get: return True;
1457 case Iex_GetI: return isAtom(e->Iex.GetI.ix);
1458 case Iex_Tmp: return True;
1459 case Iex_Binop: return isAtom(e->Iex.Binop.arg1)
1460 && isAtom(e->Iex.Binop.arg2);
1461 case Iex_Unop: return isAtom(e->Iex.Unop.arg);
1462 case Iex_LDle: return isAtom(e->Iex.LDle.addr);
1463 case Iex_Const: return True;
1464 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
1465 if (!isAtom(e->Iex.CCall.args[i]))
1466 return False;
1467 return True;
1468 case Iex_Mux0X: return isAtom(e->Iex.Mux0X.cond)
1469 && isAtom(e->Iex.Mux0X.expr0)
1470 && isAtom(e->Iex.Mux0X.exprX);
1471 default: vpanic("isFlatIRStmt(e)");
1472 }
1473 /*notreached*/
1474 vassert(0);
1475 case Ist_STle:
1476 return isAtom(st->Ist.STle.addr) && isAtom(st->Ist.STle.data);
1477 case Ist_Dirty:
1478 di = st->Ist.Dirty.details;
1479 if (!isAtom(di->guard))
1480 return False;
1481 for (i = 0; di->args[i]; i++)
1482 if (!isAtom(di->args[i]))
1483 return False;
1484 if (di->mAddr && !isAtom(di->mAddr))
1485 return False;
1486 return True;
1487 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001488 return isAtom(st->Ist.Exit.guard);
sewardjcf787902004-11-03 09:08:33 +00001489 default:
1490 vpanic("isFlatIRStmt(st)");
1491 }
1492}
1493
1494
1495/*---------------------------------------------------------------*/
sewardje539a402004-07-14 18:24:17 +00001496/*--- Sanity checking ---*/
1497/*---------------------------------------------------------------*/
1498
1499/* Checks:
1500
1501 Everything is type-consistent. No ill-typed anything.
sewardj35439212004-07-14 22:36:10 +00001502 The target address at the end of the BB is a 32- or 64-
1503 bit expression, depending on the guest's word size.
sewardje539a402004-07-14 18:24:17 +00001504
1505 Each temp is assigned only once, before its uses.
sewardjc13e2ed2004-10-31 21:44:54 +00001506*/
1507
1508static inline Int countArgs ( IRExpr** args )
1509{
1510 Int i;
1511 for (i = 0; args[i]; i++)
1512 ;
1513 return i;
1514}
sewardje539a402004-07-14 18:24:17 +00001515
sewardj35439212004-07-14 22:36:10 +00001516static
1517__attribute((noreturn))
1518void sanityCheckFail ( IRBB* bb, IRStmt* stmt, Char* what )
sewardje539a402004-07-14 18:24:17 +00001519{
sewardj35439212004-07-14 22:36:10 +00001520 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
1521 ppIRBB(bb);
1522 if (stmt) {
1523 vex_printf("\nIN STATEMENT:\n\n");
1524 ppIRStmt(stmt);
1525 }
1526 vex_printf("\n\nERROR = %s\n\n", what );
1527 vpanic("sanityCheckFail: exiting due to bad IR");
1528}
1529
sewardj2d3f77c2004-09-22 23:49:09 +00001530static Bool saneIRArray ( IRArray* arr )
1531{
1532 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
1533 return False;
sewardjba999312004-11-15 15:21:17 +00001534 if (arr->elemTy == Ity_I1)
sewardj2d3f77c2004-09-22 23:49:09 +00001535 return False;
1536 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
1537 return False;
1538 return True;
1539}
1540
sewardj8ea867b2004-10-30 19:03:02 +00001541static Bool saneIRCallee ( IRCallee* cee )
1542{
1543 if (cee->name == NULL)
1544 return False;
1545 if (cee->addr == 0)
1546 return False;
sewardj77352542004-10-30 20:39:01 +00001547 if (cee->regparms < 0 || cee->regparms > 3)
sewardj8ea867b2004-10-30 19:03:02 +00001548 return False;
1549 return True;
1550}
1551
sewardj49bfe672004-11-15 15:46:26 +00001552static Bool saneIRConst ( IRConst* con )
1553{
1554 switch (con->tag) {
1555 case Ico_U1:
1556 return con->Ico.U1 == True || con->Ico.U1 == False;
1557 default:
1558 /* Is there anything we can meaningfully check? I don't
1559 think so. */
1560 return True;
1561 }
1562}
sewardj35439212004-07-14 22:36:10 +00001563
1564/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
1565 range ones. Report any which are read and for which the current
1566 def_count is zero. */
1567
1568static
sewardj17442fe2004-09-20 14:54:28 +00001569void useBeforeDef_Temp ( IRBB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
1570{
1571 if (tmp < 0 || tmp >= bb->tyenv->types_used)
1572 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
1573 if (def_counts[tmp] < 1)
1574 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
1575}
1576
1577static
sewardj35439212004-07-14 22:36:10 +00001578void useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
1579{
1580 Int i;
1581 switch (expr->tag) {
1582 case Iex_Get:
1583 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001584 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001585 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
sewardjbb53f8c2004-08-14 11:50:01 +00001586 break;
sewardj17442fe2004-09-20 14:54:28 +00001587 case Iex_Tmp:
1588 useBeforeDef_Temp(bb,stmt,expr->Iex.Tmp.tmp,def_counts);
sewardj35439212004-07-14 22:36:10 +00001589 break;
1590 case Iex_Binop:
1591 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
1592 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
1593 break;
1594 case Iex_Unop:
1595 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
1596 break;
1597 case Iex_LDle:
1598 useBeforeDef_Expr(bb,stmt,expr->Iex.LDle.addr,def_counts);
1599 break;
1600 case Iex_Const:
1601 break;
1602 case Iex_CCall:
1603 for (i = 0; expr->Iex.CCall.args[i]; i++)
1604 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
1605 break;
sewardj4042c7e2004-07-18 01:28:30 +00001606 case Iex_Mux0X:
1607 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
1608 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
1609 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
sewardjeeb9ef82004-07-15 12:39:03 +00001610 break;
1611 default:
1612 vpanic("useBeforeDef_Expr");
sewardj35439212004-07-14 22:36:10 +00001613 }
1614}
1615
1616static
1617void useBeforeDef_Stmt ( IRBB* bb, IRStmt* stmt, Int* def_counts )
1618{
sewardj17442fe2004-09-20 14:54:28 +00001619 Int i;
1620 IRDirty* d;
sewardj35439212004-07-14 22:36:10 +00001621 switch (stmt->tag) {
1622 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001623 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001624 break;
sewardjd1725d12004-08-12 20:46:53 +00001625 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +00001626 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
sewardj2d3f77c2004-09-22 23:49:09 +00001627 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
sewardjd1725d12004-08-12 20:46:53 +00001628 break;
sewardj35439212004-07-14 22:36:10 +00001629 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001630 useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001631 break;
1632 case Ist_STle:
1633 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.addr,def_counts);
1634 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.data,def_counts);
1635 break;
sewardj17442fe2004-09-20 14:54:28 +00001636 case Ist_Dirty:
1637 d = stmt->Ist.Dirty.details;
1638 for (i = 0; d->args[i] != NULL; i++)
1639 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
1640 if (d->mFx != Ifx_None)
1641 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
1642 break;
sewardj35439212004-07-14 22:36:10 +00001643 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001644 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
sewardj35439212004-07-14 22:36:10 +00001645 break;
1646 default:
1647 vpanic("useBeforeDef_Stmt");
1648 }
1649}
1650
sewardj6efd4a12004-07-15 03:54:23 +00001651static
1652void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
1653{
1654 Int i;
1655 IRType t_dst, t_arg1, t_arg2;
1656 IRTypeEnv* tyenv = bb->tyenv;
1657 switch (expr->tag) {
1658 case Iex_Get:
1659 case Iex_Tmp:
1660 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001661 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001662 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
1663 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
1664 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001665 if (!saneIRArray(expr->Iex.GetI.descr))
1666 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
sewardjbb53f8c2004-08-14 11:50:01 +00001667 break;
sewardj6d2638e2004-07-15 09:38:27 +00001668 case Iex_Binop: {
1669 IRType ttarg1, ttarg2;
sewardj6efd4a12004-07-15 03:54:23 +00001670 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
1671 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
1672 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
sewardj8f3debf2004-09-08 23:42:23 +00001673 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID) {
1674 vex_printf(" op name: " );
1675 ppIROp(expr->Iex.Binop.op);
1676 vex_printf("\n");
1677 sanityCheckFail(bb,stmt,
1678 "Iex.Binop: wrong arity op\n"
1679 "... name of op precedes BB printout\n");
1680 }
sewardj6d2638e2004-07-15 09:38:27 +00001681 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
1682 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
1683 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
1684 vex_printf(" op name: ");
1685 ppIROp(expr->Iex.Binop.op);
1686 vex_printf("\n");
1687 vex_printf(" op type is (");
1688 ppIRType(t_arg1);
1689 vex_printf(",");
1690 ppIRType(t_arg2);
1691 vex_printf(") -> ");
1692 ppIRType (t_dst);
1693 vex_printf("\narg tys are (");
1694 ppIRType(ttarg1);
1695 vex_printf(",");
1696 ppIRType(ttarg2);
1697 vex_printf(")\n");
1698 sanityCheckFail(bb,stmt,
1699 "Iex.Binop: arg tys don't match op tys\n"
1700 "... additional details precede BB printout\n");
sewardj695cff92004-10-13 14:50:14 +00001701 }
sewardj6efd4a12004-07-15 03:54:23 +00001702 break;
sewardj6d2638e2004-07-15 09:38:27 +00001703 }
sewardj6efd4a12004-07-15 03:54:23 +00001704 case Iex_Unop:
1705 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
1706 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1707 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID)
1708 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
1709 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
1710 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
1711 break;
1712 case Iex_LDle:
1713 tcExpr(bb,stmt, expr->Iex.LDle.addr, gWordTy);
1714 if (typeOfIRExpr(tyenv, expr->Iex.LDle.addr) != gWordTy)
1715 sanityCheckFail(bb,stmt,"Iex.LDle.addr: not :: guest word type");
1716 break;
1717 case Iex_CCall:
sewardjc13e2ed2004-10-31 21:44:54 +00001718 if (!saneIRCallee(expr->Iex.CCall.cee))
1719 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
sewardjcf787902004-11-03 09:08:33 +00001720 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
sewardjc13e2ed2004-10-31 21:44:54 +00001721 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
sewardj43c56462004-11-06 12:17:57 +00001722 for (i = 0; expr->Iex.CCall.args[i]; i++) {
1723 if (i >= 32)
1724 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
sewardj6efd4a12004-07-15 03:54:23 +00001725 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
sewardj43c56462004-11-06 12:17:57 +00001726 }
sewardjba999312004-11-15 15:21:17 +00001727 if (expr->Iex.CCall.retty == Ity_I1)
1728 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001729 for (i = 0; expr->Iex.CCall.args[i]; i++)
sewardjba999312004-11-15 15:21:17 +00001730 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
1731 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001732 break;
1733 case Iex_Const:
sewardj49bfe672004-11-15 15:46:26 +00001734 if (!saneIRConst(expr->Iex.Const.con))
1735 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
sewardj6efd4a12004-07-15 03:54:23 +00001736 break;
sewardj4042c7e2004-07-18 01:28:30 +00001737 case Iex_Mux0X:
1738 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
1739 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
1740 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
1741 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
1742 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
1743 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
1744 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
1745 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
sewardjeeb9ef82004-07-15 12:39:03 +00001746 break;
1747 default:
sewardj6efd4a12004-07-15 03:54:23 +00001748 vpanic("tcExpr");
1749 }
1750}
1751
1752
1753static
1754void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
1755{
sewardj17442fe2004-09-20 14:54:28 +00001756 Int i;
1757 IRDirty* d;
sewardj6efd4a12004-07-15 03:54:23 +00001758 IRTypeEnv* tyenv = bb->tyenv;
1759 switch (stmt->tag) {
1760 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001761 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001762 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
1763 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
sewardj2d3f77c2004-09-22 23:49:09 +00001764 break;
sewardjd1725d12004-08-12 20:46:53 +00001765 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +00001766 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
sewardjeeac8412004-11-02 00:26:55 +00001767 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001768 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
1769 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
sewardj6d076362004-09-23 11:06:17 +00001770 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data)
1771 != stmt->Ist.PutI.descr->elemTy)
1772 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
sewardjeeac8412004-11-02 00:26:55 +00001773 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
1774 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001775 if (!saneIRArray(stmt->Ist.PutI.descr))
1776 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
1777 break;
sewardj6efd4a12004-07-15 03:54:23 +00001778 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001779 tcExpr( bb, stmt, stmt->Ist.Tmp.data, gWordTy );
sewardj17442fe2004-09-20 14:54:28 +00001780 if (typeOfIRTemp(tyenv, stmt->Ist.Tmp.tmp)
sewardj6d076362004-09-23 11:06:17 +00001781 != typeOfIRExpr(tyenv, stmt->Ist.Tmp.data))
sewardj6d2638e2004-07-15 09:38:27 +00001782 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
sewardj6efd4a12004-07-15 03:54:23 +00001783 break;
1784 case Ist_STle:
1785 tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
1786 tcExpr( bb, stmt, stmt->Ist.STle.data, gWordTy );
1787 if (typeOfIRExpr(tyenv, stmt->Ist.STle.addr) != gWordTy)
1788 sanityCheckFail(bb,stmt,"IRStmt.STle.addr: not :: guest word type");
sewardjba999312004-11-15 15:21:17 +00001789 if (typeOfIRExpr(tyenv, stmt->Ist.STle.data) == Ity_I1)
1790 sanityCheckFail(bb,stmt,"IRStmt.STle.data: cannot STle :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001791 break;
sewardj17442fe2004-09-20 14:54:28 +00001792 case Ist_Dirty:
1793 /* Mostly check for various kinds of ill-formed dirty calls. */
1794 d = stmt->Ist.Dirty.details;
sewardj8ea867b2004-10-30 19:03:02 +00001795 if (d->cee == NULL) goto bad_dirty;
1796 if (!saneIRCallee(d->cee)) goto bad_dirty;
sewardjcf787902004-11-03 09:08:33 +00001797 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001798 if (d->mFx == Ifx_None) {
1799 if (d->mAddr != NULL || d->mSize != 0)
1800 goto bad_dirty;
1801 } else {
1802 if (d->mAddr == NULL || d->mSize == 0)
1803 goto bad_dirty;
1804 }
1805 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
1806 goto bad_dirty;
sewardjc5fc7aa2004-10-27 23:00:55 +00001807 if (d->nFxState == 0 && d->needsBBP)
1808 goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001809 for (i = 0; i < d->nFxState; i++) {
1810 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
1811 if (d->fxState[i].size <= 0) goto bad_dirty;
1812 }
1813 /* check types, minimally */
sewardjb8385d82004-11-02 01:34:15 +00001814 if (d->guard == NULL) goto bad_dirty;
sewardj49bfe672004-11-15 15:46:26 +00001815 tcExpr( bb, stmt, d->guard, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001816 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
1817 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
sewardj92d168d2004-11-15 14:22:12 +00001818 if (d->tmp != IRTemp_INVALID
sewardjba999312004-11-15 15:21:17 +00001819 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
1820 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001821 for (i = 0; d->args[i] != NULL; i++) {
sewardj43c56462004-11-06 12:17:57 +00001822 if (i >= 32)
1823 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
sewardjba999312004-11-15 15:21:17 +00001824 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
1825 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001826 }
1827 break;
1828 bad_dirty:
1829 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
1830
sewardj6efd4a12004-07-15 03:54:23 +00001831 case Ist_Exit:
sewardj0276d4b2004-11-15 15:30:21 +00001832 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
1833 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
1834 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
sewardj49bfe672004-11-15 15:46:26 +00001835 if (!saneIRConst(stmt->Ist.Exit.dst))
1836 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
sewardj6efd4a12004-07-15 03:54:23 +00001837 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
1838 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
1839 break;
1840 default:
1841 vpanic("tcStmt");
1842 }
1843}
1844
sewardj35439212004-07-14 22:36:10 +00001845void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
1846{
1847 Int i;
1848 IRStmt* stmt;
1849 Int n_temps = bb->tyenv->types_used;
1850 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
1851
1852 vassert(guest_word_size == Ity_I32
sewardj695cff92004-10-13 14:50:14 +00001853 || guest_word_size == Ity_I64);
sewardj35439212004-07-14 22:36:10 +00001854
sewardjd7cb8532004-08-17 23:59:23 +00001855 if (bb->stmts_used < 0 || bb->stmts_size < 8
1856 || bb->stmts_used > bb->stmts_size)
1857 /* this BB is so strange we can't even print it */
1858 vpanic("sanityCheckIRBB: stmts array limits wierd");
1859
sewardj6d2638e2004-07-15 09:38:27 +00001860 /* Ensure each temp has a plausible type. */
1861 for (i = 0; i < n_temps; i++) {
sewardj17442fe2004-09-20 14:54:28 +00001862 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
sewardj6d2638e2004-07-15 09:38:27 +00001863 if (!isPlausibleType(ty)) {
1864 vex_printf("Temp t%d declared with implausible type 0x%x\n",
1865 i, (UInt)ty);
1866 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
1867 }
1868 }
sewardj35439212004-07-14 22:36:10 +00001869
1870 /* Count the defs of each temp. Only one def is allowed.
1871 Also, check that each used temp has already been defd. */
sewardj6d2638e2004-07-15 09:38:27 +00001872
1873 for (i = 0; i < n_temps; i++)
1874 def_counts[i] = 0;
1875
sewardjd7cb8532004-08-17 23:59:23 +00001876 for (i = 0; i < bb->stmts_used; i++) {
1877 stmt = bb->stmts[i];
sewardj39e3f242004-08-18 16:54:52 +00001878 if (!stmt)
1879 continue;
sewardj35439212004-07-14 22:36:10 +00001880 useBeforeDef_Stmt(bb,stmt,def_counts);
sewardj17442fe2004-09-20 14:54:28 +00001881
sewardj35439212004-07-14 22:36:10 +00001882 if (stmt->tag == Ist_Tmp) {
1883 if (stmt->Ist.Tmp.tmp < 0 || stmt->Ist.Tmp.tmp >= n_temps)
sewardj17442fe2004-09-20 14:54:28 +00001884 sanityCheckFail(bb, stmt,
1885 "IRStmt.Tmp: destination tmp is out of range");
sewardj35439212004-07-14 22:36:10 +00001886 def_counts[stmt->Ist.Tmp.tmp]++;
1887 if (def_counts[stmt->Ist.Tmp.tmp] > 1)
sewardj17442fe2004-09-20 14:54:28 +00001888 sanityCheckFail(bb, stmt,
sewardjcf787902004-11-03 09:08:33 +00001889 "IRStmt.Tmp: destination tmp is assigned more than once");
sewardj17442fe2004-09-20 14:54:28 +00001890 }
1891 else
1892 if (stmt->tag == Ist_Dirty
sewardj92d168d2004-11-15 14:22:12 +00001893 && stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
sewardj17442fe2004-09-20 14:54:28 +00001894 IRDirty* d = stmt->Ist.Dirty.details;
1895 if (d->tmp < 0 || d->tmp >= n_temps)
1896 sanityCheckFail(bb, stmt,
1897 "IRStmt.Dirty: destination tmp is out of range");
1898 def_counts[d->tmp]++;
1899 if (def_counts[d->tmp] > 1)
1900 sanityCheckFail(bb, stmt,
1901 "IRStmt.Dirty: destination tmp is assigned more than once");
sewardj35439212004-07-14 22:36:10 +00001902 }
1903 }
1904
sewardj6efd4a12004-07-15 03:54:23 +00001905 /* Typecheck everything. */
sewardjd7cb8532004-08-17 23:59:23 +00001906 for (i = 0; i < bb->stmts_used; i++)
sewardj39e3f242004-08-18 16:54:52 +00001907 if (bb->stmts[i])
1908 tcStmt( bb, bb->stmts[i], guest_word_size );
sewardj6efd4a12004-07-15 03:54:23 +00001909 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
1910 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
sewardje539a402004-07-14 18:24:17 +00001911}
1912
sewardj4345f7a2004-09-22 19:49:27 +00001913/*---------------------------------------------------------------*/
1914/*--- Misc helper functions ---*/
1915/*---------------------------------------------------------------*/
1916
1917Bool eqIRConst ( IRConst* c1, IRConst* c2 )
1918{
1919 if (c1->tag != c2->tag)
1920 return False;
1921
1922 switch (c1->tag) {
sewardjba999312004-11-15 15:21:17 +00001923 case Ico_U1: return (1 & c1->Ico.U1) == (1 & c2->Ico.U1);
sewardj4345f7a2004-09-22 19:49:27 +00001924 case Ico_U8: return c1->Ico.U8 == c2->Ico.U8;
1925 case Ico_U16: return c1->Ico.U16 == c2->Ico.U16;
1926 case Ico_U32: return c1->Ico.U32 == c2->Ico.U32;
1927 case Ico_U64: return c1->Ico.U64 == c2->Ico.U64;
1928 case Ico_F64: return c1->Ico.F64 == c2->Ico.F64;
1929 default: vpanic("eqIRConst");
1930 }
1931}
1932
sewardje98dcf22004-10-04 09:15:11 +00001933Bool eqIRArray ( IRArray* descr1, IRArray* descr2 )
1934{
1935 return descr1->base == descr2->base
1936 && descr1->elemTy == descr2->elemTy
1937 && descr1->nElems == descr2->nElems;
1938}
1939
sewardj2d3f77c2004-09-22 23:49:09 +00001940Int sizeofIRType ( IRType ty )
1941{
1942 switch (ty) {
sewardjc9a43662004-11-30 18:51:59 +00001943 case Ity_I8: return 1;
1944 case Ity_I16: return 2;
1945 case Ity_I32: return 4;
1946 case Ity_I64: return 8;
1947 case Ity_F32: return 4;
1948 case Ity_F64: return 8;
1949 case Ity_V128: return 16;
sewardj2d3f77c2004-09-22 23:49:09 +00001950 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
1951 vpanic("sizeofIRType");
1952 }
1953}
1954
sewardj49651f42004-10-28 22:11:04 +00001955IRExpr* mkIRExpr_HWord ( HWord hw )
1956{
sewardjf9655262004-10-31 20:02:16 +00001957 vassert(sizeof(void*) == sizeof(HWord));
sewardj49651f42004-10-28 22:11:04 +00001958 if (sizeof(HWord) == 4)
1959 return IRExpr_Const(IRConst_U32((UInt)hw));
1960 if (sizeof(HWord) == 8)
sewardjf9655262004-10-31 20:02:16 +00001961 return IRExpr_Const(IRConst_U64((ULong)hw));
sewardj49651f42004-10-28 22:11:04 +00001962 vpanic("mkIRExpr_HWord");
1963}
sewardj6efd4a12004-07-15 03:54:23 +00001964
sewardjf9655262004-10-31 20:02:16 +00001965IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr,
1966 IRExpr** args )
1967{
1968 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001969 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001970 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001971 d->args = args;
sewardjf9655262004-10-31 20:02:16 +00001972 return d;
1973}
1974
1975IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1976 Int regparms, Char* name, void* addr,
1977 IRExpr** args )
1978{
1979 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001980 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001981 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001982 d->args = args;
1983 d->tmp = dst;
sewardjf9655262004-10-31 20:02:16 +00001984 return d;
1985}
1986
1987IRExpr* mkIRExprCCall ( IRType retty,
1988 Int regparms, Char* name, void* addr,
1989 IRExpr** args )
1990{
1991 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
1992 retty, args );
1993}
1994
sewardje539a402004-07-14 18:24:17 +00001995/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +00001996/*--- end ir/irdefs.c ---*/
sewardj887a11a2004-07-05 17:26:47 +00001997/*---------------------------------------------------------------*/