blob: cf4b58439178e4ddabdc8ad26e89ee80903fd432 [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,
sewardjd1725d12004-08-12 20:46:53 +000024 Ity_I8, Ity_I16, Ity_I32, Ity_I64,
25 Ity_F32, Ity_F64
26 }
sewardje3d0d2e2004-06-27 10:42:44 +000027 IRType;
28
sewardj35421a32004-07-05 13:12:34 +000029extern void ppIRType ( IRType );
sewardje3d0d2e2004-06-27 10:42:44 +000030
sewardjc97096c2004-06-30 09:28:04 +000031
32/* ------------------ Constants ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000033
sewardjac6b7122004-06-27 01:03:57 +000034typedef
sewardj51cba892004-08-20 00:09:03 +000035 enum { Ico_Bit=0x12000,
sewardj207557a2004-08-27 12:00:18 +000036 Ico_U8, Ico_U16, Ico_U32, Ico_U64, Ico_F64,
37 Ico_NaN64 /* 64-bit IEEE NaN. */
38 }
sewardjac6b7122004-06-27 01:03:57 +000039 IRConstTag;
40
41typedef
sewardje3d0d2e2004-06-27 10:42:44 +000042 struct _IRConst {
sewardjac6b7122004-06-27 01:03:57 +000043 IRConstTag tag;
44 union {
sewardj51cba892004-08-20 00:09:03 +000045 Bool Bit;
sewardjc97096c2004-06-30 09:28:04 +000046 UChar U8;
47 UShort U16;
48 UInt U32;
49 ULong U64;
sewardja58ea662004-08-15 03:12:41 +000050 Double F64;
sewardjac6b7122004-06-27 01:03:57 +000051 } Ico;
52 }
53 IRConst;
sewardjec6ad592004-06-20 12:26:53 +000054
sewardj207557a2004-08-27 12:00:18 +000055extern IRConst* IRConst_Bit ( Bool );
56extern IRConst* IRConst_U8 ( UChar );
57extern IRConst* IRConst_U16 ( UShort );
58extern IRConst* IRConst_U32 ( UInt );
59extern IRConst* IRConst_U64 ( ULong );
60extern IRConst* IRConst_F64 ( Double );
61extern IRConst* IRConst_NaN64 ( void );
sewardjec6ad592004-06-20 12:26:53 +000062
sewardj35421a32004-07-05 13:12:34 +000063extern void ppIRConst ( IRConst* );
sewardjc97096c2004-06-30 09:28:04 +000064
65
66/* ------------------ Temporaries ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000067
sewardjfbcaf332004-07-08 01:46:01 +000068typedef UInt IRTemp;
sewardjec6ad592004-06-20 12:26:53 +000069
sewardj35421a32004-07-05 13:12:34 +000070extern void ppIRTemp ( IRTemp );
sewardjec6ad592004-06-20 12:26:53 +000071
sewardjfbcaf332004-07-08 01:46:01 +000072#define INVALID_IRTEMP ((IRTemp)0xFFFFFFFF)
73
sewardjc97096c2004-06-30 09:28:04 +000074
75/* ------------------ Binary and unary ops ------------------ */
sewardjec6ad592004-06-20 12:26:53 +000076
sewardj8f3debf2004-09-08 23:42:23 +000077/* Encoding of rounding modes in Float -> Int conversions. This is
78 the same as the encoding used by Intel IA32 to indicate x87
79 rounding mode. */
80typedef
81 enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 }
82 IRRoundingMode;
83
84/* Floating point comparison result values, as created by Iop_CmpF64.
85 This is also derived from what IA32 does. */
86typedef
87 enum {
88 Ircr_UN = 0x85,
89 Ircr_LT = 0x01,
90 Ircr_GT = 0x00,
91 Ircr_EQ = 0x80
92 }
93 IRCmpF64Result;
94
95
sewardjac6b7122004-06-27 01:03:57 +000096typedef
sewardj41f43bc2004-07-08 14:23:22 +000097 enum {
98 /* Do not change this ordering. The IR generators
99 rely on (eg) Iop_Add64 == IopAdd8 + 3. */
sewardj66de2272004-07-16 21:19:05 +0000100 Iop_INVALID=0x13000,
101 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
sewardj41f43bc2004-07-08 14:23:22 +0000102 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
sewardj41f43bc2004-07-08 14:23:22 +0000103 /* Signless mul. MullS/MullU is elsewhere. */
104 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
105 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
106 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
107 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
108 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
109 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
110 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
sewardje90ad6a2004-07-10 19:02:10 +0000111 /* Integer comparisons. */
112 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
113 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
sewardj41f43bc2004-07-08 14:23:22 +0000114 /* Tags for unary ops */
115 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
sewardje87b4842004-07-10 12:23:30 +0000116 Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64,
sewardj9690d922004-07-14 01:39:17 +0000117 /* Widening multiplies */
118 Iop_MullS8, Iop_MullS16, Iop_MullS32,
119 Iop_MullU8, Iop_MullU16, Iop_MullU32,
sewardj8f3debf2004-09-08 23:42:23 +0000120
sewardjce646f22004-08-31 23:55:54 +0000121 /* Wierdo integer stuff */
122 Iop_Clz32, /* count leading zeroes */
123 Iop_Ctz32, /* count trailing zeros */
sewardj8f3debf2004-09-08 23:42:23 +0000124 /* Ctz32/Clz32 are UNDEFINED when given arguments of zero.
125 You must ensure they are never given a zero argument.
126 */
127
sewardj9690d922004-07-14 01:39:17 +0000128 /* Ordering not important after here. */
sewardj84ff0652004-08-23 16:16:08 +0000129 Iop_CmpLT32S,
130 Iop_CmpLE32S,
131 Iop_CmpLT32U,
132 Iop_CmpLE32U,
sewardj9690d922004-07-14 01:39:17 +0000133 /* Division */
sewardj8f3debf2004-09-08 23:42:23 +0000134 /* TODO: clarify semantics wrt rounding, negative values, whatever */
sewardj9690d922004-07-14 01:39:17 +0000135 Iop_DivModU64to32, // :: I64,I32 -> I64
136 // of which lo half is div and hi half is mod
137 Iop_DivModS64to32, // ditto, signed
138 /* Widening conversions */
sewardje5427e82004-09-11 19:43:51 +0000139 Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, Iop_32Uto64,
sewardjbb53f8c2004-08-14 11:50:01 +0000140 Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64,
sewardja2384712004-07-29 14:36:40 +0000141 /* Narrowing conversions */
sewardj8c7f1ab2004-07-29 20:31:09 +0000142 Iop_32to8,
sewardjb81f8b32004-07-30 10:17:50 +0000143 /* 8 <-> 16 bit conversions */
144 Iop_16to8, // :: I16 -> I8, low half
145 Iop_16HIto8, // :: I16 -> I8, high half
146 Iop_8HLto16, // :: (I8,I8) -> I16
sewardj8c7f1ab2004-07-29 20:31:09 +0000147 /* 16 <-> 32 bit conversions */
148 Iop_32to16, // :: I32 -> I16, low half
149 Iop_32HIto16, // :: I32 -> I16, high half
150 Iop_16HLto32, // :: (I16,I16) -> I32
sewardj9690d922004-07-14 01:39:17 +0000151 /* 32 <-> 64 bit conversions */
sewardj8c7f1ab2004-07-29 20:31:09 +0000152 Iop_64to32, // :: I64 -> I32, low half
sewardj9690d922004-07-14 01:39:17 +0000153 Iop_64HIto32, // :: I64 -> I32, high half
154 Iop_32HLto64, // :: (I32,I32) -> I64
sewardjcf780b42004-07-13 18:42:17 +0000155 /* 1-bit stuff */
sewardj84ff0652004-08-23 16:16:08 +0000156 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
157 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
158 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
sewardj8f3debf2004-09-08 23:42:23 +0000159
160 /* ------ Floating point. We try and be IEEE754 compliant. ------ */
161
sewardj52ace3e2004-09-11 17:10:08 +0000162 /* Binary operations mandated by IEEE754. */
sewardj46de4072004-09-11 19:23:24 +0000163 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */
sewardjcfded9a2004-09-09 11:44:16 +0000164
sewardj52ace3e2004-09-11 17:10:08 +0000165 /* Binary ops supported by IA32 but not mandated by 754. */
sewardj46de4072004-09-11 19:23:24 +0000166 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
167 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
sewardj8308aad2004-09-12 11:09:54 +0000168 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
sewardj46de4072004-09-11 19:23:24 +0000169 Iop_PRemF64, /* FPREM, remainder(arg1/arg2) */
170 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
sewardj06c32a02004-09-12 12:07:34 +0000171 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
sewardj52ace3e2004-09-11 17:10:08 +0000172
173 /* Unary operations mandated by IEEE754. */
174 Iop_NegF64, Iop_SqrtF64,
175
176 /* Unary ops supported by IA32 but not mandated by 754. */
177 Iop_AbsF64, /* FABS */
178 Iop_SinF64, /* FSIN */
179 Iop_CosF64, /* FCOS */
sewardj06c32a02004-09-12 12:07:34 +0000180 Iop_2xm1F64, /* (2^arg - 1.0) */
sewardj8f3debf2004-09-08 23:42:23 +0000181
182 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
sewardj883b00b2004-09-11 09:30:24 +0000183 0x45 Unordered
sewardj8f3debf2004-09-08 23:42:23 +0000184 0x01 LT
185 0x00 GT
sewardj883b00b2004-09-11 09:30:24 +0000186 0x40 EQ
sewardj8f3debf2004-09-08 23:42:23 +0000187 This just happens to be the Intel encoding. The values
188 are recorded in the type IRCmpF64Result.
189 */
190 Iop_CmpF64,
191
192 /* int -> double */
193 Iop_I32toF64, Iop_I64toF64,
194
195 /* double -> int. These take a first argument :: Ity_I32
196 (an IRRoundingMode) which is an indication of the rounding mode,
197 as per the following encoding:
198 00b to nearest (the default)
199 01b to -infinity
200 10b to +infinity
201 11b to zero
202 This just happens to be the Intel encoding. For reference only,
203 the PPC encoding is:
204 00b to nearest (the default)
205 01b to zero
206 10b to +infinity
207 11b to -infinity
208 Any PPC -> IR front end will have to translate these PPC
209 encodings to the standard encodings.
210
211 If one of these conversions gets an out-of-range condition,
212 or a NaN, as an argument, the result is host-defined. On x86
213 the "integer indefinite" value 0x80..00 is produced.
214 On PPC it is either 0x80..00 or 0x7F..FF depending on the sign
215 of the argument.
216 */
217 Iop_F64toI64, Iop_F64toI32, Iop_F64toI16,
sewardj52ace3e2004-09-11 17:10:08 +0000218
sewardje6709112004-09-10 18:37:18 +0000219 /* F64 -> F64, also takes an I32 first argument encoding the
220 rounding mode. */
221 Iop_RoundF64,
sewardj8f3debf2004-09-08 23:42:23 +0000222
223 /* double <-> float. What does this mean -- does it round? */
sewardj89cd0932004-09-08 18:23:25 +0000224 Iop_F32toF64, Iop_F64toF32
sewardjac6b7122004-06-27 01:03:57 +0000225 }
226 IROp;
sewardjec6ad592004-06-20 12:26:53 +0000227
sewardjce646f22004-08-31 23:55:54 +0000228
sewardj35421a32004-07-05 13:12:34 +0000229extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +0000230
sewardje3d0d2e2004-06-27 10:42:44 +0000231
sewardjc97096c2004-06-30 09:28:04 +0000232/* ------------------ Expressions ------------------ */
233/*
sewardje3d0d2e2004-06-27 10:42:44 +0000234data Expr
sewardjd1725d12004-08-12 20:46:53 +0000235 = GET Int Type -- offset, size
236 | GETI Expr Type Int Int -- offset, size, minoff, maxoff
sewardje3d0d2e2004-06-27 10:42:44 +0000237 | TMP Temp -- value of temporary
238 | BINOP Op Expr Expr -- binary op
239 | UNOP Op Expr -- unary op
240 | LDle Type Expr -- load of the given type, Expr:: 32 or 64
241 | CONST Const -- 8/16/32/64-bit int constant
sewardjd1725d12004-08-12 20:46:53 +0000242
243Re GETI. It carries two ints, which give the lowest and highest
244possible byte offsets that the GetI can possibly reference.
245For example, if the type is Ity_I32, and the Expr may have
246a value of M, M+4 or M+8, where M is a translation-time known
247constant, then the low and high limits are M and M+11 respectively.
248
249PUTI carries similar limit values.
250
251These can be used by IR optimisers to establish aliasing/non-aliasing
252between seperate GETI and PUTI terms, which could be used to do
253reordering of them, or suchlike things. Clearly it's critical to give
254the correct limit values -- this is something that can't be
255automatically checked (in general), and so the front-end writers must
256be very careful to tell the truth, since not doing so could lead to
257obscure IR optimisation bugs.
sewardje3d0d2e2004-06-27 10:42:44 +0000258*/
sewardjd1725d12004-08-12 20:46:53 +0000259
sewardje3d0d2e2004-06-27 10:42:44 +0000260typedef
sewardje6709112004-09-10 18:37:18 +0000261 enum { Iex_Binder, /* Used only in pattern matching.
262 Not an expression. */
sewardjd1725d12004-08-12 20:46:53 +0000263 Iex_Get, Iex_GetI, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle,
sewardj4042c7e2004-07-18 01:28:30 +0000264 Iex_Const, Iex_CCall, Iex_Mux0X }
sewardje3d0d2e2004-06-27 10:42:44 +0000265 IRExprTag;
266
267typedef
268 struct _IRExpr {
269 IRExprTag tag;
270 union {
sewardj443cd9d2004-07-18 23:06:45 +0000271 struct {
272 Int binder;
273 } Binder;
sewardje3d0d2e2004-06-27 10:42:44 +0000274 struct {
sewardjfbcaf332004-07-08 01:46:01 +0000275 Int offset;
276 IRType ty;
sewardje3d0d2e2004-06-27 10:42:44 +0000277 } Get;
278 struct {
sewardjd1725d12004-08-12 20:46:53 +0000279 struct _IRExpr* offset;
280 IRType ty;
281 UShort minoff;
282 UShort maxoff;
283 } GetI;
284 struct {
sewardje3d0d2e2004-06-27 10:42:44 +0000285 IRTemp tmp;
286 } Tmp;
287 struct {
288 IROp op;
289 struct _IRExpr* arg1;
290 struct _IRExpr* arg2;
291 } Binop;
292 struct {
293 IROp op;
294 struct _IRExpr* arg;
295 } Unop;
296 struct {
297 IRType ty;
298 struct _IRExpr* addr;
299 } LDle;
300 struct {
sewardj66f2f792004-06-30 16:37:16 +0000301 IRConst* con;
sewardje3d0d2e2004-06-27 10:42:44 +0000302 } Const;
sewardje87b4842004-07-10 12:23:30 +0000303 struct {
304 Char* name;
305 IRType retty;
306 struct _IRExpr** args;
307 } CCall;
sewardjeeb9ef82004-07-15 12:39:03 +0000308 struct {
309 struct _IRExpr* cond;
sewardjeeb9ef82004-07-15 12:39:03 +0000310 struct _IRExpr* expr0;
sewardj4042c7e2004-07-18 01:28:30 +0000311 struct _IRExpr* exprX;
312 } Mux0X;
sewardje3d0d2e2004-06-27 10:42:44 +0000313 } Iex;
314 }
315 IRExpr;
316
sewardj443cd9d2004-07-18 23:06:45 +0000317extern IRExpr* IRExpr_Binder ( Int binder );
318extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjd1725d12004-08-12 20:46:53 +0000319extern IRExpr* IRExpr_GetI ( IRExpr* off, IRType ty,
320 UShort minoff, UShort maxoff );
sewardj443cd9d2004-07-18 23:06:45 +0000321extern IRExpr* IRExpr_Tmp ( IRTemp tmp );
322extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
323extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
324extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr );
325extern IRExpr* IRExpr_Const ( IRConst* con );
326extern IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args );
327extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
sewardje3d0d2e2004-06-27 10:42:44 +0000328
sewardj35421a32004-07-05 13:12:34 +0000329extern void ppIRExpr ( IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +0000330
sewardje87b4842004-07-10 12:23:30 +0000331/* CCall info. The name is the C helper function; the backends
sewardjd1725d12004-08-12 20:46:53 +0000332 will hand the name to the front ends to get the address of a
333 host-code helper function to be called.
sewardje87b4842004-07-10 12:23:30 +0000334
335 The args are a NULL-terminated array of arguments. The stated
336 return IRType, and the implied argument types, must match that
337 of the function being called well enough so that the back end
338 can actually generate correct code for the call. (too vague)
339
340 The called function must satisfy the following:
341
342 * no side effects -- must be a pure function
343 * it may not look at any of the guest state -- must depend
344 purely on passed parameters
345 * it may not access guest memory -- since that would
346 hide guest memory transactions from the instrumenters
347*/
sewardjc97096c2004-06-30 09:28:04 +0000348
349/* ------------------ Statements ------------------ */
350/*
sewardjec6ad592004-06-20 12:26:53 +0000351data Stmt
352 = PUT Int Int Expr -- offset, size, value
353 | TMP Temp Expr -- store value in Temp
354 | STle Expr Expr -- address (32 or 64 bit), value
sewardj64e1d652004-07-12 14:00:46 +0000355 | Exit Expr Const -- conditional exit from middle of BB
356 -- Const is destination guest addr
sewardjec6ad592004-06-20 12:26:53 +0000357*/
sewardjac6b7122004-06-27 01:03:57 +0000358typedef
sewardjd1725d12004-08-12 20:46:53 +0000359 enum { Ist_Put, Ist_PutI, Ist_Tmp, Ist_STle, Ist_Exit }
sewardjac6b7122004-06-27 01:03:57 +0000360 IRStmtTag;
361
362typedef
363 struct _IRStmt {
364 IRStmtTag tag;
365 union {
366 struct {
367 Int offset;
sewardjc97096c2004-06-30 09:28:04 +0000368 IRExpr* expr;
sewardjac6b7122004-06-27 01:03:57 +0000369 } Put;
370 struct {
sewardjd1725d12004-08-12 20:46:53 +0000371 IRExpr* offset;
372 IRExpr* expr;
373 UShort minoff;
374 UShort maxoff;
375 } PutI;
376 struct {
sewardjac6b7122004-06-27 01:03:57 +0000377 IRTemp tmp;
sewardjc97096c2004-06-30 09:28:04 +0000378 IRExpr* expr;
sewardjac6b7122004-06-27 01:03:57 +0000379 } Tmp;
380 struct {
sewardjc97096c2004-06-30 09:28:04 +0000381 IRExpr* addr;
382 IRExpr* data;
sewardjac6b7122004-06-27 01:03:57 +0000383 } STle;
sewardj64e1d652004-07-12 14:00:46 +0000384 struct {
sewardj443cd9d2004-07-18 23:06:45 +0000385 IRExpr* cond;
sewardj64e1d652004-07-12 14:00:46 +0000386 IRConst* dst;
387 } Exit;
sewardjac6b7122004-06-27 01:03:57 +0000388 } Ist;
sewardjac6b7122004-06-27 01:03:57 +0000389 }
390 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +0000391
sewardjeeb9ef82004-07-15 12:39:03 +0000392extern IRStmt* IRStmt_Put ( Int off, IRExpr* value );
sewardjd1725d12004-08-12 20:46:53 +0000393extern IRStmt* IRStmt_PutI ( IRExpr* off, IRExpr* value,
394 UShort minoff, UShort maxoff );
sewardjc97096c2004-06-30 09:28:04 +0000395extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr );
396extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value );
sewardj64e1d652004-07-12 14:00:46 +0000397extern IRStmt* IRStmt_Exit ( IRExpr* cond, IRConst* dst );
sewardjec6ad592004-06-20 12:26:53 +0000398
sewardj35421a32004-07-05 13:12:34 +0000399extern void ppIRStmt ( IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +0000400
sewardje90ad6a2004-07-10 19:02:10 +0000401/* Guards in Put: if NULL, the Put is always done.
402 If non-NULL, the expr must denote a value of Ity_Bit, and
403 the Put is only done if this evaluates to 1. The expression
404 to be stored (expr) will be evaluated regardless of what
405 the guard is.
406*/
sewardjc97096c2004-06-30 09:28:04 +0000407
sewardje539a402004-07-14 18:24:17 +0000408/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +0000409
sewardje539a402004-07-14 18:24:17 +0000410/* This describes the unconditional jumps which implicitly happen at
411 the end of each basic block. Conditional jumps -- which can only
412 be done with the IRStmt_Exit statement -- are implicitly of the
413 Ijk_Boring kind. */
414
sewardj78c19df2004-07-12 22:49:27 +0000415typedef
416 enum {
sewardje8e9d732004-07-16 21:03:45 +0000417 Ijk_Boring=0x14000, /* not interesting; just goto next */
sewardj78c19df2004-07-12 22:49:27 +0000418 Ijk_Call, /* guest is doing a call */
419 Ijk_Ret, /* guest is doing a return */
420 Ijk_ClientReq, /* do guest client req before continuing */
421 Ijk_Syscall, /* do guest syscall before continuing */
422 Ijk_Yield /* client is yielding to thread scheduler */
423 }
424 IRJumpKind;
425
426extern void ppIRJumpKind ( IRJumpKind );
427
428
sewardjc97096c2004-06-30 09:28:04 +0000429/* A bunch of statements, expressions, etc, are incomplete without an
430 environment indicating the type of each IRTemp. So this provides
sewardje539a402004-07-14 18:24:17 +0000431 one. IR temporaries are really just unsigned ints and so this
432 provides an array, 0 .. n_types_used-1 of them.
sewardjc97096c2004-06-30 09:28:04 +0000433*/
434typedef
sewardjc97096c2004-06-30 09:28:04 +0000435 struct {
sewardje539a402004-07-14 18:24:17 +0000436 IRType* types;
437 Int types_size;
438 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +0000439 }
440 IRTypeEnv;
441
sewardj35421a32004-07-05 13:12:34 +0000442extern void ppIRTypeEnv ( IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +0000443
sewardjec6ad592004-06-20 12:26:53 +0000444
sewardjd7cb8532004-08-17 23:59:23 +0000445/* Basic blocks contain:
sewardjc97096c2004-06-30 09:28:04 +0000446 - A table giving a type for each temp
sewardjd7cb8532004-08-17 23:59:23 +0000447 - An expandable array of statements
sewardje539a402004-07-14 18:24:17 +0000448 - An expression of type 32 or 64 bits, depending on the
449 guest's word size, indicating the next destination.
sewardjd7cb8532004-08-17 23:59:23 +0000450 - An indication of any special actions (JumpKind) needed
451 for this final jump.
sewardjec6ad592004-06-20 12:26:53 +0000452*/
sewardjac6b7122004-06-27 01:03:57 +0000453typedef
454 struct _IRBB {
sewardjc97096c2004-06-30 09:28:04 +0000455 IRTypeEnv* tyenv;
sewardjd7cb8532004-08-17 23:59:23 +0000456 IRStmt** stmts;
457 Int stmts_size;
458 Int stmts_used;
sewardje539a402004-07-14 18:24:17 +0000459 IRExpr* next;
460 IRJumpKind jumpkind;
sewardjac6b7122004-06-27 01:03:57 +0000461 }
462 IRBB;
sewardjec6ad592004-06-20 12:26:53 +0000463
sewardjd7cb8532004-08-17 23:59:23 +0000464extern IRBB* emptyIRBB ( void );
465extern void addStmtToIRBB ( IRBB*, IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +0000466
sewardj35421a32004-07-05 13:12:34 +0000467extern void ppIRBB ( IRBB* );
sewardjc97096c2004-06-30 09:28:04 +0000468
sewardjec6ad592004-06-20 12:26:53 +0000469
470/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +0000471/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +0000472/*---------------------------------------------------------------*/
473
sewardjc97096c2004-06-30 09:28:04 +0000474/* For messing with IR type environments */
sewardjd7cb8532004-08-17 23:59:23 +0000475extern IRTypeEnv* emptyIRTypeEnv ( void );
sewardje539a402004-07-14 18:24:17 +0000476extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
sewardjc97096c2004-06-30 09:28:04 +0000477extern IRType lookupIRTypeEnv ( IRTypeEnv*, IRTemp );
sewardjd7cb8532004-08-17 23:59:23 +0000478extern IRTypeEnv* copyIRTypeEnv ( IRTypeEnv* );
sewardjec6ad592004-06-20 12:26:53 +0000479
sewardjc97096c2004-06-30 09:28:04 +0000480/* What is the type of this expression? */
sewardj6efd4a12004-07-15 03:54:23 +0000481extern IRType typeOfIRConst ( IRConst* );
482extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +0000483
sewardj35439212004-07-14 22:36:10 +0000484/* Sanity check a BB of IR */
485extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size );
sewardjec6ad592004-06-20 12:26:53 +0000486
sewardj6d2638e2004-07-15 09:38:27 +0000487/* Is this any value actually in the enumeration 'IRType' ? */
488extern Bool isPlausibleType ( IRType ty );
489
sewardj887a11a2004-07-05 17:26:47 +0000490#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +0000491
492
493/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +0000494/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +0000495/*---------------------------------------------------------------*/