libvex_ir.h revision 6d2638e5edd8849e036f235d42a23c959e3bc3d8
1
2/*---------------------------------------------------------------*/
3/*---                                                         ---*/
4/*--- This file (libvex_ir.h) is                              ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
6/*---                                                         ---*/
7/*---------------------------------------------------------------*/
8
9#ifndef __LIBVEX_IR_H
10#define __LIBVEX_IR_H
11
12#include "libvex_basictypes.h"
13
14
15/*---------------------------------------------------------------*/
16/*--- Type definitions for the IR                             ---*/
17/*---------------------------------------------------------------*/
18
19/* ------------------ Types ------------------ */
20
21typedef
22   enum { Ity_INVALID=0x10FFF,
23          Ity_Bit=0x11000,
24          Ity_I8, Ity_I16, Ity_I32, Ity_I64 }
25   IRType;
26
27extern void ppIRType ( IRType );
28
29
30/* ------------------ Constants ------------------ */
31
32typedef
33   enum { Ico_U8, Ico_U16, Ico_U32, Ico_U64 }
34   IRConstTag;
35
36typedef
37   struct _IRConst {
38      IRConstTag tag;
39      union {
40         UChar  U8;
41         UShort U16;
42         UInt   U32;
43         ULong  U64;
44      } Ico;
45   }
46   IRConst;
47
48extern IRConst* IRConst_U8  ( UChar );
49extern IRConst* IRConst_U16 ( UShort );
50extern IRConst* IRConst_U32 ( UInt );
51extern IRConst* IRConst_U64 ( ULong );
52
53extern void ppIRConst ( IRConst* );
54
55
56/* ------------------ Temporaries ------------------ */
57
58typedef UInt IRTemp;
59
60extern void ppIRTemp ( IRTemp );
61
62#define INVALID_IRTEMP ((IRTemp)0xFFFFFFFF)
63
64
65/* ------------------ Binary and unary ops ------------------ */
66
67typedef
68   enum {
69      /* Do not change this ordering.  The IR generators
70         rely on (eg) Iop_Add64 == IopAdd8 + 3. */
71      Iop_Add8=0x12000,
72                 Iop_Add16,  Iop_Add32,  Iop_Add64,
73      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
74      Iop_Adc8,  Iop_Adc16,  Iop_Adc32,  Iop_Adc64,
75      Iop_Sbb8,  Iop_Sbb16,  Iop_Sbb32,  Iop_Sbb64,
76      /* Signless mul.  MullS/MullU is elsewhere. */
77      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
78      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
79      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
80      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
81      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
82      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
83      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
84      /* Integer comparisons. */
85      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
86      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
87      /* Tags for unary ops */
88      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
89      Iop_Neg8,  Iop_Neg16,  Iop_Neg32,  Iop_Neg64,
90      /* Widening multiplies */
91      Iop_MullS8, Iop_MullS16, Iop_MullS32,
92      Iop_MullU8, Iop_MullU16, Iop_MullU32,
93      /* Ordering not important after here. */
94      /* Division */
95      Iop_DivModU64to32, // :: I64,I32 -> I64
96                         // of which lo half is div and hi half is mod
97      Iop_DivModS64to32, // ditto, signed
98      /* Widening conversions */
99      Iop_8Uto16, Iop_8Uto32, Iop_16Uto32,
100      Iop_8Sto16, Iop_8Sto32, Iop_16Sto32,
101      /* 32 <-> 64 bit conversions */
102      Iop_64LOto32,   // :: I64 -> I32, low half
103      Iop_64HIto32,   // :: I64 -> I32, high half
104      Iop_32HLto64,   // :: (I32,I32) -> I64
105      /* 1-bit stuff */
106      Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
107      Iop_1Uto8  /* :: Ity_Bit -> Ity_I8, unsigned widen */
108   }
109   IROp;
110
111extern void ppIROp ( IROp );
112
113
114/* ------------------ Expressions ------------------ */
115/*
116data Expr
117   = GET   Int Int         -- offset, size
118   | TMP   Temp            -- value of temporary
119   | BINOP Op Expr Expr    -- binary op
120   | UNOP  Op Expr         -- unary op
121   | LDle  Type Expr       -- load of the given type, Expr:: 32 or 64
122   | CONST Const           -- 8/16/32/64-bit int constant
123*/
124typedef
125   enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle,
126          Iex_Const, Iex_CCall }
127   IRExprTag;
128
129typedef
130   struct _IRExpr {
131      IRExprTag tag;
132      union {
133         struct {
134            Int    offset;
135            IRType ty;
136         } Get;
137         struct {
138            IRTemp tmp;
139         } Tmp;
140         struct {
141            IROp op;
142            struct _IRExpr* arg1;
143            struct _IRExpr* arg2;
144         } Binop;
145         struct {
146            IROp op;
147            struct _IRExpr* arg;
148         } Unop;
149         struct {
150            IRType ty;
151            struct _IRExpr* addr;
152         } LDle;
153         struct {
154            IRConst* con;
155         } Const;
156         struct {
157            Char*  name;
158            IRType retty;
159            struct _IRExpr** args;
160         }  CCall;
161      } Iex;
162   }
163   IRExpr;
164
165extern IRExpr* IRExpr_Get   ( Int off, IRType ty );
166extern IRExpr* IRExpr_Tmp   ( IRTemp tmp );
167extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
168extern IRExpr* IRExpr_Unop  ( IROp op, IRExpr* arg );
169extern IRExpr* IRExpr_LDle  ( IRType ty, IRExpr* addr );
170extern IRExpr* IRExpr_Const ( IRConst* con );
171extern IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args );
172
173extern void ppIRExpr ( IRExpr* );
174
175/* CCall info.  The name is the C helper function; the backends
176   will look it up in a table of known helpers, to get the address.
177
178   The args are a NULL-terminated array of arguments.  The stated
179   return IRType, and the implied argument types, must match that
180   of the function being called well enough so that the back end
181   can actually generate correct code for the call.  (too vague)
182
183   The called function must satisfy the following:
184
185   * no side effects -- must be a pure function
186   * it may not look at any of the guest state -- must depend
187     purely on passed parameters
188   * it may not access guest memory -- since that would
189     hide guest memory transactions from the instrumenters
190*/
191
192/* ------------------ Statements ------------------ */
193/*
194data Stmt
195   = PUT    Int Int Expr      -- offset, size, value
196   | TMP    Temp Expr         -- store value in Temp
197   | STle   Expr Expr         -- address (32 or 64 bit), value
198   | Exit   Expr Const        -- conditional exit from middle of BB
199                              -- Const is destination guest addr
200*/
201typedef
202   enum { Ist_Put, Ist_Tmp, Ist_STle, Ist_Exit }
203   IRStmtTag;
204
205typedef
206   struct _IRStmt {
207      IRStmtTag tag;
208      union {
209         struct {
210            IRExpr* guard;
211            Int     offset;
212            IRExpr* expr;
213         } Put;
214         struct {
215            IRTemp  tmp;
216            IRExpr* expr;
217         } Tmp;
218         struct {
219            IRExpr* addr;
220            IRExpr* data;
221         } STle;
222         struct {
223            IRExpr* cond;
224            IRConst* dst;
225         } Exit;
226      } Ist;
227      struct _IRStmt* link;
228   }
229   IRStmt;
230
231extern IRStmt* IRStmt_Put  ( IRExpr* guard, Int off, IRExpr* value );
232extern IRStmt* IRStmt_Tmp  ( IRTemp tmp, IRExpr* expr );
233extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value );
234extern IRStmt* IRStmt_Exit ( IRExpr* cond, IRConst* dst );
235
236extern void ppIRStmt ( IRStmt* );
237
238/* Guards in Put: if NULL, the Put is always done.
239   If non-NULL, the expr must denote a value of Ity_Bit, and
240   the Put is only done if this evaluates to 1.  The expression
241   to be stored (expr) will be evaluated regardless of what
242   the guard is.
243*/
244
245/* ------------------ Basic Blocks ------------------ */
246
247/* This describes the unconditional jumps which implicitly happen at
248   the end of each basic block.  Conditional jumps -- which can only
249   be done with the IRStmt_Exit statement -- are implicitly of the
250   Ijk_Boring kind. */
251
252typedef
253   enum {
254      Ijk_Boring=0x13000, /* not interesting; just goto next */
255      Ijk_Call,           /* guest is doing a call */
256      Ijk_Ret,            /* guest is doing a return */
257      Ijk_ClientReq,      /* do guest client req before continuing */
258      Ijk_Syscall,        /* do guest syscall before continuing */
259      Ijk_Yield           /* client is yielding to thread scheduler */
260   }
261   IRJumpKind;
262
263extern void ppIRJumpKind ( IRJumpKind );
264
265
266/* A bunch of statements, expressions, etc, are incomplete without an
267   environment indicating the type of each IRTemp.  So this provides
268   one.  IR temporaries are really just unsigned ints and so this
269   provides an array, 0 .. n_types_used-1 of them.
270*/
271typedef
272   struct {
273      IRType* types;
274      Int     types_size;
275      Int     types_used;
276   }
277   IRTypeEnv;
278
279extern void ppIRTypeEnv ( IRTypeEnv* );
280
281
282/* Basic blocks contain 4 fields:
283   - A table giving a type for each temp
284   - A list of statements
285   - An expression of type 32 or 64 bits, depending on the
286     guest's word size, indicating the next destination.
287*/
288typedef
289   struct _IRBB {
290      IRTypeEnv* tyenv;
291      IRStmt*    stmts;
292      IRExpr*    next;
293      IRJumpKind jumpkind;
294   }
295   IRBB;
296
297extern IRBB* mkIRBB ( IRTypeEnv*, IRStmt*, IRExpr*, IRJumpKind );
298
299extern void ppIRBB ( IRBB* );
300
301
302/*---------------------------------------------------------------*/
303/*--- Helper functions for the IR                             ---*/
304/*---------------------------------------------------------------*/
305
306/* For messing with IR type environments */
307extern IRTypeEnv* newIRTypeEnv    ( void );
308extern IRTemp     newIRTemp       ( IRTypeEnv*, IRType );
309extern IRType     lookupIRTypeEnv ( IRTypeEnv*, IRTemp );
310
311/* What is the type of this expression? */
312extern IRType typeOfIRConst ( IRConst* );
313extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
314
315/* Sanity check a BB of IR */
316extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size );
317
318/* Is this any value actually in the enumeration 'IRType' ? */
319extern Bool isPlausibleType ( IRType ty );
320
321#endif /* ndef __LIBVEX_IR_H */
322
323
324/*---------------------------------------------------------------*/
325/*---                                             libvex_ir.h ---*/
326/*---------------------------------------------------------------*/
327