blob: 7a42ed2b839bb2d7c65287a3b9d0f177a6c6382d [file] [log] [blame]
sewardjec6ad592004-06-20 12:26:53 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardj887a11a2004-07-05 17:26:47 +00004/*--- This file (libvex_ir.h) is ---*/
sewardjec6ad592004-06-20 12:26:53 +00005/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardj887a11a2004-07-05 17:26:47 +00009#ifndef __LIBVEX_IR_H
10#define __LIBVEX_IR_H
sewardjac9af022004-07-05 01:15:34 +000011
sewardj887a11a2004-07-05 17:26:47 +000012#include "libvex_basictypes.h"
sewardjec6ad592004-06-20 12:26:53 +000013
sewardjec6ad592004-06-20 12:26:53 +000014
15/*---------------------------------------------------------------*/
sewardjac6b7122004-06-27 01:03:57 +000016/*--- Type definitions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +000017/*---------------------------------------------------------------*/
18
sewardjc97096c2004-06-30 09:28:04 +000019/* ------------------ Types ------------------ */
sewardje3d0d2e2004-06-27 10:42:44 +000020
21typedef
sewardj6efd4a12004-07-15 03:54:23 +000022 enum { Ity_INVALID=0x10FFF,
23 Ity_Bit=0x11000,
sewardje05c42c2004-07-08 20:25:10 +000024 Ity_I8, Ity_I16, Ity_I32, Ity_I64 }
sewardje3d0d2e2004-06-27 10:42:44 +000025 IRType;
26
sewardj35421a32004-07-05 13:12:34 +000027extern void ppIRType ( IRType );
sewardje3d0d2e2004-06-27 10:42:44 +000028
sewardjc97096c2004-06-30 09:28:04 +000029
30/* ------------------ Constants ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000031
sewardjac6b7122004-06-27 01:03:57 +000032typedef
sewardje8e9d732004-07-16 21:03:45 +000033 enum { Ico_U8=0x12000,
34 Ico_U16, Ico_U32, Ico_U64 }
sewardjac6b7122004-06-27 01:03:57 +000035 IRConstTag;
36
37typedef
sewardje3d0d2e2004-06-27 10:42:44 +000038 struct _IRConst {
sewardjac6b7122004-06-27 01:03:57 +000039 IRConstTag tag;
40 union {
sewardjc97096c2004-06-30 09:28:04 +000041 UChar U8;
42 UShort U16;
43 UInt U32;
44 ULong U64;
sewardjac6b7122004-06-27 01:03:57 +000045 } Ico;
46 }
47 IRConst;
sewardjec6ad592004-06-20 12:26:53 +000048
sewardjc97096c2004-06-30 09:28:04 +000049extern IRConst* IRConst_U8 ( UChar );
50extern IRConst* IRConst_U16 ( UShort );
51extern IRConst* IRConst_U32 ( UInt );
52extern IRConst* IRConst_U64 ( ULong );
sewardjec6ad592004-06-20 12:26:53 +000053
sewardj35421a32004-07-05 13:12:34 +000054extern void ppIRConst ( IRConst* );
sewardjc97096c2004-06-30 09:28:04 +000055
56
57/* ------------------ Temporaries ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000058
sewardjfbcaf332004-07-08 01:46:01 +000059typedef UInt IRTemp;
sewardjec6ad592004-06-20 12:26:53 +000060
sewardj35421a32004-07-05 13:12:34 +000061extern void ppIRTemp ( IRTemp );
sewardjec6ad592004-06-20 12:26:53 +000062
sewardjfbcaf332004-07-08 01:46:01 +000063#define INVALID_IRTEMP ((IRTemp)0xFFFFFFFF)
64
sewardjc97096c2004-06-30 09:28:04 +000065
66/* ------------------ Binary and unary ops ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000067
sewardjac6b7122004-06-27 01:03:57 +000068typedef
sewardj41f43bc2004-07-08 14:23:22 +000069 enum {
70 /* Do not change this ordering. The IR generators
71 rely on (eg) Iop_Add64 == IopAdd8 + 3. */
sewardje8e9d732004-07-16 21:03:45 +000072 Iop_Add8=0x13000,
sewardje05c42c2004-07-08 20:25:10 +000073 Iop_Add16, Iop_Add32, Iop_Add64,
sewardj41f43bc2004-07-08 14:23:22 +000074 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
75 Iop_Adc8, Iop_Adc16, Iop_Adc32, Iop_Adc64,
76 Iop_Sbb8, Iop_Sbb16, Iop_Sbb32, Iop_Sbb64,
77 /* Signless mul. MullS/MullU is elsewhere. */
78 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
79 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
80 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
81 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
82 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
83 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
84 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
sewardje90ad6a2004-07-10 19:02:10 +000085 /* Integer comparisons. */
86 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
87 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
sewardj41f43bc2004-07-08 14:23:22 +000088 /* Tags for unary ops */
89 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
sewardje87b4842004-07-10 12:23:30 +000090 Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64,
sewardj9690d922004-07-14 01:39:17 +000091 /* Widening multiplies */
92 Iop_MullS8, Iop_MullS16, Iop_MullS32,
93 Iop_MullU8, Iop_MullU16, Iop_MullU32,
94 /* Ordering not important after here. */
95 /* Division */
96 Iop_DivModU64to32, // :: I64,I32 -> I64
97 // of which lo half is div and hi half is mod
98 Iop_DivModS64to32, // ditto, signed
99 /* Widening conversions */
sewardj9334b0f2004-07-10 22:43:54 +0000100 Iop_8Uto16, Iop_8Uto32, Iop_16Uto32,
101 Iop_8Sto16, Iop_8Sto32, Iop_16Sto32,
sewardj9690d922004-07-14 01:39:17 +0000102 /* 32 <-> 64 bit conversions */
103 Iop_64LOto32, // :: I64 -> I32, low half
104 Iop_64HIto32, // :: I64 -> I32, high half
105 Iop_32HLto64, // :: (I32,I32) -> I64
sewardjcf780b42004-07-13 18:42:17 +0000106 /* 1-bit stuff */
sewardj77b86be2004-07-11 13:28:24 +0000107 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
108 Iop_1Uto8 /* :: Ity_Bit -> Ity_I8, unsigned widen */
sewardjac6b7122004-06-27 01:03:57 +0000109 }
110 IROp;
sewardjec6ad592004-06-20 12:26:53 +0000111
sewardj35421a32004-07-05 13:12:34 +0000112extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +0000113
sewardje3d0d2e2004-06-27 10:42:44 +0000114
sewardjc97096c2004-06-30 09:28:04 +0000115/* ------------------ Expressions ------------------ */
116/*
sewardje3d0d2e2004-06-27 10:42:44 +0000117data Expr
118 = GET Int Int -- offset, size
119 | TMP Temp -- value of temporary
120 | BINOP Op Expr Expr -- binary op
121 | UNOP Op Expr -- unary op
122 | LDle Type Expr -- load of the given type, Expr:: 32 or 64
123 | CONST Const -- 8/16/32/64-bit int constant
124*/
125typedef
sewardje87b4842004-07-10 12:23:30 +0000126 enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle,
sewardjeeb9ef82004-07-15 12:39:03 +0000127 Iex_Const, Iex_CCall, Iex_Mux10 }
sewardje3d0d2e2004-06-27 10:42:44 +0000128 IRExprTag;
129
130typedef
131 struct _IRExpr {
132 IRExprTag tag;
133 union {
134 struct {
sewardjfbcaf332004-07-08 01:46:01 +0000135 Int offset;
136 IRType ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000137 } Get;
138 struct {
139 IRTemp tmp;
140 } Tmp;
141 struct {
142 IROp op;
143 struct _IRExpr* arg1;
144 struct _IRExpr* arg2;
145 } Binop;
146 struct {
147 IROp op;
148 struct _IRExpr* arg;
149 } Unop;
150 struct {
151 IRType ty;
152 struct _IRExpr* addr;
153 } LDle;
154 struct {
sewardj66f2f792004-06-30 16:37:16 +0000155 IRConst* con;
sewardje3d0d2e2004-06-27 10:42:44 +0000156 } Const;
sewardje87b4842004-07-10 12:23:30 +0000157 struct {
158 Char* name;
159 IRType retty;
160 struct _IRExpr** args;
161 } CCall;
sewardjeeb9ef82004-07-15 12:39:03 +0000162 struct {
163 struct _IRExpr* cond;
164 struct _IRExpr* expr1;
165 struct _IRExpr* expr0;
166 } Mux10;
sewardje3d0d2e2004-06-27 10:42:44 +0000167 } Iex;
168 }
169 IRExpr;
170
sewardjfbcaf332004-07-08 01:46:01 +0000171extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjc97096c2004-06-30 09:28:04 +0000172extern IRExpr* IRExpr_Tmp ( IRTemp tmp );
173extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
174extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
175extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr );
176extern IRExpr* IRExpr_Const ( IRConst* con );
sewardje87b4842004-07-10 12:23:30 +0000177extern IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args );
sewardjeeb9ef82004-07-15 12:39:03 +0000178extern IRExpr* IRExpr_Mux10 ( IRExpr* cond, IRExpr* expr1, IRExpr* expr0 );
sewardje3d0d2e2004-06-27 10:42:44 +0000179
sewardj35421a32004-07-05 13:12:34 +0000180extern void ppIRExpr ( IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +0000181
sewardje87b4842004-07-10 12:23:30 +0000182/* CCall info. The name is the C helper function; the backends
183 will look it up in a table of known helpers, to get the address.
184
185 The args are a NULL-terminated array of arguments. The stated
186 return IRType, and the implied argument types, must match that
187 of the function being called well enough so that the back end
188 can actually generate correct code for the call. (too vague)
189
190 The called function must satisfy the following:
191
192 * no side effects -- must be a pure function
193 * it may not look at any of the guest state -- must depend
194 purely on passed parameters
195 * it may not access guest memory -- since that would
196 hide guest memory transactions from the instrumenters
197*/
sewardjc97096c2004-06-30 09:28:04 +0000198
199/* ------------------ Statements ------------------ */
200/*
sewardjec6ad592004-06-20 12:26:53 +0000201data Stmt
202 = PUT Int Int Expr -- offset, size, value
203 | TMP Temp Expr -- store value in Temp
204 | STle Expr Expr -- address (32 or 64 bit), value
sewardj64e1d652004-07-12 14:00:46 +0000205 | Exit Expr Const -- conditional exit from middle of BB
206 -- Const is destination guest addr
sewardjec6ad592004-06-20 12:26:53 +0000207*/
sewardjac6b7122004-06-27 01:03:57 +0000208typedef
sewardj64e1d652004-07-12 14:00:46 +0000209 enum { Ist_Put, Ist_Tmp, Ist_STle, Ist_Exit }
sewardjac6b7122004-06-27 01:03:57 +0000210 IRStmtTag;
211
212typedef
213 struct _IRStmt {
214 IRStmtTag tag;
215 union {
216 struct {
217 Int offset;
sewardjc97096c2004-06-30 09:28:04 +0000218 IRExpr* expr;
sewardjac6b7122004-06-27 01:03:57 +0000219 } Put;
220 struct {
221 IRTemp tmp;
sewardjc97096c2004-06-30 09:28:04 +0000222 IRExpr* expr;
sewardjac6b7122004-06-27 01:03:57 +0000223 } Tmp;
224 struct {
sewardjc97096c2004-06-30 09:28:04 +0000225 IRExpr* addr;
226 IRExpr* data;
sewardjac6b7122004-06-27 01:03:57 +0000227 } STle;
sewardj64e1d652004-07-12 14:00:46 +0000228 struct {
229 IRExpr* cond;
230 IRConst* dst;
231 } Exit;
sewardjac6b7122004-06-27 01:03:57 +0000232 } Ist;
233 struct _IRStmt* link;
234 }
235 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +0000236
sewardjeeb9ef82004-07-15 12:39:03 +0000237extern IRStmt* IRStmt_Put ( Int off, IRExpr* value );
sewardjc97096c2004-06-30 09:28:04 +0000238extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr );
239extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value );
sewardj64e1d652004-07-12 14:00:46 +0000240extern IRStmt* IRStmt_Exit ( IRExpr* cond, IRConst* dst );
sewardjec6ad592004-06-20 12:26:53 +0000241
sewardj35421a32004-07-05 13:12:34 +0000242extern void ppIRStmt ( IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +0000243
sewardje90ad6a2004-07-10 19:02:10 +0000244/* Guards in Put: if NULL, the Put is always done.
245 If non-NULL, the expr must denote a value of Ity_Bit, and
246 the Put is only done if this evaluates to 1. The expression
247 to be stored (expr) will be evaluated regardless of what
248 the guard is.
249*/
sewardjc97096c2004-06-30 09:28:04 +0000250
sewardje539a402004-07-14 18:24:17 +0000251/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +0000252
sewardje539a402004-07-14 18:24:17 +0000253/* This describes the unconditional jumps which implicitly happen at
254 the end of each basic block. Conditional jumps -- which can only
255 be done with the IRStmt_Exit statement -- are implicitly of the
256 Ijk_Boring kind. */
257
sewardj78c19df2004-07-12 22:49:27 +0000258typedef
259 enum {
sewardje8e9d732004-07-16 21:03:45 +0000260 Ijk_Boring=0x14000, /* not interesting; just goto next */
sewardj78c19df2004-07-12 22:49:27 +0000261 Ijk_Call, /* guest is doing a call */
262 Ijk_Ret, /* guest is doing a return */
263 Ijk_ClientReq, /* do guest client req before continuing */
264 Ijk_Syscall, /* do guest syscall before continuing */
265 Ijk_Yield /* client is yielding to thread scheduler */
266 }
267 IRJumpKind;
268
269extern void ppIRJumpKind ( IRJumpKind );
270
271
sewardjc97096c2004-06-30 09:28:04 +0000272/* A bunch of statements, expressions, etc, are incomplete without an
273 environment indicating the type of each IRTemp. So this provides
sewardje539a402004-07-14 18:24:17 +0000274 one. IR temporaries are really just unsigned ints and so this
275 provides an array, 0 .. n_types_used-1 of them.
sewardjc97096c2004-06-30 09:28:04 +0000276*/
277typedef
sewardjc97096c2004-06-30 09:28:04 +0000278 struct {
sewardje539a402004-07-14 18:24:17 +0000279 IRType* types;
280 Int types_size;
281 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +0000282 }
283 IRTypeEnv;
284
sewardj35421a32004-07-05 13:12:34 +0000285extern void ppIRTypeEnv ( IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +0000286
sewardjec6ad592004-06-20 12:26:53 +0000287
sewardje539a402004-07-14 18:24:17 +0000288/* Basic blocks contain 4 fields:
sewardjc97096c2004-06-30 09:28:04 +0000289 - A table giving a type for each temp
sewardjec6ad592004-06-20 12:26:53 +0000290 - A list of statements
sewardje539a402004-07-14 18:24:17 +0000291 - An expression of type 32 or 64 bits, depending on the
292 guest's word size, indicating the next destination.
sewardjec6ad592004-06-20 12:26:53 +0000293*/
sewardjac6b7122004-06-27 01:03:57 +0000294typedef
295 struct _IRBB {
sewardjc97096c2004-06-30 09:28:04 +0000296 IRTypeEnv* tyenv;
297 IRStmt* stmts;
sewardje539a402004-07-14 18:24:17 +0000298 IRExpr* next;
299 IRJumpKind jumpkind;
sewardjac6b7122004-06-27 01:03:57 +0000300 }
301 IRBB;
sewardjec6ad592004-06-20 12:26:53 +0000302
sewardje539a402004-07-14 18:24:17 +0000303extern IRBB* mkIRBB ( IRTypeEnv*, IRStmt*, IRExpr*, IRJumpKind );
sewardjc97096c2004-06-30 09:28:04 +0000304
sewardj35421a32004-07-05 13:12:34 +0000305extern void ppIRBB ( IRBB* );
sewardjc97096c2004-06-30 09:28:04 +0000306
sewardjec6ad592004-06-20 12:26:53 +0000307
308/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +0000309/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +0000310/*---------------------------------------------------------------*/
311
sewardjc97096c2004-06-30 09:28:04 +0000312/* For messing with IR type environments */
313extern IRTypeEnv* newIRTypeEnv ( void );
sewardje539a402004-07-14 18:24:17 +0000314extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
sewardjc97096c2004-06-30 09:28:04 +0000315extern IRType lookupIRTypeEnv ( IRTypeEnv*, IRTemp );
sewardjec6ad592004-06-20 12:26:53 +0000316
sewardjc97096c2004-06-30 09:28:04 +0000317/* What is the type of this expression? */
sewardj6efd4a12004-07-15 03:54:23 +0000318extern IRType typeOfIRConst ( IRConst* );
319extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +0000320
sewardj35439212004-07-14 22:36:10 +0000321/* Sanity check a BB of IR */
322extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size );
sewardjec6ad592004-06-20 12:26:53 +0000323
sewardj6d2638e2004-07-15 09:38:27 +0000324/* Is this any value actually in the enumeration 'IRType' ? */
325extern Bool isPlausibleType ( IRType ty );
326
sewardj887a11a2004-07-05 17:26:47 +0000327#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +0000328
329
330/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +0000331/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +0000332/*---------------------------------------------------------------*/