#ifndef __IR_DEFS_H
#define __IR_DEFS_H
-//#include "storage.h"
-#include <stdio.h>
+#include <stdio.h> /* FILE* */
/*---------------------------------------------------------------*/
/*--- Type definitions for the IR ---*/
/*---------------------------------------------------------------*/
+/* Types */
+
+typedef
+ enum { Ity_Bit, Ity_I8, Ity_I16, Ity_I32, Ity_I64 }
+ IRType;
+
+
/* Constants */
typedef
IRConstTag;
typedef
- struct {
+ struct _IRConst {
IRConstTag tag;
union {
UChar u8;
typedef int IRTemp;
-/* Types */
-
-typedef
- enum { Ity_Bit, Ity_I8, Ity_I16, Ity_I32, Ity_I64 }
- IRType;
-
-
/* Binary and unary ops */
typedef
Iop_Shl32,
Iop_Shr32,
Iop_Sar32,
- // Tags for unary ops
+ /* Tags for unary ops */
Iop_Not32,
Iop_Neg32
}
IROp;
+/* Expressions
+
+data Expr
+ = GET Int Int -- offset, size
+ | TMP Temp -- value of temporary
+ | BINOP Op Expr Expr -- binary op
+ | UNOP Op Expr -- unary op
+ | LDle Type Expr -- load of the given type, Expr:: 32 or 64
+ | CONST Const -- 8/16/32/64-bit int constant
+*/
+typedef
+ enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle, Iex_Const }
+ IRExprTag;
+
+typedef
+ struct _IRExpr {
+ IRExprTag tag;
+ union {
+ struct {
+ Int offset;
+ Int size;
+ } Get;
+ struct {
+ IRTemp tmp;
+ } Tmp;
+ struct {
+ IROp op;
+ struct _IRExpr* arg1;
+ struct _IRExpr* arg2;
+ } Binop;
+ struct {
+ IROp op;
+ struct _IRExpr* arg;
+ } Unop;
+ struct {
+ IRType ty;
+ struct _IRExpr* addr;
+ } LDle;
+ struct {
+ struct _IRConst* con;
+ } Const;
+ } Iex;
+ }
+ IRExpr;
+
+
/* Statements:
data Stmt
IRNextTag tag;
union {
struct {
- IRConst dst;
+ struct _IRConst* dst;
} UJump;
struct {
- struct _IRExpr* cond;
- IRConst dst0;
- IRConst dst1;
+ struct _IRExpr* cond;
+ struct _IRConst* dst0;
+ struct _IRConst* dst1;
} CJump01;
struct {
struct _IRExpr* dst;
IRNext;
-/* Expressions
-
-data Expr
- = GET Int Int -- offset, size
- | TMP Temp -- value of temporary
- | BINOP Op Expr Expr -- binary op
- | UNOP Op Expr -- unary op
- | LDle Type Expr -- load of the given type, Expr:: 32 or 64
- | CONST Const -- 8/16/32/64-bit int constant
-*/
-typedef
- enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle, Iex_Const }
- IRExprTag;
-
-typedef
- struct _IRExpr {
- IRExprTag tag;
- union {
- struct {
- Int offset;
- Int size;
- } Get;
- struct {
- IRTemp tmp;
- } Tmp;
- struct {
- IROp op;
- struct _IRExpr* arg1;
- struct _IRExpr* arg2;
- } Binop;
- struct {
- IROp op;
- struct _IrExpr* arg;
- } Unop;
- struct {
- IRType ty;
- struct _IRExpr* addr;
- } LDle;
- struct {
- IRConst con;
- } Const;
- } Iex;
- }
- IRExpr;
-
-
/* Basic blocks contain 3 fields:
- An association list, giving a type for each temp
- A list of statements
- A Next
*/
-#define IR_BB 190 /* arity = 3 */
-
typedef
struct _IRBB {
struct _IRStmt* stmts;
/*---------------------------------------------------------------*/
/* Printers ... */
-extern void ppIRBB ( FILE* f, IRBB* );
-extern void ppIRNext ( FILE* f, IRNext* );
-extern void ppIRStmt ( FILE* f, IRStmt* );
-extern void ppIRExpr ( FILE* f, IRExpr* );
-extern void ppIRTemp ( FILE* f, IRTemp* );
-extern void ppIRType ( FILE* f, IRType* );
+extern void ppIRType ( FILE* f, IRType );
extern void ppIRConst ( FILE* f, IRConst* );
+extern void ppIRTemp ( FILE* f, IRTemp );
extern void ppIROp ( FILE* f, IROp );
+extern void ppIRExpr ( FILE* f, IRExpr* );
+extern void ppIRStmt ( FILE* f, IRStmt* );
+extern void ppIRNext ( FILE* f, IRNext* );
+extern void ppIRBB ( FILE* f, IRBB* );
-/* Constructors -- IRBB */
-extern IRBB* mkBB ( IRStmt* stmts, IRNext* next );
-
-/* Constructors -- IRNext */
-extern IRNext* mkUJump ( IRConst* dst );
+/* Constructors -- IRExpr */
+extern IRExpr* mkExGet ( Int off, Int sz );
+extern IRExpr* mkExTmp ( IRTemp tmp );
+extern IRExpr* mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
+extern IRExpr* mkExUnop ( IROp op, IRExpr* arg );
+extern IRExpr* mkExLDle ( IRType ty, IRExpr* addr );
+extern IRExpr* mkExConst ( IRConst* con );
/* Constructors -- IRStmt */
extern IRStmt* mkStPut ( Int off, Int sz, IRExpr* value );
extern IRStmt* mkStTmp ( IRTemp tmp, IRExpr* expr );
extern IRStmt* mkStSTle ( IRExpr* addr, IRExpr* value );
-/* Constructors -- IRExpr */
-extern IRExpr mkExGet ( Int off, Int sz );
-extern IRExpr mkExTmp ( IRTemp tmp );
-extern IRExpr mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
-extern IRExpr mkExUnop ( IROp op, IRExpr* arg );
-extern IRExpr mkExLDle ( IRType ty, IRExpr* addr );
-extern IRExpr mkExConst ( IRConst* con );
-
-/* Constructors -- IRTemp */
-extern IRTemp mkIRTemp ( Int n );
-
-/* Constructors -- IRType */
-/* Constructors -- IRAtomI */
-/* Constructors -- IROp */
+/* Constructors -- IRNext */
+extern IRNext* mkNxUJump ( IRConst* dst );
+
+/* Constructors -- IRBB */
+extern IRBB* mkIRBB ( IRStmt* stmts, IRNext* next );
#endif /* ndef __IR_DEFS_H */
/*--- ---*/
/*---------------------------------------------------------------*/
-#include <assert.h>
-
+#include "basictypes.h"
#include "ir_defs.h"
-
-/*---------------------------------------------------------------*/
-/*--- Registering the storage tags ---*/
-/*---------------------------------------------------------------*/
-
-void register_IR_tags ( void )
-{
- storage_register_tag(IR_TMP, 1, "tmp");
-
- storage_register_tag(TY_Bit, 0, "Bit");
- storage_register_tag(TY_I8, 0, "I8");
- storage_register_tag(TY_I16, 0, "I16");
- storage_register_tag(TY_I32, 0, "I32");
- storage_register_tag(TY_I64, 0, "I64");
-
- storage_register_tag(OP_Add32, 2, "Add32");
- storage_register_tag(OP_Sub32, 2, "Sub32");
- storage_register_tag(OP_Mul32, 2, "Mul32");
- storage_register_tag(OP_Or32, 2, "Or32" );
- storage_register_tag(OP_And32, 2, "And32");
- storage_register_tag(OP_Xor32, 2, "Xor32");
- storage_register_tag(OP_Shl32, 2, "Shl32");
- storage_register_tag(OP_Shr32, 2, "Shr32");
- storage_register_tag(OP_Sar32, 2, "Sar32");
-
- storage_register_tag(OP_Not32, 1, "Not32");
- storage_register_tag(OP_Neg32, 1, "Neg32");
-
- storage_register_tag(ST_Put, 3, "ST_Put");
- storage_register_tag(ST_Tmp, 2, "ST_Tmp");
- storage_register_tag(ST_STle, 2, "ST_STle");
-
- storage_register_tag(NX_UJump, 1, "NX_UJump");
- storage_register_tag(NX_CJump01, 3, "NX_CJump01");
- storage_register_tag(NX_IJump, 1, "NX_IJump");
-
- storage_register_tag(EX_Get, 2, "EX_Get");
- storage_register_tag(EX_Tmp, 1, "EX_Tmp");
- storage_register_tag(EX_Binop, 3, "EX_Binop");
- storage_register_tag(EX_Unop, 2, "EX_Unop");
- storage_register_tag(EX_LDle, 2, "EX_LDle");
- storage_register_tag(EX_AtomI, 1, "EX_AtomI");
-
- storage_register_tag(IR_BB, 3, "IR_BB");
-}
-
+#include <malloc.h>
/*---------------------------------------------------------------*/
/*--- Printing the IR ---*/
/*---------------------------------------------------------------*/
-void ppGuestAddr ( FILE* f, GuestAddr ga )
+void ppIRType ( FILE* f, IRType ty )
{
- switch (getTag(ga)) {
- case TagWord32: fprintf(f, "0x%x", getWord32(ga)); break;
- case TagWord64: fprintf(f, "0x%llx", getWord64(ga)); break;
- default: panic("ppGuestAddr");
+ switch (ty) {
+ case Ity_Bit: fprintf(f, "Bit"); break;
+ case Ity_I8: fprintf(f, "I8"); break;
+ case Ity_I16: fprintf(f, "I16"); break;
+ case Ity_I32: fprintf(f, "I32"); break;
+ case Ity_I64: fprintf(f, "I64"); break;
+ default: panic("ppIRType");
}
}
-void ppIROp ( FILE* f, IROp op )
+void ppIRConst ( FILE* f, IRConst* con )
{
- switch (getTag(op)) {
- case OP_Add32: fprintf(f, "Add32"); break;
- case OP_Sub32: fprintf(f, "Sub32"); break;
- case OP_Mul32: fprintf(f, "Mul32"); break;
- case OP_Or32: fprintf(f, "Or32"); break;
- case OP_And32: fprintf(f, "And32"); break;
- case OP_Xor32: fprintf(f, "Xor32"); break;
- case OP_Shl32: fprintf(f, "Shl32"); break;
- case OP_Shr32: fprintf(f, "Shr32"); break;
- case OP_Sar32: fprintf(f, "Sar32"); break;
- case OP_Not32: fprintf(f, "Not32"); break;
- case OP_Neg32: fprintf(f, "Neg32"); break;
- default: panic("ppIROp");
+ switch (con->tag) {
+ case Ico_u8: fprintf(f, "0x%x", (UInt)(con->Ico.u8)); break;
+ case Ico_u16: fprintf(f, "0x%x", (UInt)(con->Ico.u16)); break;
+ case Ico_u32: fprintf(f, "0x%x", (UInt)(con->Ico.u32)); break;
+ case Ico_u64: fprintf(f, "0x%llx", (ULong)(con->Ico.u64)); break;
+ default: panic("ppIRConst");
}
}
-void ppIRAtomI ( FILE* f, IRAtomI at )
+void ppIRTemp ( FILE* f, IRTemp tmp )
{
- switch (getTag(at)) {
- case TagWord8: fprintf(f, "0x%x", getWord8(at)); break;
- case TagWord16: fprintf(f, "0x%x", getWord16(at)); break;
- case TagWord32: fprintf(f, "0x%x", getWord32(at)); break;
- case TagWord64: fprintf(f, "0x%llx", getWord64(at)); break;
- default: panic("ppIRAtom");
- }
+ fprintf(f, "t%d", tmp);
}
-void ppIRType ( FILE* f, IRType ty )
+
+void ppIROp ( FILE* f, IROp op )
{
- switch (getTag(ty)) {
- case TY_Bit: fprintf(f, "Bit"); break;
- case TY_I8: fprintf(f, "I8"); break;
- case TY_I16: fprintf(f, "I16"); break;
- case TY_I32: fprintf(f, "I32"); break;
- case TY_I64: fprintf(f, "I64"); break;
- default: panic("ppIRType");
+ switch (op) {
+ case Iop_Add32: fprintf(f, "Add32"); break;
+ case Iop_Sub32: fprintf(f, "Sub32"); break;
+ case Iop_Mul32: fprintf(f, "Mul32"); break;
+ case Iop_Or32: fprintf(f, "Or32"); break;
+ case Iop_And32: fprintf(f, "And32"); break;
+ case Iop_Xor32: fprintf(f, "Xor32"); break;
+ case Iop_Shl32: fprintf(f, "Shl32"); break;
+ case Iop_Shr32: fprintf(f, "Shr32"); break;
+ case Iop_Sar32: fprintf(f, "Sar32"); break;
+ case Iop_Not32: fprintf(f, "Not32"); break;
+ case Iop_Neg32: fprintf(f, "Neg32"); break;
+ default: panic("ppIROp");
}
}
-void ppIRExpr ( FILE* f, IRExpr expr )
+void ppIRExpr ( FILE* f, IRExpr* e )
{
- switch (getTag(expr)) {
- case EX_Get:
- fprintf(f, "GET(%d,%d)", sel21(expr), sel22(expr));
+ switch (e->tag) {
+ case Iex_Get:
+ fprintf(f, "GET(%d,%d)", e->Iex.Get.offset, e->Iex.Get.size);
break;
- case EX_Tmp:
- ppIRTemp(f,sel11(expr));
+ case Iex_Tmp:
+ ppIRTemp(f, e->Iex.Tmp.tmp);
break;
- case EX_Binop:
- ppIROp(f,sel31(expr));
+ case Iex_Binop:
+ ppIROp(f, e->Iex.Binop.op);
fprintf(f, "(");
- ppIRExpr(f,sel32(expr));
+ ppIRExpr(f, e->Iex.Binop.arg1);
fprintf(f, ",");
- ppIRExpr(f,sel33(expr));
+ ppIRExpr(f, e->Iex.Binop.arg2);
fprintf(f, ")");
break;
- case EX_Unop:
- ppIROp(f,sel21(expr));
+ case Iex_Unop:
+ ppIROp(f, e->Iex.Unop.op);
fprintf(f, "(");
- ppIRExpr(f,sel22(expr));
+ ppIRExpr(f, e->Iex.Unop.arg);
fprintf(f, ")");
break;
- case EX_LDle:
+ case Iex_LDle:
fprintf(f, "LDle<");
- ppIRType(f, sel21(expr));
+ ppIRType(f, e->Iex.LDle.ty);
fprintf(f,">(");
- ppIRExpr(f, sel22(expr));
+ ppIRExpr(f, e->Iex.LDle.addr);
fprintf(f,")");
break;
- case EX_AtomI:
- ppIRAtomI(f, sel11(expr));
+ case Iex_Const:
+ ppIRConst(f, e->Iex.Const.con);
break;
default:
panic("ppIExpr");
}
}
-void ppIRTemp ( FILE* f, IRTemp tmp )
+void ppIRStmt ( FILE* f, IRStmt* s )
{
- switch (getTag(tmp)) {
- case IR_TMP: fprintf(f, "t%d", sel11(tmp)); break;
- default: panic("ppIRTemp");
- }
-}
-
-void ppIRStmt ( FILE* f, IRStmt stmt )
-{
- switch (getTag(stmt)) {
- case ST_Put:
- fprintf(f, "Put(%d,%d) = ", sel31(stmt), sel32(stmt));
- ppIRExpr(f, sel33(stmt));
+ switch (s->tag) {
+ case Ist_Put:
+ fprintf(f, "Put(%d,%d) = ", s->Ist.Put.offset, s->Ist.Put.size);
+ ppIRExpr(f, s->Ist.Put.expr);
break;
- case ST_Tmp:
- ppIRTemp(f, sel21(stmt));
+ case Ist_Tmp:
+ ppIRTemp(f, s->Ist.Tmp.tmp);
fprintf(f," = ");
- ppIRExpr(f, sel22(stmt));
+ ppIRExpr(f, s->Ist.Tmp.expr);
break;
- case ST_STle:
+ case Ist_STle:
fprintf(f, "STle(");
- ppIRExpr(f, sel21(stmt));
+ ppIRExpr(f, s->Ist.STle.addr);
fprintf(f, ") = ");
- ppIRExpr(f, sel22(stmt));
+ ppIRExpr(f, s->Ist.STle.data);
break;
default:
panic("ppIRStmt");
}
}
-void ppIRNext ( FILE* f, IRNext next )
+void ppIRNext ( FILE* f, IRNext* nx )
{
- switch (getTag(next)) {
- case NX_UJump:
+ switch (nx->tag) {
+ case Inx_UJump:
fprintf(f, "UJump ");
- ppGuestAddr(f,sel11(next));
+ ppIRConst(f, nx->Inx.UJump.dst);
break;
- case NX_CJump01:
+ case Inx_CJump01:
fprintf(f,"CJump01 (");
- ppIRExpr(f,sel31(next));
+ ppIRExpr(f, nx->Inx.CJump01.cond);
fprintf(f, ") ");
- ppGuestAddr(f,sel32(next));
+ ppIRConst(f, nx->Inx.CJump01.dst0);
fprintf(f, " ");
- ppGuestAddr(f,sel33(next));
- case NX_IJump:
+ ppIRConst(f, nx->Inx.CJump01.dst1);
+ break;
+ case Inx_IJump:
fprintf(f, "IJump ");
- ppIRExpr(f,sel11(next));
+ ppIRExpr(f, nx->Inx.IJump.dst);
break;
default:
panic("ppIRNext");
}
}
-void ppIRBB ( FILE* f, IRBB bb )
+void ppIRBB ( FILE* f, IRBB* bb )
{
- Cell sts;
- assert(getTag(bb) == IR_BB);
- for (sts = sel32(bb); nonNil(sts); sts=tail(sts)) {
+ IRStmt* s;
+ for (s = bb->stmts; s; s = s->link) {
fprintf(f, " ");
- ppIRStmt(f,head(sts));
+ ppIRStmt(f, s);
fprintf(f, "\n");
}
fprintf(f, " ");
- ppIRNext(f,sel33(bb));
+ ppIRNext(f, bb->next);
fprintf(f, "\n");
}
/*--- Constructors ---*/
/*---------------------------------------------------------------*/
-/* Constructors -- IRBB */
-IRBB mkBB ( AList tys, List stmts, IRNext next ) {
- return tuple3(IR_BB, tys, stmts, next);
-}
+/* Constructors -- IRExpr */
-/* Constructors -- IRNext */
-IRNext mkUJump ( GuestAddr dst ) {
- return tuple1 ( NX_UJump, dst );
+IRExpr* mkExGet ( Int off, Int sz ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_Get;
+ e->Iex.Get.offset = off;
+ e->Iex.Get.size = sz;
+ return e;
}
-
-/* Constructors -- IRStmt */
-IRStmt mkSTPut ( Int off, Int sz, IRExpr value ) {
- return tuple3 ( ST_Put, off, sz, value);
+IRExpr* mkExTmp ( IRTemp tmp ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_Tmp;
+ e->Iex.Tmp.tmp = tmp;
+ return e;
}
-IRStmt mkSTTmp ( IRTemp tmp, IRExpr expr ) {
- return tuple2 ( ST_Tmp, tmp, expr );
+IRExpr* mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_Binop;
+ e->Iex.Binop.op = op;
+ e->Iex.Binop.arg1 = arg1;
+ e->Iex.Binop.arg2 = arg2;
+ return e;
}
-IRStmt mkSTSTle ( IRExpr addr, IRExpr value ) {
- return tuple2 ( ST_STle, addr, value );
+IRExpr* mkExUnop ( IROp op, IRExpr* arg ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_Unop;
+ e->Iex.Unop.op = op;
+ e->Iex.Unop.arg = arg;
+ return e;
}
-
-/* Constructors -- IRExpr */
-IRExpr mkEXGet ( Int off, Int sz ) {
- return tuple2 ( EX_Get, off, sz );
+IRExpr* mkExLDle ( IRType ty, IRExpr* addr ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_LDle;
+ e->Iex.LDle.ty = ty;
+ e->Iex.LDle.addr = addr;
+ return e;
}
-IRExpr mkEXTmp ( IRTemp tmp ) {
- return tuple1 ( EX_Tmp, tmp );
+IRExpr* mkExConst ( IRConst* con ) {
+ IRExpr* e = malloc(sizeof(IRExpr));
+ e->tag = Iex_Const;
+ e->Iex.Const.con = con;
+ return e;
}
-IRExpr mkEXBinop ( IROp op, IRExpr arg1, IRExpr arg2 ) {
- return tuple3 ( EX_Binop, op, arg1, arg2 );
+
+
+/* Constructors -- IRStmt */
+
+IRStmt* mkStPut ( Int off, Int sz, IRExpr* value ) {
+ IRStmt* s = malloc(sizeof(IRStmt));
+ s->tag = Ist_Put;
+ s->Ist.Put.offset = off;
+ s->Ist.Put.size = sz;
+ s->Ist.Put.expr = value;
+ return s;
}
-IRExpr mkEXUnop ( IROp op, IRExpr arg ) {
- return tuple2 ( EX_Unop, op, arg );
+IRStmt* mkStTmp ( IRTemp tmp, IRExpr* expr ) {
+ IRStmt* s = malloc(sizeof(IRStmt));
+ s->tag = Ist_Tmp;
+ s->Ist.Tmp.tmp = tmp;
+ s->Ist.Tmp.expr = expr;
+ return s;
}
-IRExpr mkEXLDle ( IRType ty, IRExpr addr ) {
- return tuple2 ( EX_LDle, ty, addr );
+IRStmt* mkStSTle ( IRExpr* addr, IRExpr* value ) {
+ IRStmt* s = malloc(sizeof(IRStmt));
+ s->tag = Ist_STle;
+ s->Ist.STle.addr = addr;
+ s->Ist.STle.data = value;
+ return s;
}
-IRExpr mkEXAtomI ( IRAtomI atom ) {
- return tuple1 ( EX_AtomI, atom );
+
+
+/* Constructors -- IRNext */
+
+IRNext* mkNxUJump ( IRConst* dst ) {
+ IRNext* nx = malloc(sizeof(IRNext));
+ nx->tag = Inx_UJump;
+ nx->Inx.UJump.dst = dst;
+ return nx;
}
-/* Constructors -- IRTemp */
-IRTemp mkIRTemp ( Int n ) {
- return tuple1 ( IR_TMP, n );
+
+/* Constructors -- IRBB */
+
+IRBB* mkIRBB ( IRStmt* stmts, IRNext* next ) {
+ IRBB* bb = malloc(sizeof(IRBB));
+ bb->stmts = stmts;
+ bb->next = next;
+ return bb;
}
+
+