blob: c555609a4a17ad0053ad321ea619e99869b06f88 [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;
sewardj6d2638e2004-07-15 09:38:27 +000058 default: vex_printf("ty = 0x%x\n", (Int)ty);
59 vpanic("ppIRType");
sewardjec6ad592004-06-20 12:26:53 +000060 }
61}
62
sewardj35421a32004-07-05 13:12:34 +000063void ppIRConst ( IRConst* con )
sewardjec6ad592004-06-20 12:26:53 +000064{
sewardj2d3f77c2004-09-22 23:49:09 +000065 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +000066 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break;
sewardj2d3f77c2004-09-22 23:49:09 +000067 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break;
68 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break;
69 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break;
70 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break;
sewardj695cff92004-10-13 14:50:14 +000071 case Ico_F64: vex_printf( "F64{0x%llx}", *(ULong*)(&con->Ico.F64));
72 break;
sewardj2d3f77c2004-09-22 23:49:09 +000073 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break;
74 default: vpanic("ppIRConst");
75 }
76}
77
sewardj8ea867b2004-10-30 19:03:02 +000078void ppIRCallee ( IRCallee* ce )
79{
80 vex_printf("%s", ce->name);
sewardj77352542004-10-30 20:39:01 +000081 if (ce->regparms > 0)
sewardj43c56462004-11-06 12:17:57 +000082 vex_printf("[rp=%d]", ce->regparms);
83 if (ce->mcx_mask > 0)
84 vex_printf("[mcx=0x%x]", ce->mcx_mask);
sewardj8ea867b2004-10-30 19:03:02 +000085 vex_printf("{%p}", (void*)ce->addr);
86}
87
sewardj2d3f77c2004-09-22 23:49:09 +000088void ppIRArray ( IRArray* arr )
89{
sewardj0bfea7f2004-10-04 07:15:48 +000090 vex_printf("(%d:%dx", arr->base, arr->nElems);
sewardj2d3f77c2004-09-22 23:49:09 +000091 ppIRType(arr->elemTy);
sewardj0bfea7f2004-10-04 07:15:48 +000092 vex_printf(")");
sewardje3d0d2e2004-06-27 10:42:44 +000093}
94
sewardj35421a32004-07-05 13:12:34 +000095void ppIRTemp ( IRTemp tmp )
sewardje3d0d2e2004-06-27 10:42:44 +000096{
sewardj92d168d2004-11-15 14:22:12 +000097 if (tmp == IRTemp_INVALID)
98 vex_printf("IRTemp_INVALID");
sewardjfbcaf332004-07-08 01:46:01 +000099 else
sewardj41f43bc2004-07-08 14:23:22 +0000100 vex_printf( "t%d", (Int)tmp);
sewardje3d0d2e2004-06-27 10:42:44 +0000101}
102
sewardj35421a32004-07-05 13:12:34 +0000103void ppIROp ( IROp op )
sewardje3d0d2e2004-06-27 10:42:44 +0000104{
sewardj41f43bc2004-07-08 14:23:22 +0000105 Char* str;
106 IROp base;
107 switch (op) {
108 case Iop_Add8 ... Iop_Add64:
109 str = "Add"; base = Iop_Add8; break;
110 case Iop_Sub8 ... Iop_Sub64:
111 str = "Sub"; base = Iop_Sub8; break;
112 case Iop_Mul8 ... Iop_Mul64:
113 str = "Mul"; base = Iop_Mul8; break;
114 case Iop_Or8 ... Iop_Or64:
115 str = "Or"; base = Iop_Or8; break;
116 case Iop_And8 ... Iop_And64:
117 str = "And"; base = Iop_And8; break;
118 case Iop_Xor8 ... Iop_Xor64:
119 str = "Xor"; base = Iop_Xor8; break;
120 case Iop_Shl8 ... Iop_Shl64:
121 str = "Shl"; base = Iop_Shl8; break;
122 case Iop_Shr8 ... Iop_Shr64:
123 str = "Shr"; base = Iop_Shr8; break;
124 case Iop_Sar8 ... Iop_Sar64:
125 str = "Sar"; base = Iop_Sar8; break;
sewardje90ad6a2004-07-10 19:02:10 +0000126 case Iop_CmpEQ8 ... Iop_CmpEQ64:
127 str = "CmpEQ"; base = Iop_CmpEQ8; break;
128 case Iop_CmpNE8 ... Iop_CmpNE64:
129 str = "CmpNE"; base = Iop_CmpNE8; break;
sewardj41f43bc2004-07-08 14:23:22 +0000130 case Iop_Not8 ... Iop_Not64:
131 str = "Not"; base = Iop_Not8; break;
132 /* other cases must explicitly "return;" */
sewardj9690d922004-07-14 01:39:17 +0000133 case Iop_8Uto16: vex_printf("8Uto16"); return;
134 case Iop_8Uto32: vex_printf("8Uto32"); return;
135 case Iop_16Uto32: vex_printf("16Uto32"); return;
136 case Iop_8Sto16: vex_printf("8Sto16"); return;
137 case Iop_8Sto32: vex_printf("8Sto32"); return;
138 case Iop_16Sto32: vex_printf("16Sto32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000139 case Iop_32Sto64: vex_printf("32Sto64"); return;
sewardje5427e82004-09-11 19:43:51 +0000140 case Iop_32Uto64: vex_printf("32Uto64"); return;
sewardja2384712004-07-29 14:36:40 +0000141 case Iop_32to8: vex_printf("32to8"); return;
sewardj6e797c52004-10-13 15:20:17 +0000142
143 case Iop_Not1: vex_printf("Not1"); return;
sewardj9690d922004-07-14 01:39:17 +0000144 case Iop_32to1: vex_printf("32to1"); return;
145 case Iop_1Uto8: vex_printf("1Uto8"); return;
sewardj84ff0652004-08-23 16:16:08 +0000146 case Iop_1Uto32: vex_printf("1Uto32"); return;
sewardjfd332772004-11-09 16:01:40 +0000147 case Iop_1Sto8: vex_printf("1Sto8"); return;
sewardj8eda6302004-11-05 01:55:46 +0000148 case Iop_1Sto16: vex_printf("1Sto16"); return;
sewardj415d9352004-11-04 15:20:15 +0000149 case Iop_1Sto32: vex_printf("1Sto32"); return;
sewardjb5874aa2004-11-04 16:57:50 +0000150 case Iop_1Sto64: vex_printf("1Sto64"); return;
sewardj9690d922004-07-14 01:39:17 +0000151
152 case Iop_MullS8: vex_printf("MullS8"); return;
153 case Iop_MullS16: vex_printf("MullS16"); return;
154 case Iop_MullS32: vex_printf("MullS32"); return;
155 case Iop_MullU8: vex_printf("MullU8"); return;
156 case Iop_MullU16: vex_printf("MullU16"); return;
157 case Iop_MullU32: vex_printf("MullU32"); return;
158
sewardjce646f22004-08-31 23:55:54 +0000159 case Iop_Clz32: vex_printf("Clz32"); return;
160 case Iop_Ctz32: vex_printf("Ctz32"); return;
161
sewardj84ff0652004-08-23 16:16:08 +0000162 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
163 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
164 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
165 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return;
166
sewardj9690d922004-07-14 01:39:17 +0000167 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
168 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
169
sewardjb81f8b32004-07-30 10:17:50 +0000170 case Iop_16HIto8: vex_printf("16HIto8"); return;
171 case Iop_16to8: vex_printf("16to8"); return;
172 case Iop_8HLto16: vex_printf("8HLto16"); return;
173
sewardj8c7f1ab2004-07-29 20:31:09 +0000174 case Iop_32HIto16: vex_printf("32HIto16"); return;
175 case Iop_32to16: vex_printf("32to16"); return;
176 case Iop_16HLto32: vex_printf("16HLto32"); return;
177
sewardj9690d922004-07-14 01:39:17 +0000178 case Iop_64HIto32: vex_printf("64HIto32"); return;
sewardj8c7f1ab2004-07-29 20:31:09 +0000179 case Iop_64to32: vex_printf("64to32"); return;
sewardj9690d922004-07-14 01:39:17 +0000180 case Iop_32HLto64: vex_printf("32HLto64"); return;
181
sewardjcfded9a2004-09-09 11:44:16 +0000182 case Iop_AddF64: vex_printf("AddF64"); return;
183 case Iop_SubF64: vex_printf("SubF64"); return;
184 case Iop_MulF64: vex_printf("MulF64"); return;
185 case Iop_DivF64: vex_printf("DivF64"); return;
sewardj46de4072004-09-11 19:23:24 +0000186
sewardj442d0be2004-10-15 22:57:13 +0000187 case Iop_ScaleF64: vex_printf("ScaleF64"); return;
188 case Iop_AtanF64: vex_printf("AtanF64"); return;
189 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return;
190 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return;
191 case Iop_PRemF64: vex_printf("PRemF64"); return;
192 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return;
193 case Iop_PRem1F64: vex_printf("PRem1F64"); return;
194 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return;
195 case Iop_NegF64: vex_printf("NegF64"); return;
196 case Iop_SqrtF64: vex_printf("SqrtF64"); return;
sewardj46de4072004-09-11 19:23:24 +0000197
sewardj883b00b2004-09-11 09:30:24 +0000198 case Iop_AbsF64: vex_printf("AbsF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000199 case Iop_SinF64: vex_printf("SinF64"); return;
200 case Iop_CosF64: vex_printf("CosF64"); return;
sewardj99016a72004-10-15 22:09:17 +0000201 case Iop_TanF64: vex_printf("TanF64"); return;
sewardj06c32a02004-09-12 12:07:34 +0000202 case Iop_2xm1F64: vex_printf("2xm1F64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000203
sewardj46de4072004-09-11 19:23:24 +0000204 case Iop_CmpF64: vex_printf("CmpF64"); return;
205
sewardj89cd0932004-09-08 18:23:25 +0000206 case Iop_I32toF64: vex_printf("I32toF64"); return;
sewardjbdc7d212004-09-09 02:46:40 +0000207 case Iop_I64toF64: vex_printf("I64toF64"); return;
208
sewardjcfded9a2004-09-09 11:44:16 +0000209 case Iop_F64toI64: vex_printf("F64toI64"); return;
sewardj89cd0932004-09-08 18:23:25 +0000210 case Iop_F64toI32: vex_printf("F64toI32"); return;
211 case Iop_F64toI16: vex_printf("F64toI16"); return;
sewardje6709112004-09-10 18:37:18 +0000212 case Iop_RoundF64: vex_printf("RoundF64"); return;
sewardjcfded9a2004-09-09 11:44:16 +0000213
sewardj89cd0932004-09-08 18:23:25 +0000214 case Iop_F32toF64: vex_printf("F32toF64"); return;
215 case Iop_F64toF32: vex_printf("F64toF32"); return;
sewardjbb53f8c2004-08-14 11:50:01 +0000216
sewardj17442fe2004-09-20 14:54:28 +0000217 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
218 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
219
sewardj9690d922004-07-14 01:39:17 +0000220 default: vpanic("ppIROp(1)");
sewardj41f43bc2004-07-08 14:23:22 +0000221 }
222
223 switch (op - base) {
224 case 0: vex_printf(str); vex_printf("8"); break;
225 case 1: vex_printf(str); vex_printf("16"); break;
226 case 2: vex_printf(str); vex_printf("32"); break;
227 case 3: vex_printf(str); vex_printf("64"); break;
228 default: vpanic("ppIROp(2)");
229 }
sewardje3d0d2e2004-06-27 10:42:44 +0000230}
231
sewardj35421a32004-07-05 13:12:34 +0000232void ppIRExpr ( IRExpr* e )
sewardje3d0d2e2004-06-27 10:42:44 +0000233{
sewardje87b4842004-07-10 12:23:30 +0000234 Int i;
sewardje3d0d2e2004-06-27 10:42:44 +0000235 switch (e->tag) {
sewardj443cd9d2004-07-18 23:06:45 +0000236 case Iex_Binder:
237 vex_printf("BIND-%d", e->Iex.Binder.binder);
238 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000239 case Iex_Get:
sewardjfbcaf332004-07-08 01:46:01 +0000240 vex_printf( "GET(%d,", e->Iex.Get.offset);
241 ppIRType(e->Iex.Get.ty);
242 vex_printf(")");
sewardjec6ad592004-06-20 12:26:53 +0000243 break;
sewardjbb53f8c2004-08-14 11:50:01 +0000244 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +0000245 vex_printf( "GETI" );
246 ppIRArray(e->Iex.GetI.descr);
247 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000248 ppIRExpr(e->Iex.GetI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000249 vex_printf(",%d]", e->Iex.GetI.bias);
sewardjbb53f8c2004-08-14 11:50:01 +0000250 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000251 case Iex_Tmp:
sewardj35421a32004-07-05 13:12:34 +0000252 ppIRTemp(e->Iex.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +0000253 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000254 case Iex_Binop:
sewardj35421a32004-07-05 13:12:34 +0000255 ppIROp(e->Iex.Binop.op);
256 vex_printf( "(" );
257 ppIRExpr(e->Iex.Binop.arg1);
258 vex_printf( "," );
259 ppIRExpr(e->Iex.Binop.arg2);
260 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000261 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000262 case Iex_Unop:
sewardj35421a32004-07-05 13:12:34 +0000263 ppIROp(e->Iex.Unop.op);
264 vex_printf( "(" );
265 ppIRExpr(e->Iex.Unop.arg);
266 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000267 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000268 case Iex_LDle:
sewardje05c42c2004-07-08 20:25:10 +0000269 vex_printf( "LDle:" );
sewardj35421a32004-07-05 13:12:34 +0000270 ppIRType(e->Iex.LDle.ty);
sewardje05c42c2004-07-08 20:25:10 +0000271 vex_printf( "(" );
sewardj35421a32004-07-05 13:12:34 +0000272 ppIRExpr(e->Iex.LDle.addr);
273 vex_printf( ")" );
sewardjec6ad592004-06-20 12:26:53 +0000274 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000275 case Iex_Const:
sewardj35421a32004-07-05 13:12:34 +0000276 ppIRConst(e->Iex.Const.con);
sewardjec6ad592004-06-20 12:26:53 +0000277 break;
sewardje87b4842004-07-10 12:23:30 +0000278 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000279 ppIRCallee(e->Iex.CCall.cee);
280 vex_printf("(");
sewardje87b4842004-07-10 12:23:30 +0000281 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
282 ppIRExpr(e->Iex.CCall.args[i]);
283 if (e->Iex.CCall.args[i+1] != NULL)
284 vex_printf(",");
285 }
286 vex_printf("):");
287 ppIRType(e->Iex.CCall.retty);
288 break;
sewardj4042c7e2004-07-18 01:28:30 +0000289 case Iex_Mux0X:
290 vex_printf("Mux0X(");
291 ppIRExpr(e->Iex.Mux0X.cond);
sewardjeeb9ef82004-07-15 12:39:03 +0000292 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000293 ppIRExpr(e->Iex.Mux0X.expr0);
sewardjeeb9ef82004-07-15 12:39:03 +0000294 vex_printf(",");
sewardj4042c7e2004-07-18 01:28:30 +0000295 ppIRExpr(e->Iex.Mux0X.exprX);
sewardjeeb9ef82004-07-15 12:39:03 +0000296 vex_printf(")");
297 break;
sewardjec6ad592004-06-20 12:26:53 +0000298 default:
sewardj35421a32004-07-05 13:12:34 +0000299 vpanic("ppIExpr");
sewardjec6ad592004-06-20 12:26:53 +0000300 }
301}
302
sewardj17442fe2004-09-20 14:54:28 +0000303void ppIREffect ( IREffect fx )
304{
305 switch (fx) {
306 case Ifx_None: vex_printf("noFX"); return;
307 case Ifx_Read: vex_printf("RdFX"); return;
308 case Ifx_Write: vex_printf("WrFX"); return;
309 case Ifx_Modify: vex_printf("MoFX"); return;
310 default: vpanic("ppIREffect");
311 }
312}
313
314void ppIRDirty ( IRDirty* d )
315{
316 Int i;
sewardj92d168d2004-11-15 14:22:12 +0000317 if (d->tmp != IRTemp_INVALID) {
sewardj4b861de2004-11-03 15:24:42 +0000318 ppIRTemp(d->tmp);
319 vex_printf(" = ");
320 }
sewardjb8385d82004-11-02 01:34:15 +0000321 vex_printf("DIRTY ");
322 ppIRExpr(d->guard);
sewardjc5fc7aa2004-10-27 23:00:55 +0000323 if (d->needsBBP)
324 vex_printf(" NeedsBBP");
sewardj17442fe2004-09-20 14:54:28 +0000325 if (d->mFx != Ifx_None) {
sewardj49651f42004-10-28 22:11:04 +0000326 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000327 ppIREffect(d->mFx);
328 vex_printf("-mem(");
329 ppIRExpr(d->mAddr);
sewardj49651f42004-10-28 22:11:04 +0000330 vex_printf(",%d)", d->mSize);
sewardj17442fe2004-09-20 14:54:28 +0000331 }
332 for (i = 0; i < d->nFxState; i++) {
sewardj49651f42004-10-28 22:11:04 +0000333 vex_printf(" ");
sewardj17442fe2004-09-20 14:54:28 +0000334 ppIREffect(d->fxState[i].fx);
sewardj49651f42004-10-28 22:11:04 +0000335 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
sewardj17442fe2004-09-20 14:54:28 +0000336 }
sewardjc5fc7aa2004-10-27 23:00:55 +0000337 vex_printf(" ::: ");
sewardj8ea867b2004-10-30 19:03:02 +0000338 ppIRCallee(d->cee);
339 vex_printf("(");
sewardj17442fe2004-09-20 14:54:28 +0000340 for (i = 0; d->args[i] != NULL; i++) {
341 ppIRExpr(d->args[i]);
342 if (d->args[i+1] != NULL) {
343 vex_printf(",");
344 }
345 }
346 vex_printf(")");
347}
348
sewardj35421a32004-07-05 13:12:34 +0000349void ppIRStmt ( IRStmt* s )
sewardjec6ad592004-06-20 12:26:53 +0000350{
sewardj17442fe2004-09-20 14:54:28 +0000351 switch (s->tag) {
352 case Ist_Put:
353 vex_printf( "PUT(%d) = ", s->Ist.Put.offset);
sewardj6d076362004-09-23 11:06:17 +0000354 ppIRExpr(s->Ist.Put.data);
sewardj17442fe2004-09-20 14:54:28 +0000355 break;
356 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +0000357 vex_printf( "PUTI" );
358 ppIRArray(s->Ist.PutI.descr);
359 vex_printf("[");
sewardjeeac8412004-11-02 00:26:55 +0000360 ppIRExpr(s->Ist.PutI.ix);
sewardj2d3f77c2004-09-22 23:49:09 +0000361 vex_printf(",%d] = ", s->Ist.PutI.bias);
362 ppIRExpr(s->Ist.PutI.data);
sewardj17442fe2004-09-20 14:54:28 +0000363 break;
364 case Ist_Tmp:
365 ppIRTemp(s->Ist.Tmp.tmp);
366 vex_printf( " = " );
sewardj6d076362004-09-23 11:06:17 +0000367 ppIRExpr(s->Ist.Tmp.data);
sewardj17442fe2004-09-20 14:54:28 +0000368 break;
369 case Ist_STle:
370 vex_printf( "STle(");
371 ppIRExpr(s->Ist.STle.addr);
372 vex_printf( ") = ");
373 ppIRExpr(s->Ist.STle.data);
374 break;
375 case Ist_Dirty:
376 ppIRDirty(s->Ist.Dirty.details);
377 break;
378 case Ist_Exit:
379 vex_printf( "if (" );
380 ppIRExpr(s->Ist.Exit.cond);
381 vex_printf( ") goto ");
382 ppIRConst(s->Ist.Exit.dst);
383 break;
384 default:
385 vpanic("ppIRStmt");
386 }
sewardjec6ad592004-06-20 12:26:53 +0000387}
388
sewardj78c19df2004-07-12 22:49:27 +0000389void ppIRJumpKind ( IRJumpKind kind )
390{
391 switch (kind) {
392 case Ijk_Boring: vex_printf("Boring"); break;
393 case Ijk_Call: vex_printf("Call"); break;
394 case Ijk_Ret: vex_printf("Return"); break;
395 case Ijk_ClientReq: vex_printf("ClientReq"); break;
396 case Ijk_Syscall: vex_printf("Syscall"); break;
397 case Ijk_Yield: vex_printf("Yield"); break;
398 default: vpanic("ppIRJumpKind");
sewardj17442fe2004-09-20 14:54:28 +0000399 }
sewardj78c19df2004-07-12 22:49:27 +0000400}
401
sewardj35421a32004-07-05 13:12:34 +0000402void ppIRTypeEnv ( IRTypeEnv* env ) {
sewardjc97096c2004-06-30 09:28:04 +0000403 UInt i;
sewardje539a402004-07-14 18:24:17 +0000404 for (i = 0; i < env->types_used; i++) {
sewardjc97096c2004-06-30 09:28:04 +0000405 if (i % 8 == 0)
sewardj35421a32004-07-05 13:12:34 +0000406 vex_printf( " ");
sewardje539a402004-07-14 18:24:17 +0000407 ppIRTemp(i);
sewardj35421a32004-07-05 13:12:34 +0000408 vex_printf( ":");
sewardje539a402004-07-14 18:24:17 +0000409 ppIRType(env->types[i]);
sewardjc97096c2004-06-30 09:28:04 +0000410 if (i % 8 == 7)
sewardj35421a32004-07-05 13:12:34 +0000411 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000412 else
sewardj35421a32004-07-05 13:12:34 +0000413 vex_printf( " ");
sewardjc97096c2004-06-30 09:28:04 +0000414 }
sewardje539a402004-07-14 18:24:17 +0000415 if (env->types_used > 0 && env->types_used % 8 != 7)
sewardj35421a32004-07-05 13:12:34 +0000416 vex_printf( "\n");
sewardjc97096c2004-06-30 09:28:04 +0000417}
418
sewardj35421a32004-07-05 13:12:34 +0000419void ppIRBB ( IRBB* bb )
sewardjec6ad592004-06-20 12:26:53 +0000420{
sewardjd7cb8532004-08-17 23:59:23 +0000421 Int i;
sewardj35439212004-07-14 22:36:10 +0000422 vex_printf("IRBB {\n");
sewardj35421a32004-07-05 13:12:34 +0000423 ppIRTypeEnv(bb->tyenv);
sewardj35439212004-07-14 22:36:10 +0000424 vex_printf("\n");
sewardjd7cb8532004-08-17 23:59:23 +0000425 for (i = 0; i < bb->stmts_used; i++) {
sewardj39e3f242004-08-18 16:54:52 +0000426 if (bb->stmts[i]) {
427 vex_printf( " ");
428 ppIRStmt(bb->stmts[i]);
429 }
sewardj35421a32004-07-05 13:12:34 +0000430 vex_printf( "\n");
sewardjec6ad592004-06-20 12:26:53 +0000431 }
sewardje539a402004-07-14 18:24:17 +0000432 vex_printf( " goto {");
433 ppIRJumpKind(bb->jumpkind);
434 vex_printf( "} ");
435 ppIRExpr( bb->next );
sewardj35439212004-07-14 22:36:10 +0000436 vex_printf( "\n}\n");
sewardjec6ad592004-06-20 12:26:53 +0000437}
438
439
440/*---------------------------------------------------------------*/
441/*--- Constructors ---*/
442/*---------------------------------------------------------------*/
443
sewardjc97096c2004-06-30 09:28:04 +0000444
445/* Constructors -- IRConst */
446
sewardjba999312004-11-15 15:21:17 +0000447IRConst* IRConst_U1 ( Bool bit )
sewardjb8e75862004-08-19 17:58:45 +0000448{
449 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjba999312004-11-15 15:21:17 +0000450 c->tag = Ico_U1;
451 c->Ico.U1 = bit;
sewardj4b861de2004-11-03 15:24:42 +0000452 /* call me paranoid; I don't care :-) */
453 vassert(bit == False || bit == True);
sewardjb8e75862004-08-19 17:58:45 +0000454 return c;
455}
sewardjc97096c2004-06-30 09:28:04 +0000456IRConst* IRConst_U8 ( UChar u8 )
457{
sewardj35421a32004-07-05 13:12:34 +0000458 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000459 c->tag = Ico_U8;
460 c->Ico.U8 = u8;
461 return c;
462}
463IRConst* IRConst_U16 ( UShort u16 )
464{
sewardj35421a32004-07-05 13:12:34 +0000465 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000466 c->tag = Ico_U16;
467 c->Ico.U16 = u16;
468 return c;
469}
470IRConst* IRConst_U32 ( UInt u32 )
471{
sewardj35421a32004-07-05 13:12:34 +0000472 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000473 c->tag = Ico_U32;
474 c->Ico.U32 = u32;
475 return c;
476}
477IRConst* IRConst_U64 ( ULong u64 )
478{
sewardj35421a32004-07-05 13:12:34 +0000479 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
sewardjc97096c2004-06-30 09:28:04 +0000480 c->tag = Ico_U64;
481 c->Ico.U64 = u64;
482 return c;
483}
sewardja58ea662004-08-15 03:12:41 +0000484IRConst* IRConst_F64 ( Double f64 )
485{
486 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
487 c->tag = Ico_F64;
488 c->Ico.F64 = f64;
489 return c;
490}
sewardj17442fe2004-09-20 14:54:28 +0000491IRConst* IRConst_F64i ( ULong f64i )
sewardj207557a2004-08-27 12:00:18 +0000492{
sewardj17442fe2004-09-20 14:54:28 +0000493 IRConst* c = LibVEX_Alloc(sizeof(IRConst));
494 c->tag = Ico_F64i;
495 c->Ico.F64i = f64i;
sewardj207557a2004-08-27 12:00:18 +0000496 return c;
497}
498
sewardjc97096c2004-06-30 09:28:04 +0000499
sewardj8ea867b2004-10-30 19:03:02 +0000500/* Constructors -- IRCallee */
501
sewardjf9655262004-10-31 20:02:16 +0000502IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr )
sewardj8ea867b2004-10-30 19:03:02 +0000503{
504 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
sewardj77352542004-10-30 20:39:01 +0000505 ce->regparms = regparms;
506 ce->name = name;
507 ce->addr = addr;
sewardj43c56462004-11-06 12:17:57 +0000508 ce->mcx_mask = 0;
sewardj77352542004-10-30 20:39:01 +0000509 vassert(regparms >= 0 && regparms <= 3);
sewardj8ea867b2004-10-30 19:03:02 +0000510 vassert(name != NULL);
511 vassert(addr != 0);
512 return ce;
513}
514
515
516/* Constructors -- IRArray */
sewardje3d0d2e2004-06-27 10:42:44 +0000517
sewardj2d3f77c2004-09-22 23:49:09 +0000518IRArray* mkIRArray ( Int base, IRType elemTy, Int nElems )
519{
520 IRArray* arr = LibVEX_Alloc(sizeof(IRArray));
521 arr->base = base;
522 arr->elemTy = elemTy;
523 arr->nElems = nElems;
524 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */));
sewardjba999312004-11-15 15:21:17 +0000525 vassert(!(arr->elemTy == Ity_I1));
sewardj2d3f77c2004-09-22 23:49:09 +0000526 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */));
527 return arr;
528}
529
530
531/* Constructors -- IRExpr */
532
sewardj443cd9d2004-07-18 23:06:45 +0000533IRExpr* IRExpr_Binder ( Int binder ) {
534 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
535 e->tag = Iex_Binder;
536 e->Iex.Binder.binder = binder;
537 return e;
538}
sewardjfbcaf332004-07-08 01:46:01 +0000539IRExpr* IRExpr_Get ( Int off, IRType ty ) {
sewardj35421a32004-07-05 13:12:34 +0000540 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000541 e->tag = Iex_Get;
542 e->Iex.Get.offset = off;
sewardjfbcaf332004-07-08 01:46:01 +0000543 e->Iex.Get.ty = ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000544 return e;
545}
sewardjeeac8412004-11-02 00:26:55 +0000546IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ) {
sewardj2d3f77c2004-09-22 23:49:09 +0000547 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
548 e->tag = Iex_GetI;
549 e->Iex.GetI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000550 e->Iex.GetI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000551 e->Iex.GetI.bias = bias;
sewardjd1725d12004-08-12 20:46:53 +0000552 return e;
553}
sewardjc97096c2004-06-30 09:28:04 +0000554IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
sewardj35421a32004-07-05 13:12:34 +0000555 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000556 e->tag = Iex_Tmp;
557 e->Iex.Tmp.tmp = tmp;
558 return e;
559}
sewardjc97096c2004-06-30 09:28:04 +0000560IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
sewardj35421a32004-07-05 13:12:34 +0000561 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000562 e->tag = Iex_Binop;
563 e->Iex.Binop.op = op;
564 e->Iex.Binop.arg1 = arg1;
565 e->Iex.Binop.arg2 = arg2;
566 return e;
567}
sewardjc97096c2004-06-30 09:28:04 +0000568IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
sewardj35421a32004-07-05 13:12:34 +0000569 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000570 e->tag = Iex_Unop;
571 e->Iex.Unop.op = op;
572 e->Iex.Unop.arg = arg;
573 return e;
574}
sewardjc97096c2004-06-30 09:28:04 +0000575IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
sewardj35421a32004-07-05 13:12:34 +0000576 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000577 e->tag = Iex_LDle;
578 e->Iex.LDle.ty = ty;
579 e->Iex.LDle.addr = addr;
580 return e;
581}
sewardjc97096c2004-06-30 09:28:04 +0000582IRExpr* IRExpr_Const ( IRConst* con ) {
sewardj35421a32004-07-05 13:12:34 +0000583 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardje3d0d2e2004-06-27 10:42:44 +0000584 e->tag = Iex_Const;
585 e->Iex.Const.con = con;
586 return e;
sewardjec6ad592004-06-20 12:26:53 +0000587}
sewardj8ea867b2004-10-30 19:03:02 +0000588IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
sewardje87b4842004-07-10 12:23:30 +0000589 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
590 e->tag = Iex_CCall;
sewardj8ea867b2004-10-30 19:03:02 +0000591 e->Iex.CCall.cee = cee;
sewardje87b4842004-07-10 12:23:30 +0000592 e->Iex.CCall.retty = retty;
593 e->Iex.CCall.args = args;
594 return e;
595}
sewardj4042c7e2004-07-18 01:28:30 +0000596IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
sewardjeeb9ef82004-07-15 12:39:03 +0000597 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
sewardj4042c7e2004-07-18 01:28:30 +0000598 e->tag = Iex_Mux0X;
599 e->Iex.Mux0X.cond = cond;
600 e->Iex.Mux0X.expr0 = expr0;
601 e->Iex.Mux0X.exprX = exprX;
sewardjeeb9ef82004-07-15 12:39:03 +0000602 return e;
603}
sewardjec6ad592004-06-20 12:26:53 +0000604
sewardjec6ad592004-06-20 12:26:53 +0000605
sewardjc5fc7aa2004-10-27 23:00:55 +0000606/* Constructors for NULL-terminated IRExpr expression vectors,
607 suitable for use as arg lists in clean/dirty helper calls. */
608
609IRExpr** mkIRExprVec_0 ( void ) {
610 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*));
611 vec[0] = NULL;
612 return vec;
613}
614IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) {
615 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*));
616 vec[0] = arg1;
617 vec[1] = NULL;
618 return vec;
619}
620IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
621 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*));
622 vec[0] = arg1;
623 vec[1] = arg2;
624 vec[2] = NULL;
625 return vec;
626}
sewardjf9655262004-10-31 20:02:16 +0000627IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) {
628 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*));
629 vec[0] = arg1;
630 vec[1] = arg2;
631 vec[2] = arg3;
632 vec[3] = NULL;
633 return vec;
634}
635IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2,
636 IRExpr* arg3, IRExpr* arg4 ) {
637 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*));
638 vec[0] = arg1;
639 vec[1] = arg2;
640 vec[2] = arg3;
641 vec[3] = arg4;
642 vec[4] = NULL;
643 return vec;
644}
sewardjf32c67d2004-11-08 13:10:44 +0000645IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2,
646 IRExpr* arg3, IRExpr* arg4, IRExpr* arg5 ) {
647 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*));
648 vec[0] = arg1;
649 vec[1] = arg2;
650 vec[2] = arg3;
651 vec[3] = arg4;
652 vec[4] = arg5;
653 vec[5] = NULL;
654 return vec;
655}
sewardjc5fc7aa2004-10-27 23:00:55 +0000656
657
sewardj17442fe2004-09-20 14:54:28 +0000658/* Constructors -- IRDirty */
659
sewardjc5fc7aa2004-10-27 23:00:55 +0000660IRDirty* emptyIRDirty ( void ) {
sewardj17442fe2004-09-20 14:54:28 +0000661 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
sewardj8ea867b2004-10-30 19:03:02 +0000662 d->cee = NULL;
sewardjb8385d82004-11-02 01:34:15 +0000663 d->guard = NULL;
sewardj17442fe2004-09-20 14:54:28 +0000664 d->args = NULL;
sewardj92d168d2004-11-15 14:22:12 +0000665 d->tmp = IRTemp_INVALID;
sewardj17442fe2004-09-20 14:54:28 +0000666 d->mFx = Ifx_None;
667 d->mAddr = NULL;
668 d->mSize = 0;
sewardjc5fc7aa2004-10-27 23:00:55 +0000669 d->needsBBP = False;
sewardj17442fe2004-09-20 14:54:28 +0000670 d->nFxState = 0;
671 return d;
672}
673
674
sewardjec6ad592004-06-20 12:26:53 +0000675/* Constructors -- IRStmt */
sewardje3d0d2e2004-06-27 10:42:44 +0000676
sewardj6d076362004-09-23 11:06:17 +0000677IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000678 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000679 s->tag = Ist_Put;
680 s->Ist.Put.offset = off;
sewardj6d076362004-09-23 11:06:17 +0000681 s->Ist.Put.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000682 return s;
sewardjec6ad592004-06-20 12:26:53 +0000683}
sewardjeeac8412004-11-02 00:26:55 +0000684IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix,
sewardj2d3f77c2004-09-22 23:49:09 +0000685 Int bias, IRExpr* data ) {
686 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
687 s->tag = Ist_PutI;
688 s->Ist.PutI.descr = descr;
sewardjeeac8412004-11-02 00:26:55 +0000689 s->Ist.PutI.ix = ix;
sewardj2d3f77c2004-09-22 23:49:09 +0000690 s->Ist.PutI.bias = bias;
691 s->Ist.PutI.data = data;
sewardjd1725d12004-08-12 20:46:53 +0000692 return s;
693}
sewardj6d076362004-09-23 11:06:17 +0000694IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000695 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000696 s->tag = Ist_Tmp;
697 s->Ist.Tmp.tmp = tmp;
sewardj6d076362004-09-23 11:06:17 +0000698 s->Ist.Tmp.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000699 return s;
sewardjec6ad592004-06-20 12:26:53 +0000700}
sewardj6d076362004-09-23 11:06:17 +0000701IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ) {
sewardj35421a32004-07-05 13:12:34 +0000702 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
sewardje3d0d2e2004-06-27 10:42:44 +0000703 s->tag = Ist_STle;
704 s->Ist.STle.addr = addr;
sewardj6d076362004-09-23 11:06:17 +0000705 s->Ist.STle.data = data;
sewardje3d0d2e2004-06-27 10:42:44 +0000706 return s;
sewardjec6ad592004-06-20 12:26:53 +0000707}
sewardj17442fe2004-09-20 14:54:28 +0000708IRStmt* IRStmt_Dirty ( IRDirty* d )
709{
710 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
711 s->tag = Ist_Dirty;
712 s->Ist.Dirty.details = d;
713 return s;
714}
sewardj64e1d652004-07-12 14:00:46 +0000715IRStmt* IRStmt_Exit ( IRExpr* cond, IRConst* dst ) {
716 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
717 s->tag = Ist_Exit;
sewardj64e1d652004-07-12 14:00:46 +0000718 s->Ist.Exit.cond = cond;
719 s->Ist.Exit.dst = dst;
720 return s;
721}
sewardje3d0d2e2004-06-27 10:42:44 +0000722
sewardj695cff92004-10-13 14:50:14 +0000723
724/* Constructors -- IRTypeEnv */
725
726IRTypeEnv* emptyIRTypeEnv ( void )
727{
728 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
729 env->types = LibVEX_Alloc(8 * sizeof(IRType));
730 env->types_size = 8;
731 env->types_used = 0;
732 return env;
733}
734
735
736/* Constructors -- IRBB */
sewardje3d0d2e2004-06-27 10:42:44 +0000737
sewardjd7cb8532004-08-17 23:59:23 +0000738IRBB* emptyIRBB ( void )
739{
740 IRBB* bb = LibVEX_Alloc(sizeof(IRBB));
741 bb->tyenv = emptyIRTypeEnv();
742 bb->stmts_used = 0;
743 bb->stmts_size = 8;
744 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*));
745 bb->next = NULL;
746 bb->jumpkind = Ijk_Boring;
sewardje3d0d2e2004-06-27 10:42:44 +0000747 return bb;
sewardjec6ad592004-06-20 12:26:53 +0000748}
749
sewardj695cff92004-10-13 14:50:14 +0000750
751/*---------------------------------------------------------------*/
752/*--- (Deep) copy constructors. These make complete copies ---*/
753/*--- the original, which can be modified without affecting ---*/
754/*--- the original. ---*/
755/*---------------------------------------------------------------*/
756
757/* Copying IR Expr vectors (for call args). */
758
759/* Shallow copy of an IRExpr vector */
760
761IRExpr** sopyIRExprVec ( IRExpr** vec )
sewardjd7cb8532004-08-17 23:59:23 +0000762{
sewardj695cff92004-10-13 14:50:14 +0000763 Int i;
764 IRExpr** newvec;
765 for (i = 0; vec[i]; i++)
766 ;
767 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*));
768 for (i = 0; vec[i]; i++)
769 newvec[i] = vec[i];
770 newvec[i] = NULL;
771 return newvec;
772}
773
774/* Deep copy of an IRExpr vector */
775
776IRExpr** dopyIRExprVec ( IRExpr** vec )
777{
778 Int i;
779 IRExpr** newvec = sopyIRExprVec( vec );
780 for (i = 0; newvec[i]; i++)
781 newvec[i] = dopyIRExpr(newvec[i]);
782 return newvec;
783}
784
785/* Deep copy constructors for all heap-allocated IR types follow. */
786
787IRConst* dopyIRConst ( IRConst* c )
788{
789 switch (c->tag) {
sewardjba999312004-11-15 15:21:17 +0000790 case Ico_U1: return IRConst_U1(c->Ico.U1);
sewardj695cff92004-10-13 14:50:14 +0000791 case Ico_U8: return IRConst_U8(c->Ico.U8);
792 case Ico_U16: return IRConst_U16(c->Ico.U16);
793 case Ico_U32: return IRConst_U32(c->Ico.U32);
794 case Ico_U64: return IRConst_U64(c->Ico.U64);
795 case Ico_F64: return IRConst_F64(c->Ico.F64);
796 case Ico_F64i: return IRConst_F64i(c->Ico.F64i);
797 default: vpanic("dopyIRConst");
sewardjd7cb8532004-08-17 23:59:23 +0000798 }
sewardj695cff92004-10-13 14:50:14 +0000799}
800
sewardj8ea867b2004-10-30 19:03:02 +0000801IRCallee* dopyIRCallee ( IRCallee* ce )
802{
sewardj43c56462004-11-06 12:17:57 +0000803 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
804 ce2->mcx_mask = ce->mcx_mask;
805 return ce2;
sewardj8ea867b2004-10-30 19:03:02 +0000806}
807
sewardj695cff92004-10-13 14:50:14 +0000808IRArray* dopyIRArray ( IRArray* d )
809{
810 return mkIRArray(d->base, d->elemTy, d->nElems);
811}
812
813IRExpr* dopyIRExpr ( IRExpr* e )
814{
815 switch (e->tag) {
816 case Iex_Get:
817 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty);
818 case Iex_GetI:
819 return IRExpr_GetI(dopyIRArray(e->Iex.GetI.descr),
sewardjeeac8412004-11-02 00:26:55 +0000820 dopyIRExpr(e->Iex.GetI.ix),
sewardj695cff92004-10-13 14:50:14 +0000821 e->Iex.GetI.bias);
822 case Iex_Tmp:
823 return IRExpr_Tmp(e->Iex.Tmp.tmp);
824 case Iex_Binop:
825 return IRExpr_Binop(e->Iex.Binop.op,
826 dopyIRExpr(e->Iex.Binop.arg1),
827 dopyIRExpr(e->Iex.Binop.arg2));
828 case Iex_Unop:
829 return IRExpr_Unop(e->Iex.Unop.op,
830 dopyIRExpr(e->Iex.Unop.arg));
831 case Iex_LDle:
832 return IRExpr_LDle(e->Iex.LDle.ty,
833 dopyIRExpr(e->Iex.LDle.addr));
834 case Iex_Const:
835 return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
836 case Iex_CCall:
sewardj8ea867b2004-10-30 19:03:02 +0000837 return IRExpr_CCall(dopyIRCallee(e->Iex.CCall.cee),
sewardj695cff92004-10-13 14:50:14 +0000838 e->Iex.CCall.retty,
839 dopyIRExprVec(e->Iex.CCall.args));
840
841 case Iex_Mux0X:
842 return IRExpr_Mux0X(dopyIRExpr(e->Iex.Mux0X.cond),
843 dopyIRExpr(e->Iex.Mux0X.expr0),
844 dopyIRExpr(e->Iex.Mux0X.exprX));
845 default:
846 vpanic("dopyIRExpr");
847 }
848}
849
850IRDirty* dopyIRDirty ( IRDirty* d )
851{
852 Int i;
853 IRDirty* d2 = emptyIRDirty();
sewardj8ea867b2004-10-30 19:03:02 +0000854 d2->cee = dopyIRCallee(d->cee);
sewardjb8385d82004-11-02 01:34:15 +0000855 d2->guard = dopyIRExpr(d->guard);
sewardj695cff92004-10-13 14:50:14 +0000856 d2->args = dopyIRExprVec(d->args);
857 d2->tmp = d->tmp;
858 d2->mFx = d->mFx;
859 d2->mAddr = d->mAddr==NULL ? NULL : dopyIRExpr(d->mAddr);
860 d2->mSize = d->mSize;
sewardjc5fc7aa2004-10-27 23:00:55 +0000861 d2->needsBBP = d->needsBBP;
sewardj695cff92004-10-13 14:50:14 +0000862 d2->nFxState = d->nFxState;
863 for (i = 0; i < d2->nFxState; i++)
864 d2->fxState[i] = d->fxState[i];
865 return d2;
866}
867
868IRStmt* dopyIRStmt ( IRStmt* s )
869{
870 switch (s->tag) {
871 case Ist_Put:
872 return IRStmt_Put(s->Ist.Put.offset,
873 dopyIRExpr(s->Ist.Put.data));
874 case Ist_PutI:
875 return IRStmt_PutI(dopyIRArray(s->Ist.PutI.descr),
sewardjeeac8412004-11-02 00:26:55 +0000876 dopyIRExpr(s->Ist.PutI.ix),
sewardj695cff92004-10-13 14:50:14 +0000877 s->Ist.PutI.bias,
878 dopyIRExpr(s->Ist.PutI.data));
879 case Ist_Tmp:
880 return IRStmt_Tmp(s->Ist.Tmp.tmp,
881 dopyIRExpr(s->Ist.Tmp.data));
882 case Ist_STle:
883 return IRStmt_STle(dopyIRExpr(s->Ist.STle.addr),
884 dopyIRExpr(s->Ist.STle.data));
885 case Ist_Dirty:
886 return IRStmt_Dirty(dopyIRDirty(s->Ist.Dirty.details));
887 case Ist_Exit:
888 return IRStmt_Exit(dopyIRExpr(s->Ist.Exit.cond),
889 dopyIRConst(s->Ist.Exit.dst));
890 default:
891 vpanic("dopyIRStmt");
892 }
893}
894
895IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* src )
896{
897 Int i;
898 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv));
899 dst->types_size = src->types_size;
900 dst->types_used = src->types_used;
901 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType));
902 for (i = 0; i < src->types_used; i++)
903 dst->types[i] = src->types[i];
904 return dst;
905}
906
907IRBB* dopyIRBB ( IRBB* bb )
908{
909 Int i;
910 IRStmt** sts2;
911 IRBB* bb2 = emptyIRBB();
912 bb2->tyenv = dopyIRTypeEnv(bb->tyenv);
913 bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
914 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*));
915 for (i = 0; i < bb2->stmts_used; i++)
916 sts2[i] = bb->stmts[i]==NULL ? NULL : dopyIRStmt(bb->stmts[i]);
917 bb2->stmts = sts2;
918 bb2->next = dopyIRExpr(bb->next);
919 bb2->jumpkind = bb->jumpkind;
920 return bb2;
sewardjd7cb8532004-08-17 23:59:23 +0000921}
922
sewardjec6ad592004-06-20 12:26:53 +0000923
sewardjc97096c2004-06-30 09:28:04 +0000924/*---------------------------------------------------------------*/
sewardj6efd4a12004-07-15 03:54:23 +0000925/*--- Primop types ---*/
926/*---------------------------------------------------------------*/
927
928static
929void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
930{
931# define UNARY(_td,_ta1) \
932 *t_dst = (_td); *t_arg1 = (_ta1); break
933# define BINARY(_td,_ta1,_ta2) \
934 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break
935# define COMPARISON(_ta) \
sewardjba999312004-11-15 15:21:17 +0000936 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break;
sewardj6efd4a12004-07-15 03:54:23 +0000937
938 *t_dst = Ity_INVALID;
939 *t_arg1 = Ity_INVALID;
940 *t_arg2 = Ity_INVALID;
941 switch (op) {
sewardj17442fe2004-09-20 14:54:28 +0000942 case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
943 case Iop_Or8: case Iop_And8: case Iop_Xor8:
sewardj6efd4a12004-07-15 03:54:23 +0000944 BINARY(Ity_I8,Ity_I8,Ity_I8);
945
sewardj17442fe2004-09-20 14:54:28 +0000946 case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
947 case Iop_Or16: case Iop_And16: case Iop_Xor16:
sewardj6efd4a12004-07-15 03:54:23 +0000948 BINARY(Ity_I16,Ity_I16,Ity_I16);
949
sewardj17442fe2004-09-20 14:54:28 +0000950 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
951 case Iop_Or32: case Iop_And32: case Iop_Xor32:
sewardj6efd4a12004-07-15 03:54:23 +0000952 BINARY(Ity_I32,Ity_I32,Ity_I32);
953
sewardj17442fe2004-09-20 14:54:28 +0000954 case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
955 case Iop_Or64: case Iop_And64: case Iop_Xor64:
sewardj6efd4a12004-07-15 03:54:23 +0000956 BINARY(Ity_I64,Ity_I64,Ity_I64);
957
958 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8:
959 BINARY(Ity_I8,Ity_I8,Ity_I8);
960 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
961 BINARY(Ity_I16,Ity_I16,Ity_I8);
962 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
963 BINARY(Ity_I32,Ity_I32,Ity_I8);
964 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
965 BINARY(Ity_I64,Ity_I64,Ity_I8);
966
sewardj86b133b2004-11-15 13:54:26 +0000967 case Iop_Not8: UNARY(Ity_I8,Ity_I8);
968 case Iop_Not16: UNARY(Ity_I16,Ity_I16);
969 case Iop_Not32: UNARY(Ity_I32,Ity_I32);
970 case Iop_Not64: UNARY(Ity_I64,Ity_I64);
sewardj6efd4a12004-07-15 03:54:23 +0000971
972 case Iop_CmpEQ8: case Iop_CmpNE8:
973 COMPARISON(Ity_I8);
974 case Iop_CmpEQ16: case Iop_CmpNE16:
975 COMPARISON(Ity_I16);
976 case Iop_CmpEQ32: case Iop_CmpNE32:
sewardj17442fe2004-09-20 14:54:28 +0000977 case Iop_CmpLT32S: case Iop_CmpLE32S:
978 case Iop_CmpLT32U: case Iop_CmpLE32U:
sewardj6efd4a12004-07-15 03:54:23 +0000979 COMPARISON(Ity_I32);
980 case Iop_CmpEQ64: case Iop_CmpNE64:
981 COMPARISON(Ity_I64);
982
sewardjb81f8b32004-07-30 10:17:50 +0000983 case Iop_MullU8: case Iop_MullS8:
984 BINARY(Ity_I16,Ity_I8,Ity_I8);
985 case Iop_MullU16: case Iop_MullS16:
986 BINARY(Ity_I32,Ity_I16,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +0000987 case Iop_MullU32: case Iop_MullS32:
988 BINARY(Ity_I64,Ity_I32,Ity_I32);
989
sewardj17442fe2004-09-20 14:54:28 +0000990 case Iop_Clz32: case Iop_Ctz32:
sewardjce646f22004-08-31 23:55:54 +0000991 UNARY(Ity_I32,Ity_I32);
992
sewardj17442fe2004-09-20 14:54:28 +0000993 case Iop_DivModU64to32: case Iop_DivModS64to32:
sewardj6d2638e2004-07-15 09:38:27 +0000994 BINARY(Ity_I64,Ity_I64,Ity_I32);
995
sewardjb81f8b32004-07-30 10:17:50 +0000996 case Iop_16HIto8: case Iop_16to8:
997 UNARY(Ity_I8,Ity_I16);
998 case Iop_8HLto16:
999 BINARY(Ity_I16,Ity_I8,Ity_I8);
1000
sewardj8c7f1ab2004-07-29 20:31:09 +00001001 case Iop_32HIto16: case Iop_32to16:
1002 UNARY(Ity_I16,Ity_I32);
1003 case Iop_16HLto32:
1004 BINARY(Ity_I32,Ity_I16,Ity_I16);
1005
1006 case Iop_64HIto32: case Iop_64to32:
sewardj6d2638e2004-07-15 09:38:27 +00001007 UNARY(Ity_I32, Ity_I64);
1008 case Iop_32HLto64:
1009 BINARY(Ity_I64,Ity_I32,Ity_I32);
1010
sewardjba999312004-11-15 15:21:17 +00001011 case Iop_Not1: UNARY(Ity_I1,Ity_I1);
1012 case Iop_1Uto8: UNARY(Ity_I8,Ity_I1);
1013 case Iop_1Sto8: UNARY(Ity_I8,Ity_I1);
1014 case Iop_1Sto16: UNARY(Ity_I16,Ity_I1);
1015 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I32,Ity_I1);
1016 case Iop_1Sto64: UNARY(Ity_I64,Ity_I1);
1017 case Iop_32to1: UNARY(Ity_I1,Ity_I32);
sewardj47341042004-09-19 11:55:46 +00001018
sewardj17442fe2004-09-20 14:54:28 +00001019 case Iop_8Uto32: case Iop_8Sto32:
1020 UNARY(Ity_I32,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001021
sewardj17442fe2004-09-20 14:54:28 +00001022 case Iop_8Uto16: case Iop_8Sto16:
1023 UNARY(Ity_I16,Ity_I8);
sewardj47341042004-09-19 11:55:46 +00001024
sewardj17442fe2004-09-20 14:54:28 +00001025 case Iop_16Uto32: case Iop_16Sto32:
1026 UNARY(Ity_I32,Ity_I16);
sewardj6d2638e2004-07-15 09:38:27 +00001027
sewardj17442fe2004-09-20 14:54:28 +00001028 case Iop_32Sto64: case Iop_32Uto64:
1029 UNARY(Ity_I64,Ity_I32);
1030
1031 case Iop_32to8: UNARY(Ity_I8,Ity_I32);
1032
sewardj442d0be2004-10-15 22:57:13 +00001033 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64:
sewardj17442fe2004-09-20 14:54:28 +00001034 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64:
1035 case Iop_AddF64: case Iop_SubF64: case Iop_MulF64: case Iop_DivF64:
sewardja58ea662004-08-15 03:12:41 +00001036 BINARY(Ity_F64,Ity_F64,Ity_F64);
sewardj442d0be2004-10-15 22:57:13 +00001037 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
sewardjbdc7d212004-09-09 02:46:40 +00001038 case Iop_CmpF64:
1039 BINARY(Ity_I32,Ity_F64,Ity_F64);
sewardj883b00b2004-09-11 09:30:24 +00001040 case Iop_NegF64: case Iop_AbsF64: case Iop_SqrtF64:
sewardj99016a72004-10-15 22:09:17 +00001041 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: case Iop_2xm1F64:
sewardjcfded9a2004-09-09 11:44:16 +00001042 UNARY(Ity_F64,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001043
sewardj89cd0932004-09-08 18:23:25 +00001044 case Iop_I32toF64: UNARY(Ity_F64,Ity_I32);
sewardj17442fe2004-09-20 14:54:28 +00001045 case Iop_I64toF64: case Iop_ReinterpI64asF64:
1046 UNARY(Ity_F64,Ity_I64);
1047 case Iop_ReinterpF64asI64: UNARY(Ity_I64, Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001048
sewardjcfded9a2004-09-09 11:44:16 +00001049 case Iop_F64toI64: BINARY(Ity_I64, Ity_I32,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001050 case Iop_F64toI32: BINARY(Ity_I32, Ity_I32,Ity_F64);
1051 case Iop_F64toI16: BINARY(Ity_I16, Ity_I32,Ity_F64);
sewardje6709112004-09-10 18:37:18 +00001052 case Iop_RoundF64: BINARY(Ity_F64, Ity_I32,Ity_F64);
sewardj8f3debf2004-09-08 23:42:23 +00001053
sewardj89cd0932004-09-08 18:23:25 +00001054 case Iop_F32toF64: UNARY(Ity_F64,Ity_F32);
1055 case Iop_F64toF32: UNARY(Ity_F32,Ity_F64);
sewardjbb53f8c2004-08-14 11:50:01 +00001056
sewardj6efd4a12004-07-15 03:54:23 +00001057 default:
1058 ppIROp(op);
1059 vpanic("typeOfPrimop");
1060 }
1061# undef UNARY
1062# undef BINARY
1063# undef COMPARISON
1064}
1065
1066
1067/*---------------------------------------------------------------*/
sewardj695cff92004-10-13 14:50:14 +00001068/*--- Helper functions for the IR -- IR Basic Blocks ---*/
sewardjc97096c2004-06-30 09:28:04 +00001069/*---------------------------------------------------------------*/
1070
sewardj695cff92004-10-13 14:50:14 +00001071void addStmtToIRBB ( IRBB* bb, IRStmt* st )
sewardjd7cb8532004-08-17 23:59:23 +00001072{
1073 Int i;
sewardj695cff92004-10-13 14:50:14 +00001074 if (bb->stmts_used == bb->stmts_size) {
1075 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));
1076 for (i = 0; i < bb->stmts_size; i++)
1077 stmts2[i] = bb->stmts[i];
1078 bb->stmts = stmts2;
1079 bb->stmts_size *= 2;
1080 }
1081 vassert(bb->stmts_used < bb->stmts_size);
1082 bb->stmts[bb->stmts_used] = st;
1083 bb->stmts_used++;
sewardjd7cb8532004-08-17 23:59:23 +00001084}
1085
sewardj695cff92004-10-13 14:50:14 +00001086
1087/*---------------------------------------------------------------*/
1088/*--- Helper functions for the IR -- IR Type Environments ---*/
1089/*---------------------------------------------------------------*/
1090
sewardjd7cb8532004-08-17 23:59:23 +00001091/* Allocate a new IRTemp, given its type. */
sewardje3d0d2e2004-06-27 10:42:44 +00001092
sewardje539a402004-07-14 18:24:17 +00001093IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
sewardjc97096c2004-06-30 09:28:04 +00001094{
sewardj35421a32004-07-05 13:12:34 +00001095 vassert(env);
sewardje539a402004-07-14 18:24:17 +00001096 vassert(env->types_used >= 0);
1097 vassert(env->types_size >= 0);
1098 vassert(env->types_used <= env->types_size);
1099 if (env->types_used < env->types_size) {
1100 env->types[env->types_used] = ty;
1101 return env->types_used++;
sewardjc97096c2004-06-30 09:28:04 +00001102 } else {
1103 Int i;
sewardje539a402004-07-14 18:24:17 +00001104 Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
1105 IRType* new_types
1106 = LibVEX_Alloc(new_size * sizeof(IRType));
1107 for (i = 0; i < env->types_used; i++)
1108 new_types[i] = env->types[i];
1109 env->types = new_types;
1110 env->types_size = new_size;
1111 return newIRTemp(env, ty);
sewardjc97096c2004-06-30 09:28:04 +00001112 }
1113}
1114
1115
sewardj17442fe2004-09-20 14:54:28 +00001116/*---------------------------------------------------------------*/
1117/*--- Helper functions for the IR -- finding types of exprs ---*/
1118/*---------------------------------------------------------------*/
1119
sewardjedeb4c42004-09-21 23:39:25 +00001120inline
sewardj17442fe2004-09-20 14:54:28 +00001121IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp )
sewardjc97096c2004-06-30 09:28:04 +00001122{
sewardje539a402004-07-14 18:24:17 +00001123 vassert(tmp >= 0);
1124 vassert(tmp < env->types_used);
1125 return env->types[tmp];
sewardjc97096c2004-06-30 09:28:04 +00001126}
1127
1128
sewardj6efd4a12004-07-15 03:54:23 +00001129IRType typeOfIRConst ( IRConst* con )
1130{
1131 switch (con->tag) {
sewardjba999312004-11-15 15:21:17 +00001132 case Ico_U1: return Ity_I1;
sewardj207557a2004-08-27 12:00:18 +00001133 case Ico_U8: return Ity_I8;
1134 case Ico_U16: return Ity_I16;
1135 case Ico_U32: return Ity_I32;
1136 case Ico_U64: return Ity_I64;
1137 case Ico_F64: return Ity_F64;
sewardj17442fe2004-09-20 14:54:28 +00001138 case Ico_F64i: return Ity_F64;
sewardj6efd4a12004-07-15 03:54:23 +00001139 default: vpanic("typeOfIRConst");
1140 }
1141}
1142
sewardjc97096c2004-06-30 09:28:04 +00001143IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
1144{
sewardj6efd4a12004-07-15 03:54:23 +00001145 IRType t_dst, t_arg1, t_arg2;
sewardjedeb4c42004-09-21 23:39:25 +00001146 start:
sewardjc97096c2004-06-30 09:28:04 +00001147 switch (e->tag) {
sewardje05c42c2004-07-08 20:25:10 +00001148 case Iex_LDle:
1149 return e->Iex.LDle.ty;
sewardjfbcaf332004-07-08 01:46:01 +00001150 case Iex_Get:
1151 return e->Iex.Get.ty;
sewardjbb53f8c2004-08-14 11:50:01 +00001152 case Iex_GetI:
sewardj2d3f77c2004-09-22 23:49:09 +00001153 return e->Iex.GetI.descr->elemTy;
sewardjc97096c2004-06-30 09:28:04 +00001154 case Iex_Tmp:
sewardj17442fe2004-09-20 14:54:28 +00001155 return typeOfIRTemp(tyenv, e->Iex.Tmp.tmp);
sewardjc97096c2004-06-30 09:28:04 +00001156 case Iex_Const:
sewardj695cff92004-10-13 14:50:14 +00001157 return typeOfIRConst(e->Iex.Const.con);
sewardjc97096c2004-06-30 09:28:04 +00001158 case Iex_Binop:
sewardj6efd4a12004-07-15 03:54:23 +00001159 typeOfPrimop(e->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1160 return t_dst;
1161 case Iex_Unop:
1162 typeOfPrimop(e->Iex.Unop.op, &t_dst, &t_arg1, &t_arg2);
1163 return t_dst;
1164 case Iex_CCall:
1165 return e->Iex.CCall.retty;
sewardj4042c7e2004-07-18 01:28:30 +00001166 case Iex_Mux0X:
sewardjedeb4c42004-09-21 23:39:25 +00001167 e = e->Iex.Mux0X.expr0;
1168 goto start;
1169 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */
sewardj443cd9d2004-07-18 23:06:45 +00001170 case Iex_Binder:
1171 vpanic("typeOfIRExpr: Binder is not a valid expression");
sewardjc97096c2004-06-30 09:28:04 +00001172 default:
sewardj6efd4a12004-07-15 03:54:23 +00001173 ppIRExpr(e);
1174 vpanic("typeOfIRExpr");
sewardjc97096c2004-06-30 09:28:04 +00001175 }
sewardjc97096c2004-06-30 09:28:04 +00001176}
sewardj887a11a2004-07-05 17:26:47 +00001177
sewardj6d2638e2004-07-15 09:38:27 +00001178/* Is this any value actually in the enumeration 'IRType' ? */
1179Bool isPlausibleType ( IRType ty )
1180{
1181 switch (ty) {
sewardjba999312004-11-15 15:21:17 +00001182 case Ity_INVALID: case Ity_I1:
sewardj6d2638e2004-07-15 09:38:27 +00001183 case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64:
sewardjbb53f8c2004-08-14 11:50:01 +00001184 case Ity_F32: case Ity_F64:
sewardj6d2638e2004-07-15 09:38:27 +00001185 return True;
1186 default:
1187 return False;
1188 }
1189}
1190
sewardj6efd4a12004-07-15 03:54:23 +00001191
sewardj887a11a2004-07-05 17:26:47 +00001192/*---------------------------------------------------------------*/
sewardjcf787902004-11-03 09:08:33 +00001193/*--- Sanity checking -- FLATNESS ---*/
1194/*---------------------------------------------------------------*/
1195
1196/* Check that the canonical flatness constraints hold on an
1197 IRStmt. The only place where any expression is allowed to be
1198 non-atomic is the RHS of IRStmt_Tmp. */
1199
1200/* Relies on:
1201 inline static Bool isAtom ( IRExpr* e ) {
1202 return e->tag == Iex_Tmp || e->tag == Iex_Const;
1203 }
1204*/
1205
1206Bool isFlatIRStmt ( IRStmt* st )
1207{
1208 Int i;
1209 IRExpr* e;
1210 IRDirty* di;
1211
1212 switch (st->tag) {
1213 case Ist_Put:
1214 return isAtom(st->Ist.Put.data);
1215 case Ist_PutI:
1216 return isAtom(st->Ist.PutI.ix) && isAtom(st->Ist.PutI.data);
1217 case Ist_Tmp:
1218 /* This is the only interesting case. The RHS can be any
1219 expression, *but* all its subexpressions *must* be
1220 atoms. */
1221 e = st->Ist.Tmp.data;
1222 switch (e->tag) {
1223 case Iex_Binder: return True;
1224 case Iex_Get: return True;
1225 case Iex_GetI: return isAtom(e->Iex.GetI.ix);
1226 case Iex_Tmp: return True;
1227 case Iex_Binop: return isAtom(e->Iex.Binop.arg1)
1228 && isAtom(e->Iex.Binop.arg2);
1229 case Iex_Unop: return isAtom(e->Iex.Unop.arg);
1230 case Iex_LDle: return isAtom(e->Iex.LDle.addr);
1231 case Iex_Const: return True;
1232 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
1233 if (!isAtom(e->Iex.CCall.args[i]))
1234 return False;
1235 return True;
1236 case Iex_Mux0X: return isAtom(e->Iex.Mux0X.cond)
1237 && isAtom(e->Iex.Mux0X.expr0)
1238 && isAtom(e->Iex.Mux0X.exprX);
1239 default: vpanic("isFlatIRStmt(e)");
1240 }
1241 /*notreached*/
1242 vassert(0);
1243 case Ist_STle:
1244 return isAtom(st->Ist.STle.addr) && isAtom(st->Ist.STle.data);
1245 case Ist_Dirty:
1246 di = st->Ist.Dirty.details;
1247 if (!isAtom(di->guard))
1248 return False;
1249 for (i = 0; di->args[i]; i++)
1250 if (!isAtom(di->args[i]))
1251 return False;
1252 if (di->mAddr && !isAtom(di->mAddr))
1253 return False;
1254 return True;
1255 case Ist_Exit:
1256 return isAtom(st->Ist.Exit.cond);
1257 default:
1258 vpanic("isFlatIRStmt(st)");
1259 }
1260}
1261
1262
1263/*---------------------------------------------------------------*/
sewardje539a402004-07-14 18:24:17 +00001264/*--- Sanity checking ---*/
1265/*---------------------------------------------------------------*/
1266
1267/* Checks:
1268
1269 Everything is type-consistent. No ill-typed anything.
sewardj35439212004-07-14 22:36:10 +00001270 The target address at the end of the BB is a 32- or 64-
1271 bit expression, depending on the guest's word size.
sewardje539a402004-07-14 18:24:17 +00001272
1273 Each temp is assigned only once, before its uses.
sewardjc13e2ed2004-10-31 21:44:54 +00001274*/
1275
1276static inline Int countArgs ( IRExpr** args )
1277{
1278 Int i;
1279 for (i = 0; args[i]; i++)
1280 ;
1281 return i;
1282}
sewardje539a402004-07-14 18:24:17 +00001283
sewardj35439212004-07-14 22:36:10 +00001284static
1285__attribute((noreturn))
1286void sanityCheckFail ( IRBB* bb, IRStmt* stmt, Char* what )
sewardje539a402004-07-14 18:24:17 +00001287{
sewardj35439212004-07-14 22:36:10 +00001288 vex_printf("\nIR SANITY CHECK FAILURE\n\n");
1289 ppIRBB(bb);
1290 if (stmt) {
1291 vex_printf("\nIN STATEMENT:\n\n");
1292 ppIRStmt(stmt);
1293 }
1294 vex_printf("\n\nERROR = %s\n\n", what );
1295 vpanic("sanityCheckFail: exiting due to bad IR");
1296}
1297
sewardj2d3f77c2004-09-22 23:49:09 +00001298static Bool saneIRArray ( IRArray* arr )
1299{
1300 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)
1301 return False;
sewardjba999312004-11-15 15:21:17 +00001302 if (arr->elemTy == Ity_I1)
sewardj2d3f77c2004-09-22 23:49:09 +00001303 return False;
1304 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)
1305 return False;
1306 return True;
1307}
1308
sewardj8ea867b2004-10-30 19:03:02 +00001309static Bool saneIRCallee ( IRCallee* cee )
1310{
1311 if (cee->name == NULL)
1312 return False;
1313 if (cee->addr == 0)
1314 return False;
sewardj77352542004-10-30 20:39:01 +00001315 if (cee->regparms < 0 || cee->regparms > 3)
sewardj8ea867b2004-10-30 19:03:02 +00001316 return False;
1317 return True;
1318}
1319
sewardj35439212004-07-14 22:36:10 +00001320
1321/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
1322 range ones. Report any which are read and for which the current
1323 def_count is zero. */
1324
1325static
sewardj17442fe2004-09-20 14:54:28 +00001326void useBeforeDef_Temp ( IRBB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts )
1327{
1328 if (tmp < 0 || tmp >= bb->tyenv->types_used)
1329 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
1330 if (def_counts[tmp] < 1)
1331 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
1332}
1333
1334static
sewardj35439212004-07-14 22:36:10 +00001335void useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
1336{
1337 Int i;
1338 switch (expr->tag) {
1339 case Iex_Get:
1340 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001341 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001342 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
sewardjbb53f8c2004-08-14 11:50:01 +00001343 break;
sewardj17442fe2004-09-20 14:54:28 +00001344 case Iex_Tmp:
1345 useBeforeDef_Temp(bb,stmt,expr->Iex.Tmp.tmp,def_counts);
sewardj35439212004-07-14 22:36:10 +00001346 break;
1347 case Iex_Binop:
1348 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
1349 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
1350 break;
1351 case Iex_Unop:
1352 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
1353 break;
1354 case Iex_LDle:
1355 useBeforeDef_Expr(bb,stmt,expr->Iex.LDle.addr,def_counts);
1356 break;
1357 case Iex_Const:
1358 break;
1359 case Iex_CCall:
1360 for (i = 0; expr->Iex.CCall.args[i]; i++)
1361 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
1362 break;
sewardj4042c7e2004-07-18 01:28:30 +00001363 case Iex_Mux0X:
1364 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
1365 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
1366 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
sewardjeeb9ef82004-07-15 12:39:03 +00001367 break;
1368 default:
1369 vpanic("useBeforeDef_Expr");
sewardj35439212004-07-14 22:36:10 +00001370 }
1371}
1372
1373static
1374void useBeforeDef_Stmt ( IRBB* bb, IRStmt* stmt, Int* def_counts )
1375{
sewardj17442fe2004-09-20 14:54:28 +00001376 Int i;
1377 IRDirty* d;
sewardj35439212004-07-14 22:36:10 +00001378 switch (stmt->tag) {
1379 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001380 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001381 break;
sewardjd1725d12004-08-12 20:46:53 +00001382 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +00001383 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);
sewardj2d3f77c2004-09-22 23:49:09 +00001384 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);
sewardjd1725d12004-08-12 20:46:53 +00001385 break;
sewardj35439212004-07-14 22:36:10 +00001386 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001387 useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);
sewardj35439212004-07-14 22:36:10 +00001388 break;
1389 case Ist_STle:
1390 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.addr,def_counts);
1391 useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.data,def_counts);
1392 break;
sewardj17442fe2004-09-20 14:54:28 +00001393 case Ist_Dirty:
1394 d = stmt->Ist.Dirty.details;
1395 for (i = 0; d->args[i] != NULL; i++)
1396 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);
1397 if (d->mFx != Ifx_None)
1398 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
1399 break;
sewardj35439212004-07-14 22:36:10 +00001400 case Ist_Exit:
1401 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.cond,def_counts);
1402 break;
1403 default:
1404 vpanic("useBeforeDef_Stmt");
1405 }
1406}
1407
sewardj6efd4a12004-07-15 03:54:23 +00001408static
1409void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
1410{
1411 Int i;
1412 IRType t_dst, t_arg1, t_arg2;
1413 IRTypeEnv* tyenv = bb->tyenv;
1414 switch (expr->tag) {
1415 case Iex_Get:
1416 case Iex_Tmp:
1417 break;
sewardjbb53f8c2004-08-14 11:50:01 +00001418 case Iex_GetI:
sewardjeeac8412004-11-02 00:26:55 +00001419 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
1420 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
1421 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001422 if (!saneIRArray(expr->Iex.GetI.descr))
1423 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
sewardjbb53f8c2004-08-14 11:50:01 +00001424 break;
sewardj6d2638e2004-07-15 09:38:27 +00001425 case Iex_Binop: {
1426 IRType ttarg1, ttarg2;
sewardj6efd4a12004-07-15 03:54:23 +00001427 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
1428 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
1429 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
sewardj8f3debf2004-09-08 23:42:23 +00001430 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID) {
1431 vex_printf(" op name: " );
1432 ppIROp(expr->Iex.Binop.op);
1433 vex_printf("\n");
1434 sanityCheckFail(bb,stmt,
1435 "Iex.Binop: wrong arity op\n"
1436 "... name of op precedes BB printout\n");
1437 }
sewardj6d2638e2004-07-15 09:38:27 +00001438 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
1439 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
1440 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
1441 vex_printf(" op name: ");
1442 ppIROp(expr->Iex.Binop.op);
1443 vex_printf("\n");
1444 vex_printf(" op type is (");
1445 ppIRType(t_arg1);
1446 vex_printf(",");
1447 ppIRType(t_arg2);
1448 vex_printf(") -> ");
1449 ppIRType (t_dst);
1450 vex_printf("\narg tys are (");
1451 ppIRType(ttarg1);
1452 vex_printf(",");
1453 ppIRType(ttarg2);
1454 vex_printf(")\n");
1455 sanityCheckFail(bb,stmt,
1456 "Iex.Binop: arg tys don't match op tys\n"
1457 "... additional details precede BB printout\n");
sewardj695cff92004-10-13 14:50:14 +00001458 }
sewardj6efd4a12004-07-15 03:54:23 +00001459 break;
sewardj6d2638e2004-07-15 09:38:27 +00001460 }
sewardj6efd4a12004-07-15 03:54:23 +00001461 case Iex_Unop:
1462 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
1463 typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
1464 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID)
1465 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
1466 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
1467 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
1468 break;
1469 case Iex_LDle:
1470 tcExpr(bb,stmt, expr->Iex.LDle.addr, gWordTy);
1471 if (typeOfIRExpr(tyenv, expr->Iex.LDle.addr) != gWordTy)
1472 sanityCheckFail(bb,stmt,"Iex.LDle.addr: not :: guest word type");
1473 break;
1474 case Iex_CCall:
sewardjc13e2ed2004-10-31 21:44:54 +00001475 if (!saneIRCallee(expr->Iex.CCall.cee))
1476 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee");
sewardjcf787902004-11-03 09:08:33 +00001477 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args))
sewardjc13e2ed2004-10-31 21:44:54 +00001478 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args");
sewardj43c56462004-11-06 12:17:57 +00001479 for (i = 0; expr->Iex.CCall.args[i]; i++) {
1480 if (i >= 32)
1481 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
sewardj6efd4a12004-07-15 03:54:23 +00001482 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy);
sewardj43c56462004-11-06 12:17:57 +00001483 }
sewardjba999312004-11-15 15:21:17 +00001484 if (expr->Iex.CCall.retty == Ity_I1)
1485 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001486 for (i = 0; expr->Iex.CCall.args[i]; i++)
sewardjba999312004-11-15 15:21:17 +00001487 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
1488 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001489 break;
1490 case Iex_Const:
1491 break;
sewardj4042c7e2004-07-18 01:28:30 +00001492 case Iex_Mux0X:
1493 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
1494 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
1495 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
1496 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
1497 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
1498 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
1499 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
1500 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
sewardjeeb9ef82004-07-15 12:39:03 +00001501 break;
1502 default:
sewardj6efd4a12004-07-15 03:54:23 +00001503 vpanic("tcExpr");
1504 }
1505}
1506
1507
1508static
1509void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
1510{
sewardj17442fe2004-09-20 14:54:28 +00001511 Int i;
1512 IRDirty* d;
sewardj6efd4a12004-07-15 03:54:23 +00001513 IRTypeEnv* tyenv = bb->tyenv;
1514 switch (stmt->tag) {
1515 case Ist_Put:
sewardj6d076362004-09-23 11:06:17 +00001516 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001517 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
1518 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
sewardj2d3f77c2004-09-22 23:49:09 +00001519 break;
sewardjd1725d12004-08-12 20:46:53 +00001520 case Ist_PutI:
sewardj2d3f77c2004-09-22 23:49:09 +00001521 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy );
sewardjeeac8412004-11-02 00:26:55 +00001522 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001523 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1)
1524 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
sewardj6d076362004-09-23 11:06:17 +00001525 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data)
1526 != stmt->Ist.PutI.descr->elemTy)
1527 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
sewardjeeac8412004-11-02 00:26:55 +00001528 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32)
1529 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
sewardj2d3f77c2004-09-22 23:49:09 +00001530 if (!saneIRArray(stmt->Ist.PutI.descr))
1531 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
1532 break;
sewardj6efd4a12004-07-15 03:54:23 +00001533 case Ist_Tmp:
sewardj6d076362004-09-23 11:06:17 +00001534 tcExpr( bb, stmt, stmt->Ist.Tmp.data, gWordTy );
sewardj17442fe2004-09-20 14:54:28 +00001535 if (typeOfIRTemp(tyenv, stmt->Ist.Tmp.tmp)
sewardj6d076362004-09-23 11:06:17 +00001536 != typeOfIRExpr(tyenv, stmt->Ist.Tmp.data))
sewardj6d2638e2004-07-15 09:38:27 +00001537 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
sewardj6efd4a12004-07-15 03:54:23 +00001538 break;
1539 case Ist_STle:
1540 tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
1541 tcExpr( bb, stmt, stmt->Ist.STle.data, gWordTy );
1542 if (typeOfIRExpr(tyenv, stmt->Ist.STle.addr) != gWordTy)
1543 sanityCheckFail(bb,stmt,"IRStmt.STle.addr: not :: guest word type");
sewardjba999312004-11-15 15:21:17 +00001544 if (typeOfIRExpr(tyenv, stmt->Ist.STle.data) == Ity_I1)
1545 sanityCheckFail(bb,stmt,"IRStmt.STle.data: cannot STle :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001546 break;
sewardj17442fe2004-09-20 14:54:28 +00001547 case Ist_Dirty:
1548 /* Mostly check for various kinds of ill-formed dirty calls. */
1549 d = stmt->Ist.Dirty.details;
sewardj8ea867b2004-10-30 19:03:02 +00001550 if (d->cee == NULL) goto bad_dirty;
1551 if (!saneIRCallee(d->cee)) goto bad_dirty;
sewardjcf787902004-11-03 09:08:33 +00001552 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001553 if (d->mFx == Ifx_None) {
1554 if (d->mAddr != NULL || d->mSize != 0)
1555 goto bad_dirty;
1556 } else {
1557 if (d->mAddr == NULL || d->mSize == 0)
1558 goto bad_dirty;
1559 }
1560 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
1561 goto bad_dirty;
sewardjc5fc7aa2004-10-27 23:00:55 +00001562 if (d->nFxState == 0 && d->needsBBP)
1563 goto bad_dirty;
sewardj17442fe2004-09-20 14:54:28 +00001564 for (i = 0; i < d->nFxState; i++) {
1565 if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
1566 if (d->fxState[i].size <= 0) goto bad_dirty;
1567 }
1568 /* check types, minimally */
sewardjb8385d82004-11-02 01:34:15 +00001569 if (d->guard == NULL) goto bad_dirty;
sewardjba999312004-11-15 15:21:17 +00001570 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
1571 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
sewardj92d168d2004-11-15 14:22:12 +00001572 if (d->tmp != IRTemp_INVALID
sewardjba999312004-11-15 15:21:17 +00001573 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1)
1574 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001575 for (i = 0; d->args[i] != NULL; i++) {
sewardj43c56462004-11-06 12:17:57 +00001576 if (i >= 32)
1577 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
sewardjba999312004-11-15 15:21:17 +00001578 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1)
1579 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
sewardj17442fe2004-09-20 14:54:28 +00001580 }
1581 break;
1582 bad_dirty:
1583 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
1584
sewardj6efd4a12004-07-15 03:54:23 +00001585 case Ist_Exit:
1586 tcExpr( bb, stmt, stmt->Ist.Exit.cond, gWordTy );
sewardjba999312004-11-15 15:21:17 +00001587 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.cond) != Ity_I1)
1588 sanityCheckFail(bb,stmt,"IRStmt.Exit.cond: not :: Ity_I1");
sewardj6efd4a12004-07-15 03:54:23 +00001589 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy)
1590 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type");
1591 break;
1592 default:
1593 vpanic("tcStmt");
1594 }
1595}
1596
sewardj35439212004-07-14 22:36:10 +00001597void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
1598{
1599 Int i;
1600 IRStmt* stmt;
1601 Int n_temps = bb->tyenv->types_used;
1602 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int));
1603
1604 vassert(guest_word_size == Ity_I32
sewardj695cff92004-10-13 14:50:14 +00001605 || guest_word_size == Ity_I64);
sewardj35439212004-07-14 22:36:10 +00001606
sewardjd7cb8532004-08-17 23:59:23 +00001607 if (bb->stmts_used < 0 || bb->stmts_size < 8
1608 || bb->stmts_used > bb->stmts_size)
1609 /* this BB is so strange we can't even print it */
1610 vpanic("sanityCheckIRBB: stmts array limits wierd");
1611
sewardj6d2638e2004-07-15 09:38:27 +00001612 /* Ensure each temp has a plausible type. */
1613 for (i = 0; i < n_temps; i++) {
sewardj17442fe2004-09-20 14:54:28 +00001614 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
sewardj6d2638e2004-07-15 09:38:27 +00001615 if (!isPlausibleType(ty)) {
1616 vex_printf("Temp t%d declared with implausible type 0x%x\n",
1617 i, (UInt)ty);
1618 sanityCheckFail(bb,NULL,"Temp declared with implausible type");
1619 }
1620 }
sewardj35439212004-07-14 22:36:10 +00001621
1622 /* Count the defs of each temp. Only one def is allowed.
1623 Also, check that each used temp has already been defd. */
sewardj6d2638e2004-07-15 09:38:27 +00001624
1625 for (i = 0; i < n_temps; i++)
1626 def_counts[i] = 0;
1627
sewardjd7cb8532004-08-17 23:59:23 +00001628 for (i = 0; i < bb->stmts_used; i++) {
1629 stmt = bb->stmts[i];
sewardj39e3f242004-08-18 16:54:52 +00001630 if (!stmt)
1631 continue;
sewardj35439212004-07-14 22:36:10 +00001632 useBeforeDef_Stmt(bb,stmt,def_counts);
sewardj17442fe2004-09-20 14:54:28 +00001633
sewardj35439212004-07-14 22:36:10 +00001634 if (stmt->tag == Ist_Tmp) {
1635 if (stmt->Ist.Tmp.tmp < 0 || stmt->Ist.Tmp.tmp >= n_temps)
sewardj17442fe2004-09-20 14:54:28 +00001636 sanityCheckFail(bb, stmt,
1637 "IRStmt.Tmp: destination tmp is out of range");
sewardj35439212004-07-14 22:36:10 +00001638 def_counts[stmt->Ist.Tmp.tmp]++;
1639 if (def_counts[stmt->Ist.Tmp.tmp] > 1)
sewardj17442fe2004-09-20 14:54:28 +00001640 sanityCheckFail(bb, stmt,
sewardjcf787902004-11-03 09:08:33 +00001641 "IRStmt.Tmp: destination tmp is assigned more than once");
sewardj17442fe2004-09-20 14:54:28 +00001642 }
1643 else
1644 if (stmt->tag == Ist_Dirty
sewardj92d168d2004-11-15 14:22:12 +00001645 && stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
sewardj17442fe2004-09-20 14:54:28 +00001646 IRDirty* d = stmt->Ist.Dirty.details;
1647 if (d->tmp < 0 || d->tmp >= n_temps)
1648 sanityCheckFail(bb, stmt,
1649 "IRStmt.Dirty: destination tmp is out of range");
1650 def_counts[d->tmp]++;
1651 if (def_counts[d->tmp] > 1)
1652 sanityCheckFail(bb, stmt,
1653 "IRStmt.Dirty: destination tmp is assigned more than once");
sewardj35439212004-07-14 22:36:10 +00001654 }
1655 }
1656
sewardj6efd4a12004-07-15 03:54:23 +00001657 /* Typecheck everything. */
sewardjd7cb8532004-08-17 23:59:23 +00001658 for (i = 0; i < bb->stmts_used; i++)
sewardj39e3f242004-08-18 16:54:52 +00001659 if (bb->stmts[i])
1660 tcStmt( bb, bb->stmts[i], guest_word_size );
sewardj6efd4a12004-07-15 03:54:23 +00001661 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
1662 sanityCheckFail(bb, NULL, "bb->next field has wrong type");
sewardje539a402004-07-14 18:24:17 +00001663}
1664
sewardj4345f7a2004-09-22 19:49:27 +00001665/*---------------------------------------------------------------*/
1666/*--- Misc helper functions ---*/
1667/*---------------------------------------------------------------*/
1668
1669Bool eqIRConst ( IRConst* c1, IRConst* c2 )
1670{
1671 if (c1->tag != c2->tag)
1672 return False;
1673
1674 switch (c1->tag) {
sewardjba999312004-11-15 15:21:17 +00001675 case Ico_U1: return (1 & c1->Ico.U1) == (1 & c2->Ico.U1);
sewardj4345f7a2004-09-22 19:49:27 +00001676 case Ico_U8: return c1->Ico.U8 == c2->Ico.U8;
1677 case Ico_U16: return c1->Ico.U16 == c2->Ico.U16;
1678 case Ico_U32: return c1->Ico.U32 == c2->Ico.U32;
1679 case Ico_U64: return c1->Ico.U64 == c2->Ico.U64;
1680 case Ico_F64: return c1->Ico.F64 == c2->Ico.F64;
1681 default: vpanic("eqIRConst");
1682 }
1683}
1684
sewardje98dcf22004-10-04 09:15:11 +00001685Bool eqIRArray ( IRArray* descr1, IRArray* descr2 )
1686{
1687 return descr1->base == descr2->base
1688 && descr1->elemTy == descr2->elemTy
1689 && descr1->nElems == descr2->nElems;
1690}
1691
sewardj2d3f77c2004-09-22 23:49:09 +00001692Int sizeofIRType ( IRType ty )
1693{
1694 switch (ty) {
1695 case Ity_I8: return 1;
1696 case Ity_I16: return 2;
1697 case Ity_I32: return 4;
sewardj49651f42004-10-28 22:11:04 +00001698 case Ity_I64: return 8;
1699 case Ity_F32: return 4;
sewardj2d3f77c2004-09-22 23:49:09 +00001700 case Ity_F64: return 8;
1701 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
1702 vpanic("sizeofIRType");
1703 }
1704}
1705
sewardj49651f42004-10-28 22:11:04 +00001706IRExpr* mkIRExpr_HWord ( HWord hw )
1707{
sewardjf9655262004-10-31 20:02:16 +00001708 vassert(sizeof(void*) == sizeof(HWord));
sewardj49651f42004-10-28 22:11:04 +00001709 if (sizeof(HWord) == 4)
1710 return IRExpr_Const(IRConst_U32((UInt)hw));
1711 if (sizeof(HWord) == 8)
sewardjf9655262004-10-31 20:02:16 +00001712 return IRExpr_Const(IRConst_U64((ULong)hw));
sewardj49651f42004-10-28 22:11:04 +00001713 vpanic("mkIRExpr_HWord");
1714}
sewardj6efd4a12004-07-15 03:54:23 +00001715
sewardjf9655262004-10-31 20:02:16 +00001716IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr,
1717 IRExpr** args )
1718{
1719 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001720 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001721 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001722 d->args = args;
sewardjf9655262004-10-31 20:02:16 +00001723 return d;
1724}
1725
1726IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1727 Int regparms, Char* name, void* addr,
1728 IRExpr** args )
1729{
1730 IRDirty* d = emptyIRDirty();
sewardjb8385d82004-11-02 01:34:15 +00001731 d->cee = mkIRCallee ( regparms, name, addr );
sewardjba999312004-11-15 15:21:17 +00001732 d->guard = IRExpr_Const(IRConst_U1(True));
sewardjb8385d82004-11-02 01:34:15 +00001733 d->args = args;
1734 d->tmp = dst;
sewardjf9655262004-10-31 20:02:16 +00001735 return d;
1736}
1737
1738IRExpr* mkIRExprCCall ( IRType retty,
1739 Int regparms, Char* name, void* addr,
1740 IRExpr** args )
1741{
1742 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ),
1743 retty, args );
1744}
1745
sewardje539a402004-07-14 18:24:17 +00001746/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +00001747/*--- end ir/irdefs.c ---*/
sewardj887a11a2004-07-05 17:26:47 +00001748/*---------------------------------------------------------------*/