]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/pub/libvex_ir.h
98a980f5ef18c4acd628670fbd02b9a32ee9189e
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / pub / libvex_ir.h
1
2 /*---------------------------------------------------------------*/
3 /*--- begin                                       libvex_ir.h ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2004-2010 OpenWorks LLP
11       info@open-works.net
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35
36 #ifndef __LIBVEX_IR_H
37 #define __LIBVEX_IR_H
38
39 #include "libvex_basictypes.h"
40
41    
42 /*---------------------------------------------------------------*/
43 /*--- High-level IR description                               ---*/
44 /*---------------------------------------------------------------*/
45
46 /* Vex IR is an architecture-neutral intermediate representation.
47    Unlike some IRs in systems similar to Vex, it is not like assembly
48    language (ie. a list of instructions).  Rather, it is more like the
49    IR that might be used in a compiler.
50
51    Code blocks
52    ~~~~~~~~~~~
53    The code is broken into small code blocks ("superblocks", type:
54    'IRSB').  Each code block typically represents from 1 to perhaps 50
55    instructions.  IRSBs are single-entry, multiple-exit code blocks.
56    Each IRSB contains three things:
57    - a type environment, which indicates the type of each temporary
58      value present in the IRSB
59    - a list of statements, which represent code
60    - a jump that exits from the end the IRSB
61    Because the blocks are multiple-exit, there can be additional
62    conditional exit statements that cause control to leave the IRSB
63    before the final exit.  Also because of this, IRSBs can cover
64    multiple non-consecutive sequences of code (up to 3).  These are
65    recorded in the type VexGuestExtents (see libvex.h).
66
67    Statements and expressions
68    ~~~~~~~~~~~~~~~~~~~~~~~~~~
69    Statements (type 'IRStmt') represent operations with side-effects,
70    eg.  guest register writes, stores, and assignments to temporaries.
71    Expressions (type 'IRExpr') represent operations without
72    side-effects, eg. arithmetic operations, loads, constants.
73    Expressions can contain sub-expressions, forming expression trees,
74    eg. (3 + (4 * load(addr1)).
75
76    Storage of guest state
77    ~~~~~~~~~~~~~~~~~~~~~~
78    The "guest state" contains the guest registers of the guest machine
79    (ie.  the machine that we are simulating).  It is stored by default
80    in a block of memory supplied by the user of the VEX library,
81    generally referred to as the guest state (area).  To operate on
82    these registers, one must first read ("Get") them from the guest
83    state into a temporary value.  Afterwards, one can write ("Put")
84    them back into the guest state.
85
86    Get and Put are characterised by a byte offset into the guest
87    state, a small integer which effectively gives the identity of the
88    referenced guest register, and a type, which indicates the size of
89    the value to be transferred.
90
91    The basic "Get" and "Put" operations are sufficient to model normal
92    fixed registers on the guest.  Selected areas of the guest state
93    can be treated as a circular array of registers (type:
94    'IRRegArray'), which can be indexed at run-time.  This is done with
95    the "GetI" and "PutI" primitives.  This is necessary to describe
96    rotating register files, for example the x87 FPU stack, SPARC
97    register windows, and the Itanium register files.
98
99    Examples, and flattened vs. unflattened code
100    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101    For example, consider this x86 instruction:
102      
103      addl %eax, %ebx
104
105    One Vex IR translation for this code would be this:
106
107      ------ IMark(0x24F275, 7) ------
108      t3 = GET:I32(0)             # get %eax, a 32-bit integer
109      t2 = GET:I32(12)            # get %ebx, a 32-bit integer
110      t1 = Add32(t3,t2)           # addl
111      PUT(0) = t1                 # put %eax
112
113    (For simplicity, this ignores the effects on the condition codes, and
114    the update of the instruction pointer.)
115
116    The "IMark" is an IR statement that doesn't represent actual code.
117    Instead it indicates the address and length of the original
118    instruction.  The numbers 0 and 12 are offsets into the guest state
119    for %eax and %ebx.  The full list of offsets for an architecture
120    <ARCH> can be found in the type VexGuest<ARCH>State in the file
121    VEX/pub/libvex_guest_<ARCH>.h.
122
123    The five statements in this example are:
124    - the IMark
125    - three assignments to temporaries
126    - one register write (put)
127
128    The six expressions in this example are:
129    - two register reads (gets)
130    - one arithmetic (add) operation
131    - three temporaries (two nested within the Add32, one in the PUT)
132
133    The above IR is "flattened", ie. all sub-expressions are "atoms",
134    either constants or temporaries.  An equivalent, unflattened version
135    would be:
136    
137      PUT(0) = Add32(GET:I32(0), GET:I32(12))
138
139    IR is guaranteed to be flattened at instrumentation-time.  This makes
140    instrumentation easier.  Equivalent flattened and unflattened IR
141    typically results in the same generated code.
142
143    Another example, this one showing loads and stores:
144
145      addl %edx,4(%eax)
146
147    This becomes (again ignoring condition code and instruction pointer
148    updates):
149
150      ------ IMark(0x4000ABA, 3) ------
151      t3 = Add32(GET:I32(0),0x4:I32)
152      t2 = LDle:I32(t3)
153      t1 = GET:I32(8)
154      t0 = Add32(t2,t1)
155      STle(t3) = t0
156
157    The "le" in "LDle" and "STle" is short for "little-endian".
158
159    No need for deallocations
160    ~~~~~~~~~~~~~~~~~~~~~~~~~
161    Although there are allocation functions for various data structures
162    in this file, there are no deallocation functions.  This is because
163    Vex uses a memory allocation scheme that automatically reclaims the
164    memory used by allocated structures once translation is completed.
165    This makes things easier for tools that instruments/transforms code
166    blocks.
167
168    SSAness and typing
169    ~~~~~~~~~~~~~~~~~~
170    The IR is fully typed.  For every IRSB (IR block) it is possible to
171    say unambiguously whether or not it is correctly typed.
172    Incorrectly typed IR has no meaning and the VEX will refuse to
173    process it.  At various points during processing VEX typechecks the
174    IR and aborts if any violations are found.  This seems overkill but
175    makes it a great deal easier to build a reliable JIT.
176
177    IR also has the SSA property.  SSA stands for Static Single
178    Assignment, and what it means is that each IR temporary may be
179    assigned to only once.  This idea became widely used in compiler
180    construction in the mid to late 90s.  It makes many IR-level
181    transformations/code improvements easier, simpler and faster.
182    Whenever it typechecks an IR block, VEX also checks the SSA
183    property holds, and will abort if not so.  So SSAness is
184    mechanically and rigidly enforced.
185 */
186
187 /*---------------------------------------------------------------*/
188 /*--- Type definitions for the IR                             ---*/
189 /*---------------------------------------------------------------*/
190
191 /* General comments about naming schemes:
192
193    All publically visible functions contain the name of the primary
194    type on which they operate (IRFoo, IRBar, etc).  Hence you should
195    be able to identify these functions by grepping for "IR[A-Z]".
196
197    For some type 'IRFoo':
198
199    - ppIRFoo is the printing method for IRFoo, printing it to the
200      output channel specified in the LibVEX_Initialise call.
201
202    - eqIRFoo is a structural equality predicate for IRFoos.
203
204    - deepCopyIRFoo is a deep copy constructor for IRFoos. 
205      It recursively traverses the entire argument tree and
206      produces a complete new tree.  All types have a deep copy
207      constructor.
208
209    - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
210      It creates a new top-level copy of the supplied object,
211      but does not copy any sub-objects.  Only some types have a
212      shallow copy constructor.
213 */
214
215 /* ------------------ Types ------------------ */
216
217 /* A type indicates the size of a value, and whether it's an integer, a
218    float, or a vector (SIMD) value. */
219 typedef 
220    enum { 
221       Ity_INVALID=0x11000,
222       Ity_I1, 
223       Ity_I8, 
224       Ity_I16, 
225       Ity_I32, 
226       Ity_I64,
227       Ity_I128,  /* 128-bit scalar */
228       Ity_F32,   /* IEEE 754 float */
229       Ity_F64,   /* IEEE 754 double */
230       Ity_V128   /* 128-bit SIMD */
231    }
232    IRType;
233
234 /* Pretty-print an IRType */
235 extern void ppIRType ( IRType );
236
237 /* Get the size (in bytes) of an IRType */ 
238 extern Int sizeofIRType ( IRType );
239
240
241 /* ------------------ Endianness ------------------ */
242
243 /* IREndness is used in load IRExprs and store IRStmts. */
244 typedef
245    enum { 
246       Iend_LE=0x12000, /* little endian */
247       Iend_BE          /* big endian */
248    }
249    IREndness;
250
251
252 /* ------------------ Constants ------------------ */
253
254 /* IRConsts are used within 'Const' and 'Exit' IRExprs. */
255
256 /* The various kinds of constant. */
257 typedef
258    enum { 
259       Ico_U1=0x13000,
260       Ico_U8, 
261       Ico_U16, 
262       Ico_U32, 
263       Ico_U64,
264       Ico_F64,   /* 64-bit IEEE754 floating */
265       Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
266                     as a IEEE754 double value. */
267       Ico_V128   /* 128-bit restricted vector constant, with 1 bit
268                     (repeated 8 times) for each of the 16 x 1-byte lanes */
269    }
270    IRConstTag;
271
272 /* A constant.  Stored as a tagged union.  'tag' indicates what kind of
273    constant this is.  'Ico' is the union that holds the fields.  If an
274    IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
275    and its value can be accessed with 'c.Ico.U32'. */
276 typedef
277    struct _IRConst {
278       IRConstTag tag;
279       union {
280          Bool   U1;
281          UChar  U8;
282          UShort U16;
283          UInt   U32;
284          ULong  U64;
285          Double F64;
286          ULong  F64i;
287          UShort V128;   /* 16-bit value; see Ico_V128 comment above */
288       } Ico;
289    }
290    IRConst;
291
292 /* IRConst constructors */
293 extern IRConst* IRConst_U1   ( Bool );
294 extern IRConst* IRConst_U8   ( UChar );
295 extern IRConst* IRConst_U16  ( UShort );
296 extern IRConst* IRConst_U32  ( UInt );
297 extern IRConst* IRConst_U64  ( ULong );
298 extern IRConst* IRConst_F64  ( Double );
299 extern IRConst* IRConst_F64i ( ULong );
300 extern IRConst* IRConst_V128 ( UShort );
301
302 /* Deep-copy an IRConst */
303 extern IRConst* deepCopyIRConst ( IRConst* );
304
305 /* Pretty-print an IRConst */
306 extern void ppIRConst ( IRConst* );
307
308 /* Compare two IRConsts for equality */
309 extern Bool eqIRConst ( IRConst*, IRConst* );
310
311
312 /* ------------------ Call targets ------------------ */
313
314 /* Describes a helper function to call.  The name part is purely for
315    pretty printing and not actually used.  regparms=n tells the back
316    end that the callee has been declared
317    "__attribute__((regparm(n)))".  On some targets (x86) the back end
318    will need to construct a non-standard sequence to call a function
319    declared like this. 
320
321    mcx_mask is a sop to Memcheck.  It indicates which args should be
322    considered 'always defined' when lazily computing definedness of
323    the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
324    args[1], etc.  If a bit is set, the corresponding arg is excluded
325    (hence "x" in "mcx") from definedness checking.  
326 */
327
328 typedef
329    struct {
330       Int    regparms;
331       HChar* name;
332       void*  addr;
333       UInt   mcx_mask;
334    }
335    IRCallee;
336
337 /* Create an IRCallee. */
338 extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
339
340 /* Deep-copy an IRCallee. */
341 extern IRCallee* deepCopyIRCallee ( IRCallee* );
342
343 /* Pretty-print an IRCallee. */
344 extern void ppIRCallee ( IRCallee* );
345
346
347 /* ------------------ Guest state arrays ------------------ */
348
349 /* This describes a section of the guest state that we want to
350    be able to index at run time, so as to be able to describe 
351    indexed or rotating register files on the guest. */
352 typedef
353    struct {
354       Int    base;   /* guest state offset of start of indexed area */
355       IRType elemTy; /* type of each element in the indexed area */
356       Int    nElems; /* number of elements in the indexed area */
357    }
358    IRRegArray;
359
360 extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
361
362 extern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
363
364 extern void ppIRRegArray ( IRRegArray* );
365 extern Bool eqIRRegArray ( IRRegArray*, IRRegArray* );
366
367
368 /* ------------------ Temporaries ------------------ */
369
370 /* This represents a temporary, eg. t1.  The IR optimiser relies on the
371    fact that IRTemps are 32-bit ints.  Do not change them to be ints of
372    any other size. */
373 typedef UInt IRTemp;
374
375 /* Pretty-print an IRTemp. */
376 extern void ppIRTemp ( IRTemp );
377
378 #define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
379
380
381 /* --------------- Primops (arity 1,2,3 and 4) --------------- */
382
383 /* Primitive operations that are used in Unop, Binop, Triop and Qop
384    IRExprs.  Once we take into account integer, floating point and SIMD
385    operations of all the different sizes, there are quite a lot of them.
386    Most instructions supported by the architectures that Vex supports
387    (x86, PPC, etc) are represented.  Some more obscure ones (eg. cpuid)
388    are not;  they are instead handled with dirty helpers that emulate
389    their functionality.  Such obscure ones are thus not directly visible
390    in the IR, but their effects on guest state (memory and registers) 
391    are made visible via the annotations in IRDirty structures.
392 */
393 typedef
394    enum { 
395       /* -- Do not change this ordering.  The IR generators rely on
396             (eg) Iop_Add64 == IopAdd8 + 3. -- */
397
398       Iop_INVALID=0x14000,
399       Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
400       Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
401       /* Signless mul.  MullS/MullU is elsewhere. */
402       Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
403       Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
404       Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
405       Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
406       Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
407       Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
408       Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
409       /* Integer comparisons. */
410       Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
411       Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
412       /* Tags for unary ops */
413       Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
414
415       /* Exactly like CmpEQ8/16/32/64, but carrying the additional
416          hint that these compute the success/failure of a CAS
417          operation, and hence are almost certainly applied to two
418          copies of the same value, which in turn has implications for
419          Memcheck's instrumentation. */
420       Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
421       Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
422
423       /* -- Ordering not important after here. -- */
424
425       /* Widening multiplies */
426       Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
427       Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
428
429       /* Wierdo integer stuff */
430       Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
431       Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
432       /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
433          zero.  You must ensure they are never given a zero argument.
434       */
435
436       /* Standard integer comparisons */
437       Iop_CmpLT32S, Iop_CmpLT64S,
438       Iop_CmpLE32S, Iop_CmpLE64S,
439       Iop_CmpLT32U, Iop_CmpLT64U,
440       Iop_CmpLE32U, Iop_CmpLE64U,
441
442       /* As a sop to Valgrind-Memcheck, the following are useful. */
443       Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
444       Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
445       Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /*  \x -> x | -x */
446       Iop_Max32U, /* unsigned max */
447
448       /* PowerPC-style 3-way integer comparisons.  Without them it is
449          difficult to simulate PPC efficiently.
450          op(x,y) | x < y  = 0x8 else 
451                  | x > y  = 0x4 else
452                  | x == y = 0x2
453       */
454       Iop_CmpORD32U, Iop_CmpORD64U,
455       Iop_CmpORD32S, Iop_CmpORD64S,
456
457       /* Division */
458       /* TODO: clarify semantics wrt rounding, negative values, whatever */
459       Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
460       Iop_DivS32,   // ditto, signed
461       Iop_DivU64,   // :: I64,I64 -> I64 (simple div, no mod)
462       Iop_DivS64,   // ditto, signed
463
464       Iop_DivModU64to32, // :: I64,I32 -> I64
465                          // of which lo half is div and hi half is mod
466       Iop_DivModS64to32, // ditto, signed
467
468       Iop_DivModU128to64, // :: V128,I64 -> V128
469                           // of which lo half is div and hi half is mod
470       Iop_DivModS128to64, // ditto, signed
471
472       /* Integer conversions.  Some of these are redundant (eg
473          Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
474          having a complete set reduces the typical dynamic size of IR
475          and makes the instruction selectors easier to write. */
476
477       /* Widening conversions */
478       Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
479                   Iop_16Uto32, Iop_16Uto64,
480                                Iop_32Uto64,
481       Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
482                   Iop_16Sto32, Iop_16Sto64,
483                                Iop_32Sto64,
484
485       /* Narrowing conversions */
486       Iop_64to8, Iop_32to8, Iop_64to16,
487       /* 8 <-> 16 bit conversions */
488       Iop_16to8,      // :: I16 -> I8, low half
489       Iop_16HIto8,    // :: I16 -> I8, high half
490       Iop_8HLto16,    // :: (I8,I8) -> I16
491       /* 16 <-> 32 bit conversions */
492       Iop_32to16,     // :: I32 -> I16, low half
493       Iop_32HIto16,   // :: I32 -> I16, high half
494       Iop_16HLto32,   // :: (I16,I16) -> I32
495       /* 32 <-> 64 bit conversions */
496       Iop_64to32,     // :: I64 -> I32, low half
497       Iop_64HIto32,   // :: I64 -> I32, high half
498       Iop_32HLto64,   // :: (I32,I32) -> I64
499       /* 64 <-> 128 bit conversions */
500       Iop_128to64,    // :: I128 -> I64, low half
501       Iop_128HIto64,  // :: I128 -> I64, high half
502       Iop_64HLto128,  // :: (I64,I64) -> I128
503       /* 1-bit stuff */
504       Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
505       Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
506       Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
507       Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
508       Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
509       Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
510       Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
511       Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
512       Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
513       Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
514
515       /* ------ Floating point.  We try to be IEEE754 compliant. ------ */
516
517       /* --- Simple stuff as mandated by 754. --- */
518
519       /* Binary operations, with rounding. */
520       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
521       Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
522
523       /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */ 
524       Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
525
526       /* Variants of the above which produce a 64-bit result but which
527          round their result to a IEEE float range first. */
528       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
529       Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32, 
530
531       /* Unary operations, without rounding. */
532       /* :: F64 -> F64 */
533       Iop_NegF64, Iop_AbsF64,
534
535       /* :: F32 -> F32 */
536       Iop_NegF32, Iop_AbsF32,
537
538       /* Unary operations, with rounding. */
539       /* :: IRRoundingMode(I32) x F64 -> F64 */
540       Iop_SqrtF64, Iop_SqrtF64r32,
541
542       /* :: IRRoundingMode(I32) x F32 -> F32 */
543       Iop_SqrtF32,
544
545       /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
546             0x45 Unordered
547             0x01 LT
548             0x00 GT
549             0x40 EQ
550          This just happens to be the Intel encoding.  The values
551          are recorded in the type IRCmpF64Result.
552       */
553       /* :: F64 x F64 -> IRCmpF64Result(I32) */
554       Iop_CmpF64,
555
556       /* --- Int to/from FP conversions. --- */
557
558       /* For the most part, these take a first argument :: Ity_I32 (as
559          IRRoundingMode) which is an indication of the rounding mode
560          to use, as per the following encoding ("the standard
561          encoding"):
562             00b  to nearest (the default)
563             01b  to -infinity
564             10b  to +infinity
565             11b  to zero
566          This just happens to be the Intel encoding.  For reference only,
567          the PPC encoding is:
568             00b  to nearest (the default)
569             01b  to zero
570             10b  to +infinity
571             11b  to -infinity
572          Any PPC -> IR front end will have to translate these PPC
573          encodings, as encoded in the guest state, to the standard
574          encodings, to pass to the primops.
575          For reference only, the ARM VFP encoding is:
576             00b  to nearest
577             01b  to +infinity
578             10b  to -infinity
579             11b  to zero
580          Again, this will have to be converted to the standard encoding
581          to pass to primops.
582
583          If one of these conversions gets an out-of-range condition,
584          or a NaN, as an argument, the result is host-defined.  On x86
585          the "integer indefinite" value 0x80..00 is produced.  On PPC
586          it is either 0x80..00 or 0x7F..FF depending on the sign of
587          the argument.
588
589          On ARMvfp, when converting to a signed integer result, the
590          overflow result is 0x80..00 for negative args and 0x7F..FF
591          for positive args.  For unsigned integer results it is
592          0x00..00 and 0xFF..FF respectively.
593
594          Rounding is required whenever the destination type cannot
595          represent exactly all values of the source type.
596       */
597       Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
598       Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
599       Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
600
601       Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
602
603       Iop_I16StoF64, /*                       signed I16 -> F64 */
604       Iop_I32StoF64, /*                       signed I32 -> F64 */
605       Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
606
607       Iop_I32UtoF64, /*                       unsigned I32 -> F64 */
608
609       /* Conversion between floating point formats */
610       Iop_F32toF64,  /*                       F32 -> F64 */
611       Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
612
613       /* Reinterpretation.  Take an F64 and produce an I64 with 
614          the same bit pattern, or vice versa. */
615       Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
616       Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
617
618       /* --- guest x86/amd64 specifics, not mandated by 754. --- */
619
620       /* Binary ops, with rounding. */
621       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
622       Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
623       Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
624       Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
625       Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
626       Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
627       Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
628       Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
629       Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
630       /* Note that on x86 guest, PRem1{C3210} has the same behaviour
631          as the IEEE mandated RemF64, except it is limited in the
632          range of its operand.  Hence the partialness. */
633
634       /* Unary ops, with rounding. */
635       /* :: IRRoundingMode(I32) x F64 -> F64 */
636       Iop_SinF64,    /* FSIN */
637       Iop_CosF64,    /* FCOS */
638       Iop_TanF64,    /* FTAN */
639       Iop_2xm1F64,   /* (2^arg - 1.0) */
640       Iop_RoundF64toInt, /* F64 value to nearest integral value (still
641                             as F64) */
642
643       /* --- guest ppc32/64 specifics, not mandated by 754. --- */
644
645       /* Ternary operations, with rounding. */
646       /* Fused multiply-add/sub, with 112-bit intermediate
647          precision */
648       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 
649             (computes arg2 * arg3 +/- arg4) */ 
650       Iop_MAddF64, Iop_MSubF64,
651
652       /* Variants of the above which produce a 64-bit result but which
653          round their result to a IEEE float range first. */
654       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */ 
655       Iop_MAddF64r32, Iop_MSubF64r32,
656
657       /* :: F64 -> F64 */
658       Iop_Est5FRSqrt,    /* reciprocal square root estimate, 5 good bits */
659       Iop_RoundF64toF64_NEAREST, /* frin */
660       Iop_RoundF64toF64_NegINF,  /* frim */ 
661       Iop_RoundF64toF64_PosINF,  /* frip */
662       Iop_RoundF64toF64_ZERO,    /* friz */
663
664       /* :: F64 -> F32 */
665       Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
666
667       /* :: IRRoundingMode(I32) x F64 -> F64 */
668       Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
669       /* NB: pretty much the same as Iop_F64toF32, except no change 
670          of type. */
671
672       /* :: F64 -> I32 */
673       Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord)
674                        from FP result */
675
676       /* ------------------ 64-bit SIMD Integer. ------------------ */
677
678       /* MISC (vector integer cmp != 0) */
679       Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
680
681       /* ADDITION (normal / unsigned sat / signed sat) */
682       Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
683       Iop_QAdd8Ux8, Iop_QAdd16Ux4,
684       Iop_QAdd8Sx8, Iop_QAdd16Sx4,
685
686       /* SUBTRACTION (normal / unsigned sat / signed sat) */
687       Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
688       Iop_QSub8Ux8, Iop_QSub16Ux4,
689       Iop_QSub8Sx8, Iop_QSub16Sx4,
690
691       /* MULTIPLICATION (normal / high half of signed/unsigned) */
692       Iop_Mul16x4, Iop_Mul32x2,
693       Iop_MulHi16Ux4,
694       Iop_MulHi16Sx4,
695
696       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
697       Iop_Avg8Ux8,
698       Iop_Avg16Ux4,
699
700       /* MIN/MAX */
701       Iop_Max16Sx4,
702       Iop_Max8Ux8,
703       Iop_Min16Sx4,
704       Iop_Min8Ux8,
705
706       /* COMPARISON */
707       Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
708       Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
709
710       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
711       Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
712                    Iop_ShrN16x4, Iop_ShrN32x2,
713       Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
714
715       /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */
716       Iop_QNarrow16Ux4,
717       Iop_QNarrow16Sx4,
718       Iop_QNarrow32Sx2,
719
720       /* INTERLEAVING -- interleave lanes from low or high halves of
721          operands.  Most-significant result lane is from the left
722          arg. */
723       Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
724       Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
725
726       /* CONCATENATION -- build a new value by concatenating either
727          the even or odd lanes of both operands.  Note that
728          Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
729          and so are omitted. */
730       Iop_CatOddLanes16x4, Iop_CatEvenLanes16x4,
731
732       /* PERMUTING -- copy src bytes to dst,
733          as indexed by control vector bytes:
734             for i in 0 .. 7 . result[i] = argL[ argR[i] ] 
735          argR[i] values may only be in the range 0 .. 7, else behaviour
736          is undefined. */
737       Iop_Perm8x8,
738
739       /* ------------------ 128-bit SIMD FP. ------------------ */
740
741       /* --- 32x4 vector FP --- */
742
743       /* binary */
744       Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 
745       Iop_Max32Fx4, Iop_Min32Fx4,
746       /* Note: For the following compares, the ppc front-end assumes a
747          nan in a lane of either argument returns zero for that lane. */
748       Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 
749       Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
750
751       /* unary */
752       Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
753
754       /* --- Int to/from FP conversion --- */
755       /* Unlike the standard fp conversions, these irops take no
756          rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
757          indicate the mode: {-inf, +inf, nearest, zero} respectively. */
758       Iop_I32UtoFx4,     Iop_I32StoFx4,       /* I32x4 -> F32x4       */
759       Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ,   /* F32x4 -> I32x4       */
760       Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
761       Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
762
763       /* --- 32x4 lowest-lane-only scalar FP --- */
764
765       /* In binary cases, upper 3/4 is copied from first operand.  In
766          unary cases, upper 3/4 is copied from the operand. */
767
768       /* binary */
769       Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 
770       Iop_Max32F0x4, Iop_Min32F0x4,
771       Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 
772
773       /* unary */
774       Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
775
776       /* --- 64x2 vector FP --- */
777
778       /* binary */
779       Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 
780       Iop_Max64Fx2, Iop_Min64Fx2,
781       Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 
782
783       /* unary */
784       Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
785
786       /* --- 64x2 lowest-lane-only scalar FP --- */
787
788       /* In binary cases, upper half is copied from first operand.  In
789          unary cases, upper half is copied from the operand. */
790
791       /* binary */
792       Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 
793       Iop_Max64F0x2, Iop_Min64F0x2,
794       Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 
795
796       /* unary */
797       Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
798
799       /* --- pack / unpack --- */
800
801       /* 64 <-> 128 bit vector */
802       Iop_V128to64,     // :: V128 -> I64, low half
803       Iop_V128HIto64,   // :: V128 -> I64, high half
804       Iop_64HLtoV128,   // :: (I64,I64) -> V128
805
806       Iop_64UtoV128,
807       Iop_SetV128lo64,
808
809       /* 32 <-> 128 bit vector */
810       Iop_32UtoV128,
811       Iop_V128to32,     // :: V128 -> I32, lowest lane
812       Iop_SetV128lo32,  // :: (V128,I32) -> V128
813
814       /* ------------------ 128-bit SIMD Integer. ------------------ */
815
816       /* BITWISE OPS */
817       Iop_NotV128,
818       Iop_AndV128, Iop_OrV128, Iop_XorV128, 
819
820       /* VECTOR SHIFT (shift amt :: Ity_I8) */
821       Iop_ShlV128, Iop_ShrV128,
822
823       /* MISC (vector integer cmp != 0) */
824       Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
825
826       /* ADDITION (normal / unsigned sat / signed sat) */
827       Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,  Iop_Add64x2,
828       Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4,
829       Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4,
830
831       /* SUBTRACTION (normal / unsigned sat / signed sat) */
832       Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,  Iop_Sub64x2,
833       Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4,
834       Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4,
835
836       /* MULTIPLICATION (normal / high half of signed/unsigned) */
837       Iop_Mul16x8,
838       Iop_MulHi16Ux8, Iop_MulHi32Ux4,
839       Iop_MulHi16Sx8, Iop_MulHi32Sx4,
840       /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
841       Iop_MullEven8Ux16, Iop_MullEven16Ux8,
842       Iop_MullEven8Sx16, Iop_MullEven16Sx8,
843
844       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
845       Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
846       Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
847
848       /* MIN/MAX */
849       Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
850       Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
851       Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
852       Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
853
854       /* COMPARISON */
855       Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,
856       Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
857       Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
858
859       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
860       Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
861       Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
862       Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4,
863
864       /* VECTOR x VECTOR SHIFT / ROTATE */
865       Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4,
866       Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4,
867       Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4,
868       Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
869
870       /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */
871       /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */
872       Iop_QNarrow16Ux8, Iop_QNarrow32Ux4,
873       Iop_QNarrow16Sx8, Iop_QNarrow32Sx4,
874       Iop_Narrow16x8, Iop_Narrow32x4,
875
876       /* INTERLEAVING -- interleave lanes from low or high halves of
877          operands.  Most-significant result lane is from the left
878          arg. */
879       Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
880       Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
881       Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, 
882       Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
883
884       /* DUPLICATING -- copy value to all lanes */
885       Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
886
887       /* PERMUTING -- copy src bytes to dst,
888          as indexed by control vector bytes:
889             for i in 0 .. 15 . result[i] = argL[ argR[i] ] 
890          argR[i] values may only be in the range 0 .. 15, else behaviour
891          is undefined. */
892       Iop_Perm8x16
893    }
894    IROp;
895
896 /* Pretty-print an op. */
897 extern void ppIROp ( IROp );
898
899
900 /* Encoding of IEEE754-specified rounding modes.  This is the same as
901    the encoding used by Intel IA32 to indicate x87 rounding mode.
902    Note, various front and back ends rely on the actual numerical
903    values of these, so do not change them. */
904 typedef
905    enum { 
906       Irrm_NEAREST = 0, 
907       Irrm_NegINF  = 1, 
908       Irrm_PosINF  = 2, 
909       Irrm_ZERO    = 3 
910    }
911    IRRoundingMode;
912
913 /* Floating point comparison result values, as created by Iop_CmpF64.
914    This is also derived from what IA32 does. */
915 typedef
916    enum {
917       Ircr_UN = 0x45,
918       Ircr_LT = 0x01,
919       Ircr_GT = 0x00,
920       Ircr_EQ = 0x40
921    }
922    IRCmpF64Result;
923
924
925 /* ------------------ Expressions ------------------ */
926
927 /* The different kinds of expressions.  Their meaning is explained below
928    in the comments for IRExpr. */
929 typedef
930    enum { 
931       Iex_Binder=0x15000,
932       Iex_Get,
933       Iex_GetI,
934       Iex_RdTmp,
935       Iex_Qop,
936       Iex_Triop,
937       Iex_Binop,
938       Iex_Unop,
939       Iex_Load,
940       Iex_Const,
941       Iex_Mux0X,
942       Iex_CCall
943    }
944    IRExprTag;
945
946 /* An expression.  Stored as a tagged union.  'tag' indicates what kind
947    of expression this is.  'Iex' is the union that holds the fields.  If
948    an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
949    expression, and the fields can be accessed with
950    'e.Iex.Load.<fieldname>'.
951
952    For each kind of expression, we show what it looks like when
953    pretty-printed with ppIRExpr().
954 */
955 typedef
956    struct _IRExpr
957    IRExpr;
958
959 struct _IRExpr {
960    IRExprTag tag;
961    union {
962       /* Used only in pattern matching within Vex.  Should not be seen
963          outside of Vex. */
964       struct {
965          Int binder;
966       } Binder;
967
968       /* Read a guest register, at a fixed offset in the guest state.
969          ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
970       */
971       struct {
972          Int    offset;    /* Offset into the guest state */
973          IRType ty;        /* Type of the value being read */
974       } Get;
975
976       /* Read a guest register at a non-fixed offset in the guest
977          state.  This allows circular indexing into parts of the guest
978          state, which is essential for modelling situations where the
979          identity of guest registers is not known until run time.  One
980          example is the x87 FP register stack.
981
982          The part of the guest state to be treated as a circular array
983          is described in the IRRegArray 'descr' field.  It holds the
984          offset of the first element in the array, the type of each
985          element, and the number of elements.
986
987          The array index is indicated rather indirectly, in a way
988          which makes optimisation easy: as the sum of variable part
989          (the 'ix' field) and a constant offset (the 'bias' field).
990
991          Since the indexing is circular, the actual array index to use
992          is computed as (ix + bias) % num-of-elems-in-the-array.
993
994          Here's an example.  The description
995
996             (96:8xF64)[t39,-7]
997
998          describes an array of 8 F64-typed values, the
999          guest-state-offset of the first being 96.  This array is
1000          being indexed at (t39 - 7) % 8.
1001
1002          It is important to get the array size/type exactly correct
1003          since IR optimisation looks closely at such info in order to
1004          establish aliasing/non-aliasing between seperate GetI and
1005          PutI events, which is used to establish when they can be
1006          reordered, etc.  Putting incorrect info in will lead to
1007          obscure IR optimisation bugs.
1008
1009             ppIRExpr output: GETI<descr>[<ix>,<bias]
1010                          eg. GETI(128:8xI8)[t1,0]
1011       */
1012       struct {
1013          IRRegArray* descr; /* Part of guest state treated as circular */
1014          IRExpr*     ix;    /* Variable part of index into array */
1015          Int         bias;  /* Constant offset part of index into array */
1016       } GetI;
1017
1018       /* The value held by a temporary.
1019          ppIRExpr output: t<tmp>, eg. t1
1020       */
1021       struct {
1022          IRTemp tmp;       /* The temporary number */
1023       } RdTmp;
1024
1025       /* A quaternary operation.
1026          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1027                       eg. MAddF64r32(t1, t2, t3, t4)
1028       */
1029       struct {
1030          IROp op;          /* op-code   */
1031          IRExpr* arg1;     /* operand 1 */
1032          IRExpr* arg2;     /* operand 2 */
1033          IRExpr* arg3;     /* operand 3 */
1034          IRExpr* arg4;     /* operand 4 */
1035       } Qop;
1036
1037       /* A ternary operation.
1038          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1039                       eg. MulF64(1, 2.0, 3.0)
1040       */
1041       struct {
1042          IROp op;          /* op-code   */
1043          IRExpr* arg1;     /* operand 1 */
1044          IRExpr* arg2;     /* operand 2 */
1045          IRExpr* arg3;     /* operand 3 */
1046       } Triop;
1047
1048       /* A binary operation.
1049          ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1050       */
1051       struct {
1052          IROp op;          /* op-code   */
1053          IRExpr* arg1;     /* operand 1 */
1054          IRExpr* arg2;     /* operand 2 */
1055       } Binop;
1056
1057       /* A unary operation.
1058          ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1059       */
1060       struct {
1061          IROp    op;       /* op-code */
1062          IRExpr* arg;      /* operand */
1063       } Unop;
1064
1065       /* A load from memory -- a normal load, not a load-linked.
1066          Load-Linkeds (and Store-Conditionals) are instead represented
1067          by IRStmt.LLSC since Load-Linkeds have side effects and so
1068          are not semantically valid IRExpr's.
1069          ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1070       */
1071       struct {
1072          IREndness end;    /* Endian-ness of the load */
1073          IRType    ty;     /* Type of the loaded value */
1074          IRExpr*   addr;   /* Address being loaded from */
1075       } Load;
1076
1077       /* A constant-valued expression.
1078          ppIRExpr output: <con>, eg. 0x4:I32
1079       */
1080       struct {
1081          IRConst* con;     /* The constant itself */
1082       } Const;
1083
1084       /* A call to a pure (no side-effects) helper C function.
1085
1086          With the 'cee' field, 'name' is the function's name.  It is
1087          only used for pretty-printing purposes.  The address to call
1088          (host address, of course) is stored in the 'addr' field
1089          inside 'cee'.
1090
1091          The 'args' field is a NULL-terminated array of arguments.
1092          The stated return IRType, and the implied argument types,
1093          must match that of the function being called well enough so
1094          that the back end can actually generate correct code for the
1095          call.
1096
1097          The called function **must** satisfy the following:
1098
1099          * no side effects -- must be a pure function, the result of
1100            which depends only on the passed parameters.
1101
1102          * it may not look at, nor modify, any of the guest state
1103            since that would hide guest state transitions from
1104            instrumenters
1105
1106          * it may not access guest memory, since that would hide
1107            guest memory transactions from the instrumenters
1108
1109          This is restrictive, but makes the semantics clean, and does
1110          not interfere with IR optimisation.
1111
1112          If you want to call a helper which can mess with guest state
1113          and/or memory, instead use Ist_Dirty.  This is a lot more
1114          flexible, but you have to give a bunch of details about what
1115          the helper does (and you better be telling the truth,
1116          otherwise any derived instrumentation will be wrong).  Also
1117          Ist_Dirty inhibits various IR optimisations and so can cause
1118          quite poor code to be generated.  Try to avoid it.
1119
1120          ppIRExpr output: <cee>(<args>):<retty>
1121                       eg. foo{0x80489304}(t1, t2):I32
1122       */
1123       struct {
1124          IRCallee* cee;    /* Function to call. */
1125          IRType    retty;  /* Type of return value. */
1126          IRExpr**  args;   /* Vector of argument expressions. */
1127       }  CCall;
1128
1129       /* A ternary if-then-else operator.  It returns expr0 if cond is
1130          zero, exprX otherwise.  Note that it is STRICT, ie. both
1131          expr0 and exprX are evaluated in all cases.
1132
1133          ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1134                          eg. Mux0X(t6,t7,t8)
1135       */
1136       struct {
1137          IRExpr* cond;     /* Condition */
1138          IRExpr* expr0;    /* True expression */
1139          IRExpr* exprX;    /* False expression */
1140       } Mux0X;
1141    } Iex;
1142 };
1143
1144 /* Expression constructors. */
1145 extern IRExpr* IRExpr_Binder ( Int binder );
1146 extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
1147 extern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
1148 extern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
1149 extern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2, 
1150                                         IRExpr* arg3, IRExpr* arg4 );
1151 extern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1, 
1152                                         IRExpr* arg2, IRExpr* arg3 );
1153 extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1154 extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
1155 extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
1156 extern IRExpr* IRExpr_Const  ( IRConst* con );
1157 extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
1158 extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
1159
1160 /* Deep-copy an IRExpr. */
1161 extern IRExpr* deepCopyIRExpr ( IRExpr* );
1162
1163 /* Pretty-print an IRExpr. */
1164 extern void ppIRExpr ( IRExpr* );
1165
1166 /* NULL-terminated IRExpr vector constructors, suitable for
1167    use as arg lists in clean/dirty helper calls. */
1168 extern IRExpr** mkIRExprVec_0 ( void );
1169 extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1170 extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1171 extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1172 extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
1173 extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1174                                 IRExpr* );
1175 extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1176                                 IRExpr*, IRExpr* );
1177 extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1178                                 IRExpr*, IRExpr*, IRExpr* );
1179
1180 /* IRExpr copiers:
1181    - shallowCopy: shallow-copy (ie. create a new vector that shares the
1182      elements with the original).
1183    - deepCopy: deep-copy (ie. create a completely new vector). */
1184 extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1185 extern IRExpr** deepCopyIRExprVec ( IRExpr** );
1186
1187 /* Make a constant expression from the given host word taking into
1188    account (of course) the host word size. */
1189 extern IRExpr* mkIRExpr_HWord ( HWord );
1190
1191 /* Convenience function for constructing clean helper calls. */
1192 extern 
1193 IRExpr* mkIRExprCCall ( IRType retty,
1194                         Int regparms, HChar* name, void* addr, 
1195                         IRExpr** args );
1196
1197
1198 /* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1199  * Iex_Const). */
1200 static inline Bool isIRAtom ( IRExpr* e ) {
1201    return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
1202 }
1203
1204 /* Are these two IR atoms identical?  Causes an assertion
1205    failure if they are passed non-atoms. */
1206 extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1207
1208
1209 /* ------------------ Jump kinds ------------------ */
1210
1211 /* This describes hints which can be passed to the dispatcher at guest
1212    control-flow transfer points.
1213
1214    Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1215    guest_TISTART and guest_TILEN, which specify the start and length
1216    of the region to be invalidated.  These are both the size of a
1217    guest word.  It is the responsibility of the relevant toIR.c to
1218    ensure that these are filled in with suitable values before issuing
1219    a jump of kind Ijk_TInval.
1220
1221    Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
1222    pseudo-register guest_EMWARN, which is 32-bits regardless of the
1223    host or guest word size.  That register should be made to hold an
1224    EmWarn_* value to indicate the reason for the exit.
1225
1226    In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1227    cannot continue) and so the jump destination can be anything.
1228
1229    Re Ijk_Sys_ (syscall jumps): the guest state must have a
1230    pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1231    word.  Front ends should set this to be the IP at the most recently
1232    executed kernel-entering (system call) instruction.  This makes it
1233    very much easier (viz, actually possible at all) to back up the
1234    guest to restart a syscall that has been interrupted by a signal.
1235 */
1236 typedef
1237    enum { 
1238       Ijk_Boring=0x16000, /* not interesting; just goto next */
1239       Ijk_Call,           /* guest is doing a call */
1240       Ijk_Ret,            /* guest is doing a return */
1241       Ijk_ClientReq,      /* do guest client req before continuing */
1242       Ijk_Yield,          /* client is yielding to thread scheduler */
1243       Ijk_EmWarn,         /* report emulation warning before continuing */
1244       Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
1245       Ijk_NoDecode,       /* next instruction cannot be decoded */
1246       Ijk_MapFail,        /* Vex-provided address translation failed */
1247       Ijk_TInval,         /* Invalidate translations before continuing. */
1248       Ijk_NoRedir,        /* Jump to un-redirected guest addr */
1249       Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
1250       Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
1251       Ijk_SigBUS,         /* current instruction synths SIGBUS */
1252       /* Unfortunately, various guest-dependent syscall kinds.  They
1253          all mean: do a syscall before continuing. */
1254       Ijk_Sys_syscall,    /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
1255       Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
1256       Ijk_Sys_int48,      /* amd64/x86 'int $0x30' */
1257       Ijk_Sys_int50,      /* amd64/x86 'int $0x32' */
1258       Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
1259       Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
1260       Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
1261       Ijk_Sys_sysenter,   /* x86 'sysenter'.  guest_EIP becomes
1262                              invalid at the point this happens. */
1263       Ijk_l4_utcb_eax,
1264       Ijk_l4_utcb_ebx,
1265       Ijk_l4_utcb_ecx,
1266       Ijk_l4_utcb_edx,
1267       Ijk_l4_utcb_edi,
1268       Ijk_l4_utcb_esi,
1269           Ijk_l4_ud2,         /* UD2 instruction */
1270           Ijk_l4_artificial,  /* L4Re artificial trap */
1271    }
1272    IRJumpKind;
1273
1274 extern void ppIRJumpKind ( IRJumpKind );
1275
1276
1277 /* ------------------ Dirty helper calls ------------------ */
1278
1279 /* A dirty call is a flexible mechanism for calling (possibly
1280    conditionally) a helper function or procedure.  The helper function
1281    may read, write or modify client memory, and may read, write or
1282    modify client state.  It can take arguments and optionally return a
1283    value.  It may return different results and/or do different things
1284    when called repeatedly with the same arguments, by means of storing
1285    private state.
1286
1287    If a value is returned, it is assigned to the nominated return
1288    temporary.
1289
1290    Dirty calls are statements rather than expressions for obvious
1291    reasons.  If a dirty call is marked as writing guest state, any
1292    values derived from the written parts of the guest state are
1293    invalid.  Similarly, if the dirty call is stated as writing
1294    memory, any loaded values are invalidated by it.
1295
1296    In order that instrumentation is possible, the call must state, and
1297    state correctly:
1298
1299    * whether it reads, writes or modifies memory, and if so where
1300      (only one chunk can be stated)
1301
1302    * whether it reads, writes or modifies guest state, and if so which
1303      pieces (several pieces may be stated, and currently their extents
1304      must be known at translation-time).
1305
1306    Normally, code is generated to pass just the args to the helper.
1307    However, if .needsBBP is set, then an extra first argument is
1308    passed, which is the baseblock pointer, so that the callee can
1309    access the guest state.  It is invalid for .nFxState to be zero
1310    but .needsBBP to be True, since .nFxState==0 is a claim that the
1311    call does not access guest state.
1312
1313    IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
1314    arguments are evaluated REGARDLESS of the guard value.  It is
1315    unspecified the relative order of arg evaluation and guard
1316    evaluation.
1317 */
1318
1319 #define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
1320
1321 /* Effects on resources (eg. registers, memory locations) */
1322 typedef
1323    enum {
1324       Ifx_None = 0x17000,   /* no effect */
1325       Ifx_Read,             /* reads the resource */
1326       Ifx_Write,            /* writes the resource */
1327       Ifx_Modify,           /* modifies the resource */
1328    }
1329    IREffect;
1330
1331 /* Pretty-print an IREffect */
1332 extern void ppIREffect ( IREffect );
1333
1334
1335 typedef
1336    struct {
1337       /* What to call, and details of args/results */
1338       IRCallee* cee;    /* where to call */
1339       IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
1340       IRExpr**  args;   /* arg list, ends in NULL */
1341       IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
1342
1343       /* Mem effects; we allow only one R/W/M region to be stated */
1344       IREffect  mFx;    /* indicates memory effects, if any */
1345       IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
1346       Int       mSize;  /* of access, or zero if mFx==Ifx_None */
1347
1348       /* Guest state effects; up to N allowed */
1349       Bool needsBBP; /* True => also pass guest state ptr to callee */
1350       Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
1351       struct {
1352          IREffect fx;   /* read, write or modify?  Ifx_None is invalid. */
1353          Int      offset;
1354          Int      size;
1355       } fxState[VEX_N_FXSTATE];
1356    }
1357    IRDirty;
1358
1359 /* Pretty-print a dirty call */
1360 extern void     ppIRDirty ( IRDirty* );
1361
1362 /* Allocate an uninitialised dirty call */
1363 extern IRDirty* emptyIRDirty ( void );
1364
1365 /* Deep-copy a dirty call */
1366 extern IRDirty* deepCopyIRDirty ( IRDirty* );
1367
1368 /* A handy function which takes some of the tedium out of constructing
1369    dirty helper calls.  The called function impliedly does not return
1370    any value and has a constant-True guard.  The call is marked as
1371    accessing neither guest state nor memory (hence the "unsafe"
1372    designation) -- you can change this marking later if need be.  A
1373    suitable IRCallee is constructed from the supplied bits. */
1374 extern 
1375 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr, 
1376                              IRExpr** args );
1377
1378 /* Similarly, make a zero-annotation dirty call which returns a value,
1379    and assign that to the given temp. */
1380 extern 
1381 IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 
1382                              Int regparms, HChar* name, void* addr, 
1383                              IRExpr** args );
1384
1385
1386 /* --------------- Memory Bus Events --------------- */
1387
1388 typedef
1389    enum { 
1390       Imbe_Fence=0x18000, 
1391    }
1392    IRMBusEvent;
1393
1394 extern void ppIRMBusEvent ( IRMBusEvent );
1395
1396
1397 /* --------------- Compare and Swap --------------- */
1398
1399 /* This denotes an atomic compare and swap operation, either
1400    a single-element one or a double-element one.
1401
1402    In the single-element case:
1403
1404      .addr is the memory address.
1405      .end  is the endianness with which memory is accessed
1406
1407      If .addr contains the same value as .expdLo, then .dataLo is
1408      written there, else there is no write.  In both cases, the
1409      original value at .addr is copied into .oldLo.
1410
1411      Types: .expdLo, .dataLo and .oldLo must all have the same type.
1412      It may be any integral type, viz: I8, I16, I32 or, for 64-bit
1413      guests, I64.
1414
1415      .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
1416      be NULL.
1417
1418    In the double-element case:
1419
1420      .addr is the memory address.
1421      .end  is the endianness with which memory is accessed
1422
1423      The operation is the same:
1424
1425      If .addr contains the same value as .expdHi:.expdLo, then
1426      .dataHi:.dataLo is written there, else there is no write.  In
1427      both cases the original value at .addr is copied into
1428      .oldHi:.oldLo.
1429
1430      Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
1431      all have the same type, which may be any integral type, viz: I8,
1432      I16, I32 or, for 64-bit guests, I64.
1433
1434      The double-element case is complicated by the issue of
1435      endianness.  In all cases, the two elements are understood to be
1436      located adjacently in memory, starting at the address .addr.
1437
1438        If .end is Iend_LE, then the .xxxLo component is at the lower
1439        address and the .xxxHi component is at the higher address, and
1440        each component is itself stored little-endianly.
1441
1442        If .end is Iend_BE, then the .xxxHi component is at the lower
1443        address and the .xxxLo component is at the higher address, and
1444        each component is itself stored big-endianly.
1445
1446    This allows representing more cases than most architectures can
1447    handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
1448
1449    How to know if the CAS succeeded?
1450
1451    * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
1452      then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
1453      stored at .addr, and the original value there was .oldLo (resp
1454      .oldHi:.oldLo).
1455
1456    * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
1457      then the CAS failed, and the original value at .addr was .oldLo
1458      (resp. .oldHi:.oldLo).
1459
1460    Hence it is easy to know whether or not the CAS succeeded.
1461 */
1462 typedef
1463    struct {
1464       IRTemp    oldHi;  /* old value of *addr is written here */
1465       IRTemp    oldLo;
1466       IREndness end;    /* endianness of the data in memory */
1467       IRExpr*   addr;   /* store address */
1468       IRExpr*   expdHi; /* expected old value at *addr */
1469       IRExpr*   expdLo;
1470       IRExpr*   dataHi; /* new value for *addr */
1471       IRExpr*   dataLo;
1472    }
1473    IRCAS;
1474
1475 extern void ppIRCAS ( IRCAS* cas );
1476
1477 extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1478                         IREndness end, IRExpr* addr, 
1479                         IRExpr* expdHi, IRExpr* expdLo,
1480                         IRExpr* dataHi, IRExpr* dataLo );
1481
1482 extern IRCAS* deepCopyIRCAS ( IRCAS* );
1483
1484 /* ------------------ Statements ------------------ */
1485
1486 /* The different kinds of statements.  Their meaning is explained
1487    below in the comments for IRStmt.
1488
1489    Those marked META do not represent code, but rather extra
1490    information about the code.  These statements can be removed
1491    without affecting the functional behaviour of the code, however
1492    they are required by some IR consumers such as tools that
1493    instrument the code.
1494 */
1495
1496 typedef 
1497    enum {
1498       Ist_NoOp=0x19000,
1499       Ist_IMark,     /* META */
1500       Ist_AbiHint,   /* META */
1501       Ist_Put,
1502       Ist_PutI,
1503       Ist_WrTmp,
1504       Ist_Store,
1505       Ist_CAS,
1506       Ist_LLSC,
1507       Ist_Dirty,
1508       Ist_MBE,       /* META (maybe) */
1509       Ist_Exit
1510    } 
1511    IRStmtTag;
1512
1513 /* A statement.  Stored as a tagged union.  'tag' indicates what kind
1514    of expression this is.  'Ist' is the union that holds the fields.
1515    If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
1516    statement, and the fields can be accessed with
1517    'st.Ist.Store.<fieldname>'.
1518
1519    For each kind of statement, we show what it looks like when
1520    pretty-printed with ppIRStmt().
1521 */
1522 typedef
1523    struct _IRStmt {
1524       IRStmtTag tag;
1525       union {
1526          /* A no-op (usually resulting from IR optimisation).  Can be
1527             omitted without any effect.
1528
1529             ppIRStmt output: IR-NoOp
1530          */
1531          struct {
1532          } NoOp;
1533
1534          /* META: instruction mark.  Marks the start of the statements
1535             that represent a single machine instruction (the end of
1536             those statements is marked by the next IMark or the end of
1537             the IRSB).  Contains the address and length of the
1538             instruction.
1539
1540             ppIRStmt output: ------ IMark(<addr>, <len>) ------,
1541                          eg. ------ IMark(0x4000792, 5) ------,
1542          */
1543          struct {
1544             Addr64 addr;   /* instruction address */
1545             Int    len;    /* instruction length */
1546          } IMark;
1547
1548          /* META: An ABI hint, which says something about this
1549             platform's ABI.
1550
1551             At the moment, the only AbiHint is one which indicates
1552             that a given chunk of address space, [base .. base+len-1],
1553             has become undefined.  This is used on amd64-linux and
1554             some ppc variants to pass stack-redzoning hints to whoever
1555             wants to see them.  It also indicates the address of the
1556             next (dynamic) instruction that will be executed.  This is
1557             to help Memcheck to origin tracking.
1558
1559             ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
1560                          eg. ====== AbiHint(t1, 16, t2) ======
1561          */
1562          struct {
1563             IRExpr* base;     /* Start  of undefined chunk */
1564             Int     len;      /* Length of undefined chunk */
1565             IRExpr* nia;      /* Address of next (guest) insn */
1566          } AbiHint;
1567
1568          /* Write a guest register, at a fixed offset in the guest state.
1569             ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
1570          */
1571          struct {
1572             Int     offset;   /* Offset into the guest state */
1573             IRExpr* data;     /* The value to write */
1574          } Put;
1575
1576          /* Write a guest register, at a non-fixed offset in the guest
1577             state.  See the comment for GetI expressions for more
1578             information.
1579
1580             ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
1581                          eg. PUTI(64:8xF64)[t5,0] = t1
1582          */
1583          struct {
1584             IRRegArray* descr; /* Part of guest state treated as circular */
1585             IRExpr*     ix;    /* Variable part of index into array */
1586             Int         bias;  /* Constant offset part of index into array */
1587             IRExpr*     data;  /* The value to write */
1588          } PutI;
1589
1590          /* Assign a value to a temporary.  Note that SSA rules require
1591             each tmp is only assigned to once.  IR sanity checking will
1592             reject any block containing a temporary which is not assigned
1593             to exactly once.
1594
1595             ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
1596          */
1597          struct {
1598             IRTemp  tmp;   /* Temporary  (LHS of assignment) */
1599             IRExpr* data;  /* Expression (RHS of assignment) */
1600          } WrTmp;
1601
1602          /* Write a value to memory.  This is a normal store, not a
1603             Store-Conditional.  To represent a Store-Conditional,
1604             instead use IRStmt.LLSC.
1605             ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
1606          */
1607          struct {
1608             IREndness end;    /* Endianness of the store */
1609             IRExpr*   addr;   /* store address */
1610             IRExpr*   data;   /* value to write */
1611          } Store;
1612
1613          /* Do an atomic compare-and-swap operation.  Semantics are
1614             described above on a comment at the definition of IRCAS.
1615
1616             ppIRStmt output:
1617                t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
1618             eg
1619                t1 = CASle(t2 :: t3->Add32(t3,1))
1620                which denotes a 32-bit atomic increment 
1621                of a value at address t2
1622
1623             A double-element CAS may also be denoted, in which case <tmp>,
1624             <expected> and <new> are all pairs of items, separated by
1625             commas.
1626          */
1627          struct {
1628             IRCAS* details;
1629          } CAS;
1630
1631          /* Either Load-Linked or Store-Conditional, depending on
1632             STOREDATA.
1633
1634             If STOREDATA is NULL then this is a Load-Linked, meaning
1635             that data is loaded from memory as normal, but a
1636             'reservation' for the address is also lodged in the
1637             hardware.
1638
1639                result = Load-Linked(addr, end)
1640
1641             The data transfer type is the type of RESULT (I32, I64,
1642             etc).  ppIRStmt output:
1643
1644                result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
1645
1646             If STOREDATA is not NULL then this is a Store-Conditional,
1647             hence:
1648
1649                result = Store-Conditional(addr, storedata, end)
1650
1651             The data transfer type is the type of STOREDATA and RESULT
1652             has type Ity_I1. The store may fail or succeed depending
1653             on the state of a previously lodged reservation on this
1654             address.  RESULT is written 1 if the store succeeds and 0
1655             if it fails.  eg ppIRStmt output:
1656
1657                result = ( ST<end>-Cond(<addr>) = <storedata> )
1658                eg t3 = ( STbe-Cond(t1, t2) )
1659
1660             In all cases, the address must be naturally aligned for
1661             the transfer type -- any misaligned addresses should be
1662             caught by a dominating IR check and side exit.  This
1663             alignment restriction exists because on at least some
1664             LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
1665             misaligned addresses, and we have to actually generate
1666             stwcx. on the host, and we don't want it trapping on the
1667             host.
1668
1669             Summary of rules for transfer type:
1670               STOREDATA == NULL (LL):
1671                 transfer type = type of RESULT
1672               STOREDATA != NULL (SC):
1673                 transfer type = type of STOREDATA, and RESULT :: Ity_I1
1674          */
1675          struct {
1676             IREndness end;
1677             IRTemp    result;
1678             IRExpr*   addr;
1679             IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
1680          } LLSC;
1681
1682          /* Call (possibly conditionally) a C function that has side
1683             effects (ie. is "dirty").  See the comments above the
1684             IRDirty type declaration for more information.
1685
1686             ppIRStmt output:
1687                t<tmp> = DIRTY <guard> <effects> 
1688                   ::: <callee>(<args>)
1689             eg.
1690                t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
1691                      ::: foo{0x380035f4}(t2)
1692          */       
1693          struct {
1694             IRDirty* details;
1695          } Dirty;
1696
1697          /* A memory bus event - a fence, or acquisition/release of the
1698             hardware bus lock.  IR optimisation treats all these as fences
1699             across which no memory references may be moved.
1700             ppIRStmt output: MBusEvent-Fence,
1701                              MBusEvent-BusLock, MBusEvent-BusUnlock.
1702          */
1703          struct {
1704             IRMBusEvent event;
1705          } MBE;
1706
1707          /* Conditional exit from the middle of an IRSB.
1708             ppIRStmt output: if (<guard>) goto {<jk>} <dst>
1709                          eg. if (t69) goto {Boring} 0x4000AAA:I32
1710          */
1711          struct {
1712             IRExpr*    guard;    /* Conditional expression */
1713             IRJumpKind jk;       /* Jump kind */
1714             IRConst*   dst;      /* Jump target (constant only) */
1715          } Exit;
1716       } Ist;
1717    }
1718    IRStmt;
1719
1720 /* Statement constructors. */
1721 extern IRStmt* IRStmt_NoOp    ( void );
1722 extern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len );
1723 extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
1724 extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
1725 extern IRStmt* IRStmt_PutI    ( IRRegArray* descr, IRExpr* ix, Int bias, 
1726                                 IRExpr* data );
1727 extern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
1728 extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
1729 extern IRStmt* IRStmt_CAS     ( IRCAS* details );
1730 extern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
1731                                 IRExpr* addr, IRExpr* storedata );
1732 extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
1733 extern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
1734 extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
1735
1736 /* Deep-copy an IRStmt. */
1737 extern IRStmt* deepCopyIRStmt ( IRStmt* );
1738
1739 /* Pretty-print an IRStmt. */
1740 extern void ppIRStmt ( IRStmt* );
1741
1742
1743 /* ------------------ Basic Blocks ------------------ */
1744
1745 /* Type environments: a bunch of statements, expressions, etc, are
1746    incomplete without an environment indicating the type of each
1747    IRTemp.  So this provides one.  IR temporaries are really just
1748    unsigned ints and so this provides an array, 0 .. n_types_used-1 of
1749    them.
1750 */
1751 typedef
1752    struct {
1753       IRType* types;
1754       Int     types_size;
1755       Int     types_used;
1756    }
1757    IRTypeEnv;
1758
1759 /* Obtain a new IRTemp */
1760 extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
1761
1762 /* Deep-copy a type environment */
1763 extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
1764
1765 /* Pretty-print a type environment */
1766 extern void ppIRTypeEnv ( IRTypeEnv* );
1767
1768
1769 /* Code blocks, which in proper compiler terminology are superblocks
1770    (single entry, multiple exit code sequences) contain:
1771
1772    - A table giving a type for each temp (the "type environment")
1773    - An expandable array of statements
1774    - An expression of type 32 or 64 bits, depending on the
1775      guest's word size, indicating the next destination if the block 
1776      executes all the way to the end, without a side exit
1777    - An indication of any special actions (JumpKind) needed
1778      for this final jump.
1779    
1780    "IRSB" stands for "IR Super Block".
1781 */
1782 typedef
1783    struct {
1784       IRTypeEnv* tyenv;
1785       IRStmt**   stmts;
1786       Int        stmts_size;
1787       Int        stmts_used;
1788       IRExpr*    next;
1789       IRJumpKind jumpkind;
1790    }
1791    IRSB;
1792
1793 /* Allocate a new, uninitialised IRSB */
1794 extern IRSB* emptyIRSB ( void );
1795
1796 /* Deep-copy an IRSB */
1797 extern IRSB* deepCopyIRSB ( IRSB* );
1798
1799 /* Deep-copy an IRSB, except for the statements list, which set to be
1800    a new, empty, list of statements. */
1801 extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
1802
1803 /* Pretty-print an IRSB */
1804 extern void ppIRSB ( IRSB* );
1805
1806 /* Append an IRStmt to an IRSB */
1807 extern void addStmtToIRSB ( IRSB*, IRStmt* );
1808
1809
1810 /*---------------------------------------------------------------*/
1811 /*--- Helper functions for the IR                             ---*/
1812 /*---------------------------------------------------------------*/
1813
1814 /* For messing with IR type environments */
1815 extern IRTypeEnv* emptyIRTypeEnv  ( void );
1816
1817 /* What is the type of this expression? */
1818 extern IRType typeOfIRConst ( IRConst* );
1819 extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
1820 extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
1821
1822 /* Sanity check a BB of IR */
1823 extern void sanityCheckIRSB ( IRSB*  bb, 
1824                               HChar* caller,
1825                               Bool   require_flatness, 
1826                               IRType guest_word_size );
1827 extern Bool isFlatIRStmt ( IRStmt* );
1828
1829 /* Is this any value actually in the enumeration 'IRType' ? */
1830 extern Bool isPlausibleIRType ( IRType ty );
1831
1832 #endif /* ndef __LIBVEX_IR_H */
1833
1834
1835 /*---------------------------------------------------------------*/
1836 /*---                                             libvex_ir.h ---*/
1837 /*---------------------------------------------------------------*/