blob: 27ca1abf683f781689b7304f06bfdb0a0ae5d57a [file] [log] [blame]
sewardjec6ad592004-06-20 12:26:53 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
4/*--- This file (ir_defs.c) is ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjc97096c2004-06-30 09:28:04 +00009#include <stdio.h>
10#include <malloc.h>
11
sewardje3d0d2e2004-06-27 10:42:44 +000012#include "basictypes.h"
sewardjec6ad592004-06-20 12:26:53 +000013#include "ir_defs.h"
14
sewardjec6ad592004-06-20 12:26:53 +000015
16/*---------------------------------------------------------------*/
17/*--- Printing the IR ---*/
18/*---------------------------------------------------------------*/
19
sewardjec6ad592004-06-20 12:26:53 +000020void ppIRType ( FILE* f, IRType ty )
21{
sewardje3d0d2e2004-06-27 10:42:44 +000022 switch (ty) {
23 case Ity_Bit: fprintf(f, "Bit"); break;
24 case Ity_I8: fprintf(f, "I8"); break;
25 case Ity_I16: fprintf(f, "I16"); break;
26 case Ity_I32: fprintf(f, "I32"); break;
27 case Ity_I64: fprintf(f, "I64"); break;
sewardjec6ad592004-06-20 12:26:53 +000028 default: panic("ppIRType");
29 }
30}
31
sewardje3d0d2e2004-06-27 10:42:44 +000032void ppIRConst ( FILE* f, IRConst* con )
sewardjec6ad592004-06-20 12:26:53 +000033{
sewardje3d0d2e2004-06-27 10:42:44 +000034 switch (con->tag) {
sewardjc97096c2004-06-30 09:28:04 +000035 case Ico_U8: fprintf(f, "0x%x", (UInt)(con->Ico.U8)); break;
36 case Ico_U16: fprintf(f, "0x%x", (UInt)(con->Ico.U16)); break;
37 case Ico_U32: fprintf(f, "0x%x", (UInt)(con->Ico.U32)); break;
38 case Ico_U64: fprintf(f, "0x%llx", (ULong)(con->Ico.U64)); break;
sewardje3d0d2e2004-06-27 10:42:44 +000039 default: panic("ppIRConst");
40 }
41}
42
43void ppIRTemp ( FILE* f, IRTemp tmp )
44{
45 fprintf(f, "t%d", tmp);
46}
47
48
49void ppIROp ( FILE* f, IROp op )
50{
51 switch (op) {
52 case Iop_Add32: fprintf(f, "Add32"); break;
53 case Iop_Sub32: fprintf(f, "Sub32"); break;
54 case Iop_Mul32: fprintf(f, "Mul32"); break;
55 case Iop_Or32: fprintf(f, "Or32"); break;
56 case Iop_And32: fprintf(f, "And32"); break;
57 case Iop_Xor32: fprintf(f, "Xor32"); break;
58 case Iop_Shl32: fprintf(f, "Shl32"); break;
59 case Iop_Shr32: fprintf(f, "Shr32"); break;
60 case Iop_Sar32: fprintf(f, "Sar32"); break;
61 case Iop_Not32: fprintf(f, "Not32"); break;
62 case Iop_Neg32: fprintf(f, "Neg32"); break;
63 default: panic("ppIROp");
64 }
65}
66
67void ppIRExpr ( FILE* f, IRExpr* e )
68{
69 switch (e->tag) {
70 case Iex_Get:
71 fprintf(f, "GET(%d,%d)", e->Iex.Get.offset, e->Iex.Get.size);
sewardjec6ad592004-06-20 12:26:53 +000072 break;
sewardje3d0d2e2004-06-27 10:42:44 +000073 case Iex_Tmp:
74 ppIRTemp(f, e->Iex.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +000075 break;
sewardje3d0d2e2004-06-27 10:42:44 +000076 case Iex_Binop:
77 ppIROp(f, e->Iex.Binop.op);
sewardjec6ad592004-06-20 12:26:53 +000078 fprintf(f, "(");
sewardje3d0d2e2004-06-27 10:42:44 +000079 ppIRExpr(f, e->Iex.Binop.arg1);
sewardjec6ad592004-06-20 12:26:53 +000080 fprintf(f, ",");
sewardje3d0d2e2004-06-27 10:42:44 +000081 ppIRExpr(f, e->Iex.Binop.arg2);
sewardjec6ad592004-06-20 12:26:53 +000082 fprintf(f, ")");
83 break;
sewardje3d0d2e2004-06-27 10:42:44 +000084 case Iex_Unop:
85 ppIROp(f, e->Iex.Unop.op);
sewardjec6ad592004-06-20 12:26:53 +000086 fprintf(f, "(");
sewardje3d0d2e2004-06-27 10:42:44 +000087 ppIRExpr(f, e->Iex.Unop.arg);
sewardjec6ad592004-06-20 12:26:53 +000088 fprintf(f, ")");
89 break;
sewardje3d0d2e2004-06-27 10:42:44 +000090 case Iex_LDle:
sewardjec6ad592004-06-20 12:26:53 +000091 fprintf(f, "LDle<");
sewardje3d0d2e2004-06-27 10:42:44 +000092 ppIRType(f, e->Iex.LDle.ty);
sewardjec6ad592004-06-20 12:26:53 +000093 fprintf(f,">(");
sewardje3d0d2e2004-06-27 10:42:44 +000094 ppIRExpr(f, e->Iex.LDle.addr);
sewardjec6ad592004-06-20 12:26:53 +000095 fprintf(f,")");
96 break;
sewardje3d0d2e2004-06-27 10:42:44 +000097 case Iex_Const:
98 ppIRConst(f, e->Iex.Const.con);
sewardjec6ad592004-06-20 12:26:53 +000099 break;
100 default:
101 panic("ppIExpr");
102 }
103}
104
sewardje3d0d2e2004-06-27 10:42:44 +0000105void ppIRStmt ( FILE* f, IRStmt* s )
sewardjec6ad592004-06-20 12:26:53 +0000106{
sewardje3d0d2e2004-06-27 10:42:44 +0000107 switch (s->tag) {
108 case Ist_Put:
109 fprintf(f, "Put(%d,%d) = ", s->Ist.Put.offset, s->Ist.Put.size);
110 ppIRExpr(f, s->Ist.Put.expr);
sewardjec6ad592004-06-20 12:26:53 +0000111 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000112 case Ist_Tmp:
113 ppIRTemp(f, s->Ist.Tmp.tmp);
sewardjec6ad592004-06-20 12:26:53 +0000114 fprintf(f," = ");
sewardje3d0d2e2004-06-27 10:42:44 +0000115 ppIRExpr(f, s->Ist.Tmp.expr);
sewardjec6ad592004-06-20 12:26:53 +0000116 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000117 case Ist_STle:
sewardjec6ad592004-06-20 12:26:53 +0000118 fprintf(f, "STle(");
sewardje3d0d2e2004-06-27 10:42:44 +0000119 ppIRExpr(f, s->Ist.STle.addr);
sewardjec6ad592004-06-20 12:26:53 +0000120 fprintf(f, ") = ");
sewardje3d0d2e2004-06-27 10:42:44 +0000121 ppIRExpr(f, s->Ist.STle.data);
sewardjec6ad592004-06-20 12:26:53 +0000122 break;
123 default:
124 panic("ppIRStmt");
125 }
126}
127
sewardje3d0d2e2004-06-27 10:42:44 +0000128void ppIRNext ( FILE* f, IRNext* nx )
sewardjec6ad592004-06-20 12:26:53 +0000129{
sewardje3d0d2e2004-06-27 10:42:44 +0000130 switch (nx->tag) {
131 case Inx_UJump:
sewardjec6ad592004-06-20 12:26:53 +0000132 fprintf(f, "UJump ");
sewardje3d0d2e2004-06-27 10:42:44 +0000133 ppIRConst(f, nx->Inx.UJump.dst);
sewardjec6ad592004-06-20 12:26:53 +0000134 break;
sewardje3d0d2e2004-06-27 10:42:44 +0000135 case Inx_CJump01:
sewardjec6ad592004-06-20 12:26:53 +0000136 fprintf(f,"CJump01 (");
sewardje3d0d2e2004-06-27 10:42:44 +0000137 ppIRExpr(f, nx->Inx.CJump01.cond);
sewardjec6ad592004-06-20 12:26:53 +0000138 fprintf(f, ") ");
sewardje3d0d2e2004-06-27 10:42:44 +0000139 ppIRConst(f, nx->Inx.CJump01.dst0);
sewardjec6ad592004-06-20 12:26:53 +0000140 fprintf(f, " ");
sewardje3d0d2e2004-06-27 10:42:44 +0000141 ppIRConst(f, nx->Inx.CJump01.dst1);
142 break;
143 case Inx_IJump:
sewardjec6ad592004-06-20 12:26:53 +0000144 fprintf(f, "IJump ");
sewardje3d0d2e2004-06-27 10:42:44 +0000145 ppIRExpr(f, nx->Inx.IJump.dst);
sewardjec6ad592004-06-20 12:26:53 +0000146 break;
147 default:
148 panic("ppIRNext");
149 }
150}
151
sewardjc97096c2004-06-30 09:28:04 +0000152void ppIRTypeEnv ( FILE* f, IRTypeEnv* env ) {
153 UInt i;
154 for (i = 0; i < env->map_used; i++) {
155 if (i % 8 == 0)
156 fprintf(f, " ");
157 ppIRTemp(f, env->map[i].name);
158 fprintf(f, ":");
159 ppIRType(f, env->map[i].type);
160 if (i % 8 == 7)
161 fprintf(f, "\n");
162 else
163 fprintf(f, " ");
164 }
165 if (env->map_used > 0 && env->map_used % 8 != 7)
166 fprintf(f, "\n");
167}
168
169
sewardje3d0d2e2004-06-27 10:42:44 +0000170void ppIRBB ( FILE* f, IRBB* bb )
sewardjec6ad592004-06-20 12:26:53 +0000171{
sewardje3d0d2e2004-06-27 10:42:44 +0000172 IRStmt* s;
sewardjc97096c2004-06-30 09:28:04 +0000173 ppIRTypeEnv(f, bb->tyenv);
sewardje3d0d2e2004-06-27 10:42:44 +0000174 for (s = bb->stmts; s; s = s->link) {
sewardjec6ad592004-06-20 12:26:53 +0000175 fprintf(f, " ");
sewardje3d0d2e2004-06-27 10:42:44 +0000176 ppIRStmt(f, s);
sewardjec6ad592004-06-20 12:26:53 +0000177 fprintf(f, "\n");
178 }
179 fprintf(f, " ");
sewardje3d0d2e2004-06-27 10:42:44 +0000180 ppIRNext(f, bb->next);
sewardjec6ad592004-06-20 12:26:53 +0000181 fprintf(f, "\n");
182}
183
184
185/*---------------------------------------------------------------*/
186/*--- Constructors ---*/
187/*---------------------------------------------------------------*/
188
sewardjc97096c2004-06-30 09:28:04 +0000189
190/* Constructors -- IRConst */
191
192IRConst* IRConst_U8 ( UChar u8 )
193{
194 IRConst* c = malloc(sizeof(IRConst));
195 c->tag = Ico_U8;
196 c->Ico.U8 = u8;
197 return c;
198}
199IRConst* IRConst_U16 ( UShort u16 )
200{
201 IRConst* c = malloc(sizeof(IRConst));
202 c->tag = Ico_U16;
203 c->Ico.U16 = u16;
204 return c;
205}
206IRConst* IRConst_U32 ( UInt u32 )
207{
208 IRConst* c = malloc(sizeof(IRConst));
209 c->tag = Ico_U32;
210 c->Ico.U32 = u32;
211 return c;
212}
213IRConst* IRConst_U64 ( ULong u64 )
214{
215 IRConst* c = malloc(sizeof(IRConst));
216 c->tag = Ico_U64;
217 c->Ico.U64 = u64;
218 return c;
219}
220
221
sewardje3d0d2e2004-06-27 10:42:44 +0000222/* Constructors -- IRExpr */
223
sewardjc97096c2004-06-30 09:28:04 +0000224IRExpr* IRExpr_Get ( Int off, Int sz ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000225 IRExpr* e = malloc(sizeof(IRExpr));
226 e->tag = Iex_Get;
227 e->Iex.Get.offset = off;
228 e->Iex.Get.size = sz;
229 return e;
230}
sewardjc97096c2004-06-30 09:28:04 +0000231IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000232 IRExpr* e = malloc(sizeof(IRExpr));
233 e->tag = Iex_Tmp;
234 e->Iex.Tmp.tmp = tmp;
235 return e;
236}
sewardjc97096c2004-06-30 09:28:04 +0000237IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000238 IRExpr* e = malloc(sizeof(IRExpr));
239 e->tag = Iex_Binop;
240 e->Iex.Binop.op = op;
241 e->Iex.Binop.arg1 = arg1;
242 e->Iex.Binop.arg2 = arg2;
243 return e;
244}
sewardjc97096c2004-06-30 09:28:04 +0000245IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000246 IRExpr* e = malloc(sizeof(IRExpr));
247 e->tag = Iex_Unop;
248 e->Iex.Unop.op = op;
249 e->Iex.Unop.arg = arg;
250 return e;
251}
sewardjc97096c2004-06-30 09:28:04 +0000252IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000253 IRExpr* e = malloc(sizeof(IRExpr));
254 e->tag = Iex_LDle;
255 e->Iex.LDle.ty = ty;
256 e->Iex.LDle.addr = addr;
257 return e;
258}
sewardjc97096c2004-06-30 09:28:04 +0000259IRExpr* IRExpr_Const ( IRConst* con ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000260 IRExpr* e = malloc(sizeof(IRExpr));
261 e->tag = Iex_Const;
262 e->Iex.Const.con = con;
263 return e;
sewardjec6ad592004-06-20 12:26:53 +0000264}
265
sewardjec6ad592004-06-20 12:26:53 +0000266
267/* Constructors -- IRStmt */
sewardje3d0d2e2004-06-27 10:42:44 +0000268
sewardjc97096c2004-06-30 09:28:04 +0000269IRStmt* IRStmt_Put ( Int off, Int sz, IRExpr* value ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000270 IRStmt* s = malloc(sizeof(IRStmt));
271 s->tag = Ist_Put;
sewardjc97096c2004-06-30 09:28:04 +0000272 s->link = NULL;
sewardje3d0d2e2004-06-27 10:42:44 +0000273 s->Ist.Put.offset = off;
274 s->Ist.Put.size = sz;
275 s->Ist.Put.expr = value;
276 return s;
sewardjec6ad592004-06-20 12:26:53 +0000277}
sewardjc97096c2004-06-30 09:28:04 +0000278IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000279 IRStmt* s = malloc(sizeof(IRStmt));
280 s->tag = Ist_Tmp;
sewardjc97096c2004-06-30 09:28:04 +0000281 s->link = NULL;
sewardje3d0d2e2004-06-27 10:42:44 +0000282 s->Ist.Tmp.tmp = tmp;
283 s->Ist.Tmp.expr = expr;
284 return s;
sewardjec6ad592004-06-20 12:26:53 +0000285}
sewardjc97096c2004-06-30 09:28:04 +0000286IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000287 IRStmt* s = malloc(sizeof(IRStmt));
288 s->tag = Ist_STle;
sewardjc97096c2004-06-30 09:28:04 +0000289 s->link = NULL;
sewardje3d0d2e2004-06-27 10:42:44 +0000290 s->Ist.STle.addr = addr;
291 s->Ist.STle.data = value;
292 return s;
sewardjec6ad592004-06-20 12:26:53 +0000293}
294
sewardje3d0d2e2004-06-27 10:42:44 +0000295
296/* Constructors -- IRNext */
297
sewardjc97096c2004-06-30 09:28:04 +0000298IRNext* IRNext_UJump ( IRConst* dst ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000299 IRNext* nx = malloc(sizeof(IRNext));
300 nx->tag = Inx_UJump;
301 nx->Inx.UJump.dst = dst;
302 return nx;
sewardjec6ad592004-06-20 12:26:53 +0000303}
304
sewardje3d0d2e2004-06-27 10:42:44 +0000305
306/* Constructors -- IRBB */
307
sewardjc97096c2004-06-30 09:28:04 +0000308IRBB* mk_IRBB ( IRTypeEnv* env, IRStmt* stmts, IRNext* next ) {
sewardje3d0d2e2004-06-27 10:42:44 +0000309 IRBB* bb = malloc(sizeof(IRBB));
sewardjc97096c2004-06-30 09:28:04 +0000310 bb->tyenv = env;
sewardje3d0d2e2004-06-27 10:42:44 +0000311 bb->stmts = stmts;
312 bb->next = next;
313 return bb;
sewardjec6ad592004-06-20 12:26:53 +0000314}
315
316
sewardjc97096c2004-06-30 09:28:04 +0000317/*---------------------------------------------------------------*/
318/*--- Helper functions for the IR ---*/
319/*---------------------------------------------------------------*/
320
321IRTypeEnv* newIRTypeEnv ( void )
322{
323 IRTypeEnv* env = malloc(sizeof(IRTypeEnv));
324 env->map = NULL;
325 env->map_size = 0;
326 env->map_used = 0;
327 return env;
328}
sewardje3d0d2e2004-06-27 10:42:44 +0000329
330
sewardjc97096c2004-06-30 09:28:04 +0000331void addToIRTypeEnv ( IRTypeEnv* env, IRTemp tmp, IRType ty )
332{
333 assert(env);
334 assert(env->map_used >= 0);
335 assert(env->map_size >= 0);
336 assert(env->map_used <= env->map_size);
337 if (env->map_used < env->map_size) {
338 env->map[env->map_used].name = tmp;
339 env->map[env->map_used].type = ty;
340 env->map_used++;
341 } else {
342 Int i;
343 Int new_size = env->map_size==0 ? 8 : 2*env->map_size;
344 IRTypeEnvMaplet* new_map = malloc(new_size * sizeof(IRTypeEnvMaplet));
345 for (i = 0; i < env->map_used; i++)
346 new_map[i] = env->map[i];
347 env->map = new_map;
348 env->map_size = new_size;
349 return addToIRTypeEnv(env, tmp, ty);
350 }
351}
352
353
354IRType lookupIRTypeEnv ( IRTypeEnv* env, IRTemp tmp )
355{
356 Int i;
357 for (i = 0; i < env->map_used; i++)
358 if (env->map[i].name == tmp)
359 return env->map[i].type;
360 panic("lookupIRTypeEnv");
361}
362
363
364IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
365{
366 switch (e->tag) {
367 case Iex_Tmp:
368 return lookupIRTypeEnv(tyenv, e->Iex.Tmp.tmp);
369 case Iex_Const:
370 switch (e->Iex.Const.con->tag) {
371 case Ico_U8: return Ity_I8;
372 case Ico_U16: return Ity_I16;
373 case Ico_U32: return Ity_I32;
374 case Ico_U64: return Ity_I64;
375 default: panic("typeOfIRExpr:Iex_Const");
376 }
377 break;
378 case Iex_Binop:
379 switch (e->Iex.Binop.op) {
380 case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
381 case Iop_Or32: case Iop_And32: case Iop_Xor32:
382 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
383 return Ity_I32;
384 default: break;
385 }
386 break;
387 default:
388 break;
389 }
390 ppIRExpr(stderr,e);
391 panic("typeOfIRExpr");
392}