libvex_ir.h revision cf7879021370aabcccb1a9347244fcc7d5680141
18459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
2d90c141feb10c80581c16dbb57fcc97719a0c002vandebo@chromium.org/*---------------------------------------------------------------*/
38459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*---                                                         ---*/
48459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*--- This file (libvex_ir.h) is                              ---*/
58459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
68459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*---                                                         ---*/
78459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*---------------------------------------------------------------*/
88459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
98459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org#ifndef __LIBVEX_IR_H
108459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org#define __LIBVEX_IR_H
118459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
128459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org#include "libvex_basictypes.h"
138459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
148459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
158459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*---------------------------------------------------------------*/
168459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*--- Type definitions for the IR                             ---*/
178459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*---------------------------------------------------------------*/
188459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
198459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/* ------------------ Types ------------------ */
208459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
218459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.orgtypedef
22a09ef977b6799f01cd3fd64725fb3069da8be4bcvandebo@chromium.org   enum { Ity_INVALID=0x10FFF,
238459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ity_Bit=0x11000,
248459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ity_I8, Ity_I16, Ity_I32, Ity_I64,
258459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ity_F32, Ity_F64
268459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   }
278459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   IRType;
288459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
298459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.orgextern void ppIRType ( IRType );
308459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.orgextern Int  sizeofIRType ( IRType );
31d90c141feb10c80581c16dbb57fcc97719a0c002vandebo@chromium.org
328459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
338459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/* ------------------ Constants ------------------ */
348459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
358459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.orgtypedef
368459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   enum { Ico_Bit=0x12000,
378459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ico_U8, Ico_U16, Ico_U32, Ico_U64,
388459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ico_F64, /* 64-bit IEEE754 floating */
398459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org          Ico_F64i /* 64-bit unsigned int to be interpreted literally
408459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org                      as a IEEE754 double value. */
418459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   }
428459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   IRConstTag;
438459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
448459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.orgtypedef
458459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org   struct _IRConst {
46a09ef977b6799f01cd3fd64725fb3069da8be4bcvandebo@chromium.org      IRConstTag tag;
47a09ef977b6799f01cd3fd64725fb3069da8be4bcvandebo@chromium.org      union {
48a09ef977b6799f01cd3fd64725fb3069da8be4bcvandebo@chromium.org         Bool   Bit;
49a09ef977b6799f01cd3fd64725fb3069da8be4bcvandebo@chromium.org         UChar  U8;
50d90c141feb10c80581c16dbb57fcc97719a0c002vandebo@chromium.org         UShort U16;
51d90c141feb10c80581c16dbb57fcc97719a0c002vandebo@chromium.org         UInt   U32;
528459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org         ULong  U64;
538459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org         Double F64;
548459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org         ULong  F64i;
55      } Ico;
56   }
57   IRConst;
58
59extern IRConst* IRConst_Bit  ( Bool );
60extern IRConst* IRConst_U8   ( UChar );
61extern IRConst* IRConst_U16  ( UShort );
62extern IRConst* IRConst_U32  ( UInt );
63extern IRConst* IRConst_U64  ( ULong );
64extern IRConst* IRConst_F64  ( Double );
65extern IRConst* IRConst_F64i ( ULong );
66
67extern IRConst* dopyIRConst ( IRConst* );
68
69extern void ppIRConst ( IRConst* );
70extern Bool eqIRConst ( IRConst*, IRConst* );
71
72
73/* ------------------ Call targets ------------------ */
74
75/* Describes a helper function to call.  The name part is purely for
76   pretty printing and not actually used.  regparms=n tells the back
77   end that the callee has been declared
78   "__attribute__((regparm(n)))".  On some targets (x86) the back end
79   will need to construct a non-standard sequence to call a function
80   declared like this. */
81
82typedef
83   struct {
84      Int   regparms;
85      Char* name;
86      void* addr;
87   }
88   IRCallee;
89
90extern IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr );
91
92extern IRCallee* dopyIRCallee ( IRCallee* );
93
94extern void ppIRCallee ( IRCallee* );
95
96
97/* ------------------ Guest state arrays ------------------ */
98
99typedef
100   struct {
101      Int    base;
102      IRType elemTy;
103      Int    nElems;
104   }
105   IRArray;
106
107extern IRArray* mkIRArray ( Int, IRType, Int );
108
109extern IRArray* dopyIRArray ( IRArray* );
110
111extern void ppIRArray ( IRArray* );
112extern Bool eqIRArray ( IRArray*, IRArray* );
113
114
115/* ------------------ Temporaries ------------------ */
116
117/* The IR optimiser relies on the fact that IRTemps are 32-bit
118   ints.  Do not change them to be ints of any other size. */
119typedef UInt IRTemp;
120
121extern void ppIRTemp ( IRTemp );
122
123#define INVALID_IRTEMP ((IRTemp)0xFFFFFFFF)
124
125
126/* ------------------ Binary and unary ops ------------------ */
127
128typedef
129   enum {
130      /* Do not change this ordering.  The IR generators
131         rely on (eg) Iop_Add64 == IopAdd8 + 3. */
132      Iop_INVALID=0x13000,
133      Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
134      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
135      /* Signless mul.  MullS/MullU is elsewhere. */
136      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
137      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
138      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
139      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
140      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
141      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
142      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
143      /* Integer comparisons. */
144      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
145      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
146      /* Tags for unary ops */
147      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
148      Iop_Neg8,  Iop_Neg16,  Iop_Neg32,  Iop_Neg64,
149      /* Widening multiplies */
150      Iop_MullS8, Iop_MullS16, Iop_MullS32,
151      Iop_MullU8, Iop_MullU16, Iop_MullU32,
152
153      /* Wierdo integer stuff */
154      Iop_Clz32,   /* count leading zeroes */
155      Iop_Ctz32,   /* count trailing zeros */
156      /* Ctz32/Clz32 are UNDEFINED when given arguments of zero.
157         You must ensure they are never given a zero argument.
158      */
159
160      /* Ordering not important after here. */
161      Iop_CmpLT32S,
162      Iop_CmpLE32S,
163      Iop_CmpLT32U,
164      Iop_CmpLE32U,
165      /* Division */
166      /* TODO: clarify semantics wrt rounding, negative values, whatever */
167      Iop_DivModU64to32, // :: I64,I32 -> I64
168                         // of which lo half is div and hi half is mod
169      Iop_DivModS64to32, // ditto, signed
170
171      /* Widening conversions */
172      Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, Iop_32Uto64,
173      Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64,
174      /* Narrowing conversions */
175      Iop_32to8,
176      /* 8 <-> 16 bit conversions */
177      Iop_16to8,      // :: I16 -> I8, low half
178      Iop_16HIto8,    // :: I16 -> I8, high half
179      Iop_8HLto16,    // :: (I8,I8) -> I16
180      /* 16 <-> 32 bit conversions */
181      Iop_32to16,     // :: I32 -> I16, low half
182      Iop_32HIto16,   // :: I32 -> I16, high half
183      Iop_16HLto32,   // :: (I16,I16) -> I32
184      /* 32 <-> 64 bit conversions */
185      Iop_64to32,     // :: I64 -> I32, low half
186      Iop_64HIto32,   // :: I64 -> I32, high half
187      Iop_32HLto64,   // :: (I32,I32) -> I64
188      /* 1-bit stuff */
189      Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
190      Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
191      Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8, unsigned widen */
192      Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
193      Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
194
195      /* ------ Floating point.  We try and be IEEE754 compliant. ------ */
196
197      /* Binary operations mandated by IEEE754. */
198      Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */
199
200      /* Binary ops supported by IA32 but not mandated by 754. */
201      Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
202      Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
203      Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
204      Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
205      Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
206      Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
207      Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
208      Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
209      /* Note that on x86 guest, PRem1{C3210} has the same behaviour
210         as the IEEE mandated RemF64, except it is limited in the
211         range of its operand.  Hence the partialness. */
212
213      /* Unary operations mandated by IEEE754. */
214      Iop_NegF64, Iop_SqrtF64,
215
216      /* Unary ops supported by IA32 but not mandated by 754. */
217      Iop_AbsF64,    /* FABS */
218      Iop_SinF64,    /* FSIN */
219      Iop_CosF64,    /* FCOS */
220      Iop_TanF64,    /* FTAN */
221      Iop_2xm1F64,   /* (2^arg - 1.0) */
222
223      /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
224            0x45 Unordered
225            0x01 LT
226            0x00 GT
227            0x40 EQ
228         This just happens to be the Intel encoding.  The values
229         are recorded in the type IRCmpF64Result.
230      */
231      Iop_CmpF64,
232
233      /* int -> double */
234      Iop_I32toF64, Iop_I64toF64,
235
236      /* double -> int.  These take a first argument :: Ity_I32
237         (an IRRoundingMode) which is an indication of the rounding mode,
238         as per the following encoding:
239            00b  to nearest (the default)
240            01b  to -infinity
241            10b  to +infinity
242            11b  to zero
243         This just happens to be the Intel encoding.  For reference only,
244         the PPC encoding is:
245            00b  to nearest (the default)
246            01b  to zero
247            10b  to +infinity
248            11b  to -infinity
249         Any PPC -> IR front end will have to translate these PPC
250         encodings to the standard encodings.
251
252         If one of these conversions gets an out-of-range condition,
253         or a NaN, as an argument, the result is host-defined.  On x86
254         the "integer indefinite" value 0x80..00 is produced.
255         On PPC it is either 0x80..00 or 0x7F..FF depending on the sign
256         of the argument.
257      */
258      Iop_F64toI64, Iop_F64toI32, Iop_F64toI16,
259
260      /* F64 -> F64, also takes an I32 first argument encoding the
261         rounding mode. */
262      Iop_RoundF64,
263
264      /* double <-> float.  What does this mean -- does it round? */
265      Iop_F32toF64, Iop_F64toF32,
266
267      /* Reinterpretation.  Take an F64 and produce an I64 with
268         the same bit pattern, or vice versa. */
269      Iop_ReinterpF64asI64, Iop_ReinterpI64asF64
270   }
271   IROp;
272
273extern void ppIROp ( IROp );
274
275
276/* Encoding of IEEE754-specified rounding modes in Float -> Int
277   conversions.  This is the same as the encoding used by Intel IA32
278   to indicate x87 rounding mode. */
279typedef
280   enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 }
281   IRRoundingMode;
282
283/* Floating point comparison result values, as created by Iop_CmpF64.
284   This is also derived from what IA32 does. */
285typedef
286   enum {
287      Ircr_UN = 0x45,
288      Ircr_LT = 0x01,
289      Ircr_GT = 0x00,
290      Ircr_EQ = 0x40
291   }
292   IRCmpF64Result;
293
294
295/* ------------------ Expressions ------------------ */
296/*
297   Some details of expression semantics:
298
299   IRExpr_GetI (also IRStmt_PutI)
300   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301   This carries two ints, which give the lowest and highest possible
302   byte offsets that the GetI can possibly reference.  For example, if
303   the type is Ity_I32, and the Expr may have a value of M, M+4 or
304   M+8, where M is a translation-time known constant, then the low and
305   high limits are M and M+11 respectively.
306
307   PutI's limit values are interpreted identically.
308
309   The limit values are used by IR optimisers to establish
310   aliasing/non-aliasing between seperate GetI and PutI events, which
311   could be used to do reordering of them, or suchlike things.
312   Clearly it's critical to give the correct limit values -- this is
313   something that can't be automatically checked (in general), and so
314   the front-end writers must be very careful to tell the truth, since
315   not doing so could lead to obscure IR optimisation bugs.
316
317   IRExpr_CCall
318   ~~~~~~~~~~~~
319   The name is the C helper function; the backends will call back to
320   the front ends to get the address of a host-code helper function to
321   be called.
322
323   The args are a NULL-terminated array of arguments.  The stated
324   return IRType, and the implied argument types, must match that of
325   the function being called well enough so that the back end can
326   actually generate correct code for the call.
327
328   The called function **must** satisfy the following:
329
330   * no side effects -- must be a pure function, the result of which
331     depends only on the passed parameters.
332
333   * it may not look at, nor modify, any of the guest state since that
334     would hide guest state transitions from instrumenters
335
336   * it may not access guest memory, since that would hide guest
337     memory transactions from the instrumenters
338
339   This is restrictive, but makes the semantics clean, and does
340   not interfere with IR optimisation.
341
342   If you want to call a helper which can mess with guest state and/or
343   memory, instead use IRStmt_Dirty.  This is a lot more flexible, but
344   you pay for that flexibility in that you have to give a bunch of
345   details about what the helper does (and you better be telling the
346   truth, otherwise any derived instrumentation will be wrong).  Also
347   IRStmt_Dirty inhibits various IR optimisations and so can cause
348   quite poor code to be generated.  Try to avoid it.
349*/
350
351/* The possible kinds of expressions are as follows: */
352typedef
353   enum {
354      Iex_Binder,  /* Used only in pattern matching.
355                      Not an expression. */
356      Iex_Get,     /* read guest state, fixed offset */
357      Iex_GetI,    /* read guest state, run-time offset */
358      Iex_Tmp,     /* value of temporary */
359      Iex_Binop,   /* binary operation */
360      Iex_Unop,    /* unary operation */
361      Iex_LDle,    /* little-endian read from memory */
362      Iex_Const,   /* constant-valued expression */
363      Iex_Mux0X,   /* ternary if-then-else operator (STRICT) */
364      Iex_CCall    /* call to pure (side-effect-free) helper fn */
365   }
366   IRExprTag;
367
368typedef
369   struct _IRExpr {
370      IRExprTag tag;
371      union {
372	 struct {
373            Int binder;
374         } Binder;
375         struct {
376            Int    offset;
377            IRType ty;
378         } Get;
379         struct {
380            IRArray* descr;
381            struct _IRExpr* ix;
382            Int bias;
383         } GetI;
384         struct {
385            IRTemp tmp;
386         } Tmp;
387         struct {
388            IROp op;
389            struct _IRExpr* arg1;
390            struct _IRExpr* arg2;
391         } Binop;
392         struct {
393            IROp op;
394            struct _IRExpr* arg;
395         } Unop;
396         struct {
397            IRType ty;
398            struct _IRExpr* addr;
399         } LDle;
400         struct {
401            IRConst* con;
402         } Const;
403         struct {
404            IRCallee* cee;
405            IRType    retty;
406            struct _IRExpr** args;
407         }  CCall;
408         struct {
409            struct _IRExpr* cond;
410            struct _IRExpr* expr0;
411            struct _IRExpr* exprX;
412         } Mux0X;
413      } Iex;
414   }
415   IRExpr;
416
417extern IRExpr* IRExpr_Binder ( Int binder );
418extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
419extern IRExpr* IRExpr_GetI   ( IRArray* descr, IRExpr* ix, Int bias );
420extern IRExpr* IRExpr_Tmp    ( IRTemp tmp );
421extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
422extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
423extern IRExpr* IRExpr_LDle   ( IRType ty, IRExpr* addr );
424extern IRExpr* IRExpr_Const  ( IRConst* con );
425extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
426extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
427
428extern IRExpr* dopyIRExpr ( IRExpr* );
429
430extern void ppIRExpr ( IRExpr* );
431
432/* NULL-terminated IRExpr expression vectors, suitable for use as arg
433   lists in clean/dirty helper calls. */
434
435extern IRExpr** mkIRExprVec_0 ( void );
436extern IRExpr** mkIRExprVec_1 ( IRExpr* );
437extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
438extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
439extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
440
441extern IRExpr** sopyIRExprVec ( IRExpr** );
442extern IRExpr** dopyIRExprVec ( IRExpr** );
443
444/* Make a constant expression from the given host word taking into
445   account of course the host word size. */
446extern IRExpr* mkIRExpr_HWord ( HWord );
447
448/* Convenience function for constructing clean helper calls. */
449extern
450IRExpr* mkIRExprCCall ( IRType retty,
451                        Int regparms, Char* name, void* addr,
452                        IRExpr** args );
453
454
455inline static Bool isAtom ( IRExpr* e ) {
456   return e->tag == Iex_Tmp || e->tag == Iex_Const;
457}
458
459
460/* ------------------ Dirty helper calls ------------------ */
461
462/* A dirty call is a flexible mechanism for calling a helper function
463   or procedure.  The helper function may read, write or modify client
464   memory, and may read, write or modify client state.  It can take
465   arguments and optionally return a value.  It may return different
466   results and/or do different things when called repeated with the
467   same arguments, by means of storing private state.
468
469   If a value is returned, it is assigned to the nominated return
470   temporary.
471
472   Dirty calls are statements rather than expressions for obvious
473   reasons.  If a dirty call is stated as writing guest state, any
474   values derived from the written parts of the guest state are
475   invalid.  Similarly, if the dirty call is stated as writing
476   memory, any loaded values are invalidated by it.
477
478   In order that instrumentation is possible, the call must state, and
479   state correctly
480
481   * whether it reads, writes or modifies memory, and if so where
482     (only one chunk can be stated)
483
484   * whether it reads, writes or modifies guest state, and if so which
485     pieces (several pieces may be stated, and currently their extents
486     must be known at translation-time).
487
488   Normally, code is generated to pass just the args to the helper.
489   However, if .needsBBP is set, then an extra first argument is
490   passed, which is the baseblock pointer, so that the callee can
491   access the guest state.  It is invalid for .nFxState to be zero
492   but .needsBBP to be True, since .nFxState==0 is a claim that the
493   call does not access guest state.
494
495   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
496   arguments are evaluated REGARDLESS of the guard value.  It is
497   unspecified the relative order of arg evaluation and guard
498   evaluation.
499*/
500
501#define VEX_N_FXSTATE  4   /* enough for CPUID on x86 */
502
503typedef
504   enum {
505      Ifx_None = 0x15000,   /* no effect */
506      Ifx_Read,             /* reads the resource */
507      Ifx_Write,            /* writes the resource */
508      Ifx_Modify,           /* modifies the resource */
509   }
510   IREffect;
511
512extern void ppIREffect ( IREffect );
513
514
515typedef
516   struct {
517      /* What to call, and details of args/results */
518      IRCallee* cee;    /* where to call */
519      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
520      IRExpr**  args;   /* arg list, ends in NULL */
521      IRTemp    tmp;    /* to assign result to, or INVALID_IRTEMP if none */
522
523      /* Mem effects; we allow only one R/W/M region to be stated */
524      IREffect  mFx;    /* indicates memory effects, if any */
525      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
526      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
527
528      /* Guest state effects; up to N allowed */
529      Bool needsBBP; /* True => also pass guest state ptr to callee */
530      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
531      struct {
532         IREffect fx;   /* read, write or modify? */
533         Int      offset;
534         Int      size;
535      } fxState[VEX_N_FXSTATE];
536   }
537   IRDirty;
538
539extern void     ppIRDirty ( IRDirty* );
540extern IRDirty* emptyIRDirty ( void );
541
542extern IRDirty* dopyIRDirty ( IRDirty* );
543
544/* A handy function which takes some of the tedium out of constructing
545   dirty helper calls.  The called function impliedly does not return
546   any value and has a constant-True guard.  The call is marked as
547   accessing neither guest state nor memory (hence the "unsafe"
548   designation) -- you can mess with this later if need be.  A
549   suitable IRCallee is constructed from the supplied bits. */
550extern
551IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr,
552                             IRExpr** args );
553
554/* Similarly, make a zero-annotation dirty call which returns a value,
555   and assign that to the given temp. */
556extern
557IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
558                             Int regparms, Char* name, void* addr,
559                             IRExpr** args );
560
561
562/* ------------------ Statements ------------------ */
563
564/* The possible kinds of statements are as follows: */
565typedef
566   enum {
567      Ist_Put,    /* write guest state, fixed offset */
568      Ist_PutI,   /* write guest state, run-time offset */
569      Ist_Tmp,    /* assign value to temporary */
570      Ist_STle,   /* little-endian write to memory */
571      Ist_Dirty,  /* call complex ("dirty") helper function */
572      Ist_Exit    /* conditional exit from BB */
573   }
574   IRStmtTag;
575
576typedef
577   struct _IRStmt {
578      IRStmtTag tag;
579      union {
580         struct {
581            Int     offset;
582            IRExpr* data;
583         } Put;
584         struct {
585            IRArray* descr;
586            IRExpr*  ix;
587            Int      bias;
588            IRExpr*  data;
589         } PutI;
590         struct {
591            IRTemp  tmp;
592            IRExpr* data;
593         } Tmp;
594         struct {
595            IRExpr* addr;
596            IRExpr* data;
597         } STle;
598         struct {
599            IRDirty* details;
600         } Dirty;
601         struct {
602            IRExpr*  cond;
603            IRConst* dst;
604         } Exit;
605      } Ist;
606   }
607   IRStmt;
608
609extern IRStmt* IRStmt_Put   ( Int off, IRExpr* data );
610extern IRStmt* IRStmt_PutI  ( IRArray* descr, IRExpr* ix, Int bias,
611                              IRExpr* data );
612extern IRStmt* IRStmt_Tmp   ( IRTemp tmp, IRExpr* data );
613extern IRStmt* IRStmt_STle  ( IRExpr* addr, IRExpr* data );
614extern IRStmt* IRStmt_Dirty ( IRDirty* details );
615extern IRStmt* IRStmt_Exit  ( IRExpr* cond, IRConst* dst );
616
617extern IRStmt* dopyIRStmt ( IRStmt* );
618
619extern void ppIRStmt ( IRStmt* );
620
621
622/* ------------------ Basic Blocks ------------------ */
623
624/* This describes the unconditional jumps which implicitly happen at
625   the end of each basic block.  Conditional jumps -- which can only
626   be done with the IRStmt_Exit statement -- are implicitly of the
627   Ijk_Boring kind. */
628
629typedef
630   enum {
631      Ijk_Boring=0x14000, /* not interesting; just goto next */
632      Ijk_Call,           /* guest is doing a call */
633      Ijk_Ret,            /* guest is doing a return */
634      Ijk_ClientReq,      /* do guest client req before continuing */
635      Ijk_Syscall,        /* do guest syscall before continuing */
636      Ijk_Yield           /* client is yielding to thread scheduler */
637   }
638   IRJumpKind;
639
640extern void ppIRJumpKind ( IRJumpKind );
641
642
643/* A bunch of statements, expressions, etc, are incomplete without an
644   environment indicating the type of each IRTemp.  So this provides
645   one.  IR temporaries are really just unsigned ints and so this
646   provides an array, 0 .. n_types_used-1 of them.
647*/
648typedef
649   struct {
650      IRType* types;
651      Int     types_size;
652      Int     types_used;
653   }
654   IRTypeEnv;
655
656extern IRTemp     newIRTemp     ( IRTypeEnv*, IRType );
657extern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* );
658
659extern void ppIRTypeEnv ( IRTypeEnv* );
660
661
662/* Basic blocks contain:
663   - A table giving a type for each temp
664   - An expandable array of statements
665   - An expression of type 32 or 64 bits, depending on the
666     guest's word size, indicating the next destination.
667   - An indication of any special actions (JumpKind) needed
668     for this final jump.
669*/
670typedef
671   struct _IRBB {
672      IRTypeEnv* tyenv;
673      IRStmt**   stmts;
674      Int        stmts_size;
675      Int        stmts_used;
676      IRExpr*    next;
677      IRJumpKind jumpkind;
678   }
679   IRBB;
680
681extern IRBB* emptyIRBB ( void );
682
683extern IRBB* dopyIRBB ( IRBB* );
684
685extern void ppIRBB ( IRBB* );
686
687extern void  addStmtToIRBB ( IRBB*, IRStmt* );
688
689
690/*---------------------------------------------------------------*/
691/*--- Helper functions for the IR                             ---*/
692/*---------------------------------------------------------------*/
693
694/* For messing with IR type environments */
695extern IRTypeEnv* emptyIRTypeEnv  ( void );
696
697/* What is the type of this expression? */
698extern IRType typeOfIRConst ( IRConst* );
699extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
700extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
701
702/* Sanity check a BB of IR */
703extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size );
704extern Bool isFlatIRStmt ( IRStmt* );
705
706/* Is this any value actually in the enumeration 'IRType' ? */
707extern Bool isPlausibleType ( IRType ty );
708
709#endif /* ndef __LIBVEX_IR_H */
710
711
712/*---------------------------------------------------------------*/
713/*---                                             libvex_ir.h ---*/
714/*---------------------------------------------------------------*/
715