• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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       Iop_RoundF32toInt, /* F32 value to nearest integral value (still
643                             as F32) */
644 
645       /* --- guest ppc32/64 specifics, not mandated by 754. --- */
646 
647       /* Ternary operations, with rounding. */
648       /* Fused multiply-add/sub, with 112-bit intermediate
649 	 precision */
650       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
651             (computes arg2 * arg3 +/- arg4) */
652       Iop_MAddF64, Iop_MSubF64,
653 
654       /* Variants of the above which produce a 64-bit result but which
655          round their result to a IEEE float range first. */
656       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
657       Iop_MAddF64r32, Iop_MSubF64r32,
658 
659       /* :: F64 -> F64 */
660       Iop_Est5FRSqrt,    /* reciprocal square root estimate, 5 good bits */
661       Iop_RoundF64toF64_NEAREST, /* frin */
662       Iop_RoundF64toF64_NegINF,  /* frim */
663       Iop_RoundF64toF64_PosINF,  /* frip */
664       Iop_RoundF64toF64_ZERO,    /* friz */
665 
666       /* :: F64 -> F32 */
667       Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
668 
669       /* :: IRRoundingMode(I32) x F64 -> F64 */
670       Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
671       /* NB: pretty much the same as Iop_F64toF32, except no change
672          of type. */
673 
674       /* :: F64 -> I32 */
675       Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord)
676                        from FP result */
677 
678       /* ------------------ 32-bit SIMD Integer ------------------ */
679 
680       /* 16x2 add/sub, also signed/unsigned saturating variants */
681       Iop_Add16x2, Iop_Sub16x2,
682       Iop_QAdd16Sx2, Iop_QAdd16Ux2,
683       Iop_QSub16Sx2, Iop_QSub16Ux2,
684 
685       /* 16x2 signed/unsigned halving add/sub.  For each lane, these
686          compute bits 16:1 of (eg) sx(argL) + sx(argR),
687          or zx(argL) - zx(argR) etc. */
688       Iop_HAdd16Ux2, Iop_HAdd16Sx2,
689       Iop_HSub16Ux2, Iop_HSub16Sx2,
690 
691       /* 8x4 add/sub, also signed/unsigned saturating variants */
692       Iop_Add8x4, Iop_Sub8x4,
693       Iop_QAdd8Sx4, Iop_QAdd8Ux4,
694       Iop_QSub8Sx4, Iop_QSub8Ux4,
695 
696       /* 8x4 signed/unsigned halving add/sub.  For each lane, these
697          compute bits 8:1 of (eg) sx(argL) + sx(argR),
698          or zx(argL) - zx(argR) etc. */
699       Iop_HAdd8Ux4, Iop_HAdd8Sx4,
700       Iop_HSub8Ux4, Iop_HSub8Sx4,
701 
702       /* 8x4 sum of absolute unsigned differences. */
703       Iop_Sad8Ux4,
704 
705       /* MISC (vector integer cmp != 0) */
706       Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
707 
708       /* ------------------ 64-bit SIMD FP ------------------------ */
709 
710       /* Convertion to/from int */
711       Iop_I32UtoFx2,  Iop_I32StoFx2,    /* I32x4 -> F32x4 */
712       Iop_FtoI32Ux2_RZ,  Iop_FtoI32Sx2_RZ,    /* F32x4 -> I32x4 */
713       /* Fixed32 format is floating-point number with fixed number of fraction
714          bits. The number of fraction bits is passed as a second argument of
715          type I8. */
716       Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
717       Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
718 
719       /* Binary operations */
720       Iop_Max32Fx2,      Iop_Min32Fx2,
721       /* Pairwise Min and Max. See integer pairwise operations for more
722          details. */
723       Iop_PwMax32Fx2,    Iop_PwMin32Fx2,
724       /* Note: For the following compares, the arm front-end assumes a
725          nan in a lane of either argument returns zero for that lane. */
726       Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
727 
728       /* Vector Reciprocal Estimate finds an approximate reciprocal of each
729       element in the operand vector, and places the results in the destination
730       vector.  */
731       Iop_Recip32Fx2,
732 
733       /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
734          Note, that if one of the arguments is zero and another one is infinity
735          of arbitrary sign the result of the operation is 2.0. */
736       Iop_Recps32Fx2,
737 
738       /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
739          square root of each element in the operand vector. */
740       Iop_Rsqrte32Fx2,
741 
742       /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
743          Note, that of one of the arguments is zero and another one is infiinty
744          of arbitrary sign the result of the operation is 1.5. */
745       Iop_Rsqrts32Fx2,
746 
747       /* Unary */
748       Iop_Neg32Fx2, Iop_Abs32Fx2,
749 
750       /* ------------------ 64-bit SIMD Integer. ------------------ */
751 
752       /* MISC (vector integer cmp != 0) */
753       Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
754 
755       /* ADDITION (normal / unsigned sat / signed sat) */
756       Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
757       Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
758       Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
759 
760       /* PAIRWISE operations */
761       /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
762             [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
763       Iop_PwAdd8x8,  Iop_PwAdd16x4,  Iop_PwAdd32x2,
764       Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
765       Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
766       Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
767       Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
768       /* Longening variant is unary. The resulting vector contains two times
769          less elements than operand, but they are two times wider.
770          Example:
771             Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
772                where a+b and c+d are unsigned 32-bit values. */
773       Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
774       Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
775 
776       /* SUBTRACTION (normal / unsigned sat / signed sat) */
777       Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
778       Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
779       Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
780 
781       /* ABSOLUTE VALUE */
782       Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
783 
784       /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
785       Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
786       Iop_Mul32Fx2,
787       Iop_MulHi16Ux4,
788       Iop_MulHi16Sx4,
789       /* Plynomial multiplication treats it's arguments as coefficients of
790          polynoms over {0, 1}. */
791       Iop_PolynomialMul8x8,
792 
793       /* Vector Saturating Doubling Multiply Returning High Half and
794          Vector Saturating Rounding Doubling Multiply Returning High Half */
795       /* These IROp's multiply corresponding elements in two vectors, double
796          the results, and place the most significant half of the final results
797          in the destination vector. The results are truncated or rounded. If
798          any of the results overflow, they are saturated. */
799       Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
800       Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
801 
802       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
803       Iop_Avg8Ux8,
804       Iop_Avg16Ux4,
805 
806       /* MIN/MAX */
807       Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
808       Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
809       Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
810       Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
811 
812       /* COMPARISON */
813       Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
814       Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
815       Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
816 
817       /* COUNT ones / leading zeroes / leading sign bits (not including topmost
818          bit) */
819       Iop_Cnt8x8,
820       Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2,
821       Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2,
822 
823       /* VECTOR x VECTOR SHIFT / ROTATE */
824       Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
825       Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
826       Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
827       Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
828 
829       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
830       Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
831       Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
832       Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
833 
834       /* VECTOR x VECTOR SATURATING SHIFT */
835       Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
836       Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
837       /* VECTOR x INTEGER SATURATING SHIFT */
838       Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1,
839       Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1,
840       Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1,
841 
842       /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */
843       Iop_QNarrow16Ux4,
844       Iop_QNarrow16Sx4,
845       Iop_QNarrow32Sx2,
846 
847       /* INTERLEAVING */
848       /* Interleave lanes from low or high halves of
849          operands.  Most-significant result lane is from the left
850          arg. */
851       Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
852       Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
853       /* Interleave odd/even lanes of operands.  Most-significant result lane
854          is from the left arg.  Note that Interleave{Odd,Even}Lanes32x2 are
855          identical to Interleave{HI,LO}32x2 and so are omitted.*/
856       Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
857       Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
858 
859 
860       /* CONCATENATION -- build a new value by concatenating either
861          the even or odd lanes of both operands.  Note that
862          Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
863          and so are omitted. */
864       Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
865       Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
866 
867       /* GET / SET elements of VECTOR
868          GET is binop (I64, I8) -> I<elem_size>
869          SET is triop (I64, I8, I<elem_size>) -> I64 */
870       /* Note: the arm back-end handles only constant second argument */
871       Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
872       Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
873 
874       /* DUPLICATING -- copy value to all lanes */
875       Iop_Dup8x8,   Iop_Dup16x4,   Iop_Dup32x2,
876 
877       /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes
878          of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
879          result.
880          It is a triop: (I64, I64, I8) -> I64 */
881       /* Note: the arm back-end handles only constant third argumnet. */
882       Iop_Extract64,
883 
884       /* REVERSE the order of elements in each Half-words, Words,
885          Double-words */
886       /* Examples:
887             Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
888             Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
889             Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
890       Iop_Reverse16_8x8,
891       Iop_Reverse32_8x8, Iop_Reverse32_16x4,
892       Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2,
893 
894       /* PERMUTING -- copy src bytes to dst,
895          as indexed by control vector bytes:
896             for i in 0 .. 7 . result[i] = argL[ argR[i] ]
897          argR[i] values may only be in the range 0 .. 7, else behaviour
898          is undefined. */
899       Iop_Perm8x8,
900 
901       /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
902          See floating-point equiwalents for details. */
903       Iop_Recip32x2, Iop_Rsqrte32x2,
904 
905       /* ------------------ 128-bit SIMD FP. ------------------ */
906 
907       /* --- 32x4 vector FP --- */
908 
909       /* binary */
910       Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
911       Iop_Max32Fx4, Iop_Min32Fx4,
912       Iop_Add32Fx2, Iop_Sub32Fx2,
913       /* Note: For the following compares, the ppc and arm front-ends assume a
914          nan in a lane of either argument returns zero for that lane. */
915       Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
916       Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
917 
918       /* Vector Absolute */
919       Iop_Abs32Fx4,
920 
921       /* Pairwise Max and Min. See integer pairwise operations for details. */
922       Iop_PwMax32Fx4, Iop_PwMin32Fx4,
923 
924       /* unary */
925       Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
926       Iop_Neg32Fx4,
927 
928       /* Vector Reciprocal Estimate finds an approximate reciprocal of each
929       element in the operand vector, and places the results in the destination
930       vector.  */
931       Iop_Recip32Fx4,
932 
933       /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
934          Note, that if one of the arguments is zero and another one is infinity
935          of arbitrary sign the result of the operation is 2.0. */
936       Iop_Recps32Fx4,
937 
938       /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
939          square root of each element in the operand vector. */
940       Iop_Rsqrte32Fx4,
941 
942       /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
943          Note, that of one of the arguments is zero and another one is infiinty
944          of arbitrary sign the result of the operation is 1.5. */
945       Iop_Rsqrts32Fx4,
946 
947 
948       /* --- Int to/from FP conversion --- */
949       /* Unlike the standard fp conversions, these irops take no
950          rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
951          indicate the mode: {-inf, +inf, nearest, zero} respectively. */
952       Iop_I32UtoFx4,  Iop_I32StoFx4,       /* I32x4 -> F32x4       */
953       Iop_FtoI32Ux4_RZ,  Iop_FtoI32Sx4_RZ,    /* F32x4 -> I32x4       */
954       Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ,   /* F32x4 -> I32x4 (with saturation) */
955       Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
956       Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
957       /* Fixed32 format is floating-point number with fixed number of fraction
958          bits. The number of fraction bits is passed as a second argument of
959          type I8. */
960       Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
961       Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
962 
963       /* --- Single to/from half conversion --- */
964       Iop_F32toF16x4, Iop_F16toF32x4,         /* F32x4 <-> F16x4      */
965 
966       /* --- 32x4 lowest-lane-only scalar FP --- */
967 
968       /* In binary cases, upper 3/4 is copied from first operand.  In
969          unary cases, upper 3/4 is copied from the operand. */
970 
971       /* binary */
972       Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
973       Iop_Max32F0x4, Iop_Min32F0x4,
974       Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
975 
976       /* unary */
977       Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
978 
979       /* --- 64x2 vector FP --- */
980 
981       /* binary */
982       Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
983       Iop_Max64Fx2, Iop_Min64Fx2,
984       Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
985 
986       /* unary */
987       Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
988 
989       /* --- 64x2 lowest-lane-only scalar FP --- */
990 
991       /* In binary cases, upper half is copied from first operand.  In
992          unary cases, upper half is copied from the operand. */
993 
994       /* binary */
995       Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
996       Iop_Max64F0x2, Iop_Min64F0x2,
997       Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
998 
999       /* unary */
1000       Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
1001 
1002       /* --- pack / unpack --- */
1003 
1004       /* 64 <-> 128 bit vector */
1005       Iop_V128to64,     // :: V128 -> I64, low half
1006       Iop_V128HIto64,   // :: V128 -> I64, high half
1007       Iop_64HLtoV128,   // :: (I64,I64) -> V128
1008 
1009       Iop_64UtoV128,
1010       Iop_SetV128lo64,
1011 
1012       /* 32 <-> 128 bit vector */
1013       Iop_32UtoV128,
1014       Iop_V128to32,     // :: V128 -> I32, lowest lane
1015       Iop_SetV128lo32,  // :: (V128,I32) -> V128
1016 
1017       /* ------------------ 128-bit SIMD Integer. ------------------ */
1018 
1019       /* BITWISE OPS */
1020       Iop_NotV128,
1021       Iop_AndV128, Iop_OrV128, Iop_XorV128,
1022 
1023       /* VECTOR SHIFT (shift amt :: Ity_I8) */
1024       Iop_ShlV128, Iop_ShrV128,
1025 
1026       /* MISC (vector integer cmp != 0) */
1027       Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
1028 
1029       /* ADDITION (normal / unsigned sat / signed sat) */
1030       Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,   Iop_Add64x2,
1031       Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1032       Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
1033 
1034       /* SUBTRACTION (normal / unsigned sat / signed sat) */
1035       Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,   Iop_Sub64x2,
1036       Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1037       Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
1038 
1039       /* MULTIPLICATION (normal / high half of signed/unsigned) */
1040       Iop_Mul8x16,  Iop_Mul16x8,    Iop_Mul32x4,
1041                     Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1042                     Iop_MulHi16Sx8, Iop_MulHi32Sx4,
1043       /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
1044       Iop_MullEven8Ux16, Iop_MullEven16Ux8,
1045       Iop_MullEven8Sx16, Iop_MullEven16Sx8,
1046       /* FIXME: document these */
1047       Iop_Mull8Ux8, Iop_Mull8Sx8,
1048       Iop_Mull16Ux4, Iop_Mull16Sx4,
1049       Iop_Mull32Ux2, Iop_Mull32Sx2,
1050       /* Vector Saturating Doubling Multiply Returning High Half and
1051          Vector Saturating Rounding Doubling Multiply Returning High Half */
1052       /* These IROp's multiply corresponding elements in two vectors, double
1053          the results, and place the most significant half of the final results
1054          in the destination vector. The results are truncated or rounded. If
1055          any of the results overflow, they are saturated. */
1056       Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4,
1057       Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4,
1058       /* Doubling saturating multiplication (long) (I64, I64) -> V128 */
1059       Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2,
1060       /* Plynomial multiplication treats it's arguments as coefficients of
1061          polynoms over {0, 1}. */
1062       Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1063       Iop_PolynomialMull8x8, /*   (I64, I64) -> V128 */
1064 
1065       /* PAIRWISE operations */
1066       /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1067             [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1068       Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1069       Iop_PwAdd32Fx2,
1070       /* Longening variant is unary. The resulting vector contains two times
1071          less elements than operand, but they are two times wider.
1072          Example:
1073             Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1074                where a+b and c+d are unsigned 32-bit values. */
1075       Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1076       Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1077 
1078       /* ABSOLUTE VALUE */
1079       Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4,
1080 
1081       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
1082       Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1083       Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
1084 
1085       /* MIN/MAX */
1086       Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
1087       Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
1088       Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
1089       Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
1090 
1091       /* COMPARISON */
1092       Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,
1093       Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
1094       Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
1095 
1096       /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1097          bit) */
1098       Iop_Cnt8x16,
1099       Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4,
1100       Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4,
1101 
1102       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1103       Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1104       Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
1105       Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
1106 
1107       /* VECTOR x VECTOR SHIFT / ROTATE */
1108       Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1109       Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1110       Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1111       Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
1112       Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
1113 
1114       /* VECTOR x VECTOR SATURATING SHIFT */
1115       Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1116       Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1117       /* VECTOR x INTEGER SATURATING SHIFT */
1118       Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2,
1119       Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2,
1120       Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2,
1121 
1122       /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */
1123       /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */
1124       Iop_QNarrow16Ux8, Iop_QNarrow32Ux4,
1125       Iop_QNarrow16Sx8, Iop_QNarrow32Sx4,
1126       Iop_Narrow16x8, Iop_Narrow32x4,
1127       /* Shortening V128->I64, lo half from each element */
1128       Iop_Shorten16x8, Iop_Shorten32x4, Iop_Shorten64x2,
1129       /* Saturating shortening from signed source to signed/unsigned destination */
1130       Iop_QShortenS16Sx8, Iop_QShortenS32Sx4, Iop_QShortenS64Sx2,
1131       Iop_QShortenU16Sx8, Iop_QShortenU32Sx4, Iop_QShortenU64Sx2,
1132       /* Saturating shortening from unsigned source to unsigned destination */
1133       Iop_QShortenU16Ux8, Iop_QShortenU32Ux4, Iop_QShortenU64Ux2,
1134 
1135       /* WIDENING */
1136       /* Longening --- sign or zero extends each element of the argument
1137          vector to the twice original size. The resulting vector consists of
1138          the same number of elements but each element and the vector itself
1139          are two times wider.
1140          All operations are I64->V128.
1141          Example
1142             Iop_Longen32Sx2( [a, b] ) = [c, d]
1143                where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
1144       Iop_Longen8Ux8, Iop_Longen16Ux4, Iop_Longen32Ux2,
1145       Iop_Longen8Sx8, Iop_Longen16Sx4, Iop_Longen32Sx2,
1146 
1147       /* INTERLEAVING */
1148       /* Interleave lanes from low or high halves of
1149          operands.  Most-significant result lane is from the left
1150          arg. */
1151       Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1152       Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
1153       Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
1154       Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
1155       /* Interleave odd/even lanes of operands.  Most-significant result lane
1156          is from the left arg. */
1157       Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1158       Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1159       Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1160 
1161       /* CONCATENATION -- build a new value by concatenating either
1162          the even or odd lanes of both operands. */
1163       Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1164       Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1165 
1166       /* GET elements of VECTOR
1167          GET is binop (V128, I8) -> I<elem_size> */
1168       /* Note: the arm back-end handles only constant second argument. */
1169       Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
1170 
1171       /* DUPLICATING -- copy value to all lanes */
1172       Iop_Dup8x16,   Iop_Dup16x8,   Iop_Dup32x4,
1173 
1174       /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes
1175          of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
1176          result.
1177          It is a triop: (V128, V128, I8) -> V128 */
1178       /* Note: the ARM back end handles only constant arg3 in this operation. */
1179       Iop_ExtractV128,
1180 
1181       /* REVERSE the order of elements in each Half-words, Words,
1182          Double-words */
1183       /* Examples:
1184             Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1185             Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */
1186       Iop_Reverse16_8x16,
1187       Iop_Reverse32_8x16, Iop_Reverse32_16x8,
1188       Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4,
1189 
1190       /* PERMUTING -- copy src bytes to dst,
1191          as indexed by control vector bytes:
1192             for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1193          argR[i] values may only be in the range 0 .. 15, else behaviour
1194          is undefined. */
1195       Iop_Perm8x16,
1196 
1197       /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1198          See floating-point equiwalents for details. */
1199       Iop_Recip32x4, Iop_Rsqrte32x4
1200    }
1201    IROp;
1202 
1203 /* Pretty-print an op. */
1204 extern void ppIROp ( IROp );
1205 
1206 
1207 /* Encoding of IEEE754-specified rounding modes.  This is the same as
1208    the encoding used by Intel IA32 to indicate x87 rounding mode.
1209    Note, various front and back ends rely on the actual numerical
1210    values of these, so do not change them. */
1211 typedef
1212    enum {
1213       Irrm_NEAREST = 0,
1214       Irrm_NegINF  = 1,
1215       Irrm_PosINF  = 2,
1216       Irrm_ZERO    = 3
1217    }
1218    IRRoundingMode;
1219 
1220 /* Floating point comparison result values, as created by Iop_CmpF64.
1221    This is also derived from what IA32 does. */
1222 typedef
1223    enum {
1224       Ircr_UN = 0x45,
1225       Ircr_LT = 0x01,
1226       Ircr_GT = 0x00,
1227       Ircr_EQ = 0x40
1228    }
1229    IRCmpF64Result;
1230 
1231 
1232 /* ------------------ Expressions ------------------ */
1233 
1234 /* The different kinds of expressions.  Their meaning is explained below
1235    in the comments for IRExpr. */
1236 typedef
1237    enum {
1238       Iex_Binder=0x15000,
1239       Iex_Get,
1240       Iex_GetI,
1241       Iex_RdTmp,
1242       Iex_Qop,
1243       Iex_Triop,
1244       Iex_Binop,
1245       Iex_Unop,
1246       Iex_Load,
1247       Iex_Const,
1248       Iex_Mux0X,
1249       Iex_CCall
1250    }
1251    IRExprTag;
1252 
1253 /* An expression.  Stored as a tagged union.  'tag' indicates what kind
1254    of expression this is.  'Iex' is the union that holds the fields.  If
1255    an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1256    expression, and the fields can be accessed with
1257    'e.Iex.Load.<fieldname>'.
1258 
1259    For each kind of expression, we show what it looks like when
1260    pretty-printed with ppIRExpr().
1261 */
1262 typedef
1263    struct _IRExpr
1264    IRExpr;
1265 
1266 struct _IRExpr {
1267    IRExprTag tag;
1268    union {
1269       /* Used only in pattern matching within Vex.  Should not be seen
1270          outside of Vex. */
1271       struct {
1272          Int binder;
1273       } Binder;
1274 
1275       /* Read a guest register, at a fixed offset in the guest state.
1276          ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1277       */
1278       struct {
1279          Int    offset;    /* Offset into the guest state */
1280          IRType ty;        /* Type of the value being read */
1281       } Get;
1282 
1283       /* Read a guest register at a non-fixed offset in the guest
1284          state.  This allows circular indexing into parts of the guest
1285          state, which is essential for modelling situations where the
1286          identity of guest registers is not known until run time.  One
1287          example is the x87 FP register stack.
1288 
1289          The part of the guest state to be treated as a circular array
1290          is described in the IRRegArray 'descr' field.  It holds the
1291          offset of the first element in the array, the type of each
1292          element, and the number of elements.
1293 
1294          The array index is indicated rather indirectly, in a way
1295          which makes optimisation easy: as the sum of variable part
1296          (the 'ix' field) and a constant offset (the 'bias' field).
1297 
1298          Since the indexing is circular, the actual array index to use
1299          is computed as (ix + bias) % num-of-elems-in-the-array.
1300 
1301          Here's an example.  The description
1302 
1303             (96:8xF64)[t39,-7]
1304 
1305          describes an array of 8 F64-typed values, the
1306          guest-state-offset of the first being 96.  This array is
1307          being indexed at (t39 - 7) % 8.
1308 
1309          It is important to get the array size/type exactly correct
1310          since IR optimisation looks closely at such info in order to
1311          establish aliasing/non-aliasing between seperate GetI and
1312          PutI events, which is used to establish when they can be
1313          reordered, etc.  Putting incorrect info in will lead to
1314          obscure IR optimisation bugs.
1315 
1316             ppIRExpr output: GETI<descr>[<ix>,<bias]
1317                          eg. GETI(128:8xI8)[t1,0]
1318       */
1319       struct {
1320          IRRegArray* descr; /* Part of guest state treated as circular */
1321          IRExpr*     ix;    /* Variable part of index into array */
1322          Int         bias;  /* Constant offset part of index into array */
1323       } GetI;
1324 
1325       /* The value held by a temporary.
1326          ppIRExpr output: t<tmp>, eg. t1
1327       */
1328       struct {
1329          IRTemp tmp;       /* The temporary number */
1330       } RdTmp;
1331 
1332       /* A quaternary operation.
1333          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1334                       eg. MAddF64r32(t1, t2, t3, t4)
1335       */
1336       struct {
1337          IROp op;          /* op-code   */
1338          IRExpr* arg1;     /* operand 1 */
1339          IRExpr* arg2;     /* operand 2 */
1340          IRExpr* arg3;     /* operand 3 */
1341          IRExpr* arg4;     /* operand 4 */
1342       } Qop;
1343 
1344       /* A ternary operation.
1345          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1346                       eg. MulF64(1, 2.0, 3.0)
1347       */
1348       struct {
1349          IROp op;          /* op-code   */
1350          IRExpr* arg1;     /* operand 1 */
1351          IRExpr* arg2;     /* operand 2 */
1352          IRExpr* arg3;     /* operand 3 */
1353       } Triop;
1354 
1355       /* A binary operation.
1356          ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1357       */
1358       struct {
1359          IROp op;          /* op-code   */
1360          IRExpr* arg1;     /* operand 1 */
1361          IRExpr* arg2;     /* operand 2 */
1362       } Binop;
1363 
1364       /* A unary operation.
1365          ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1366       */
1367       struct {
1368          IROp    op;       /* op-code */
1369          IRExpr* arg;      /* operand */
1370       } Unop;
1371 
1372       /* A load from memory -- a normal load, not a load-linked.
1373          Load-Linkeds (and Store-Conditionals) are instead represented
1374          by IRStmt.LLSC since Load-Linkeds have side effects and so
1375          are not semantically valid IRExpr's.
1376          ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1377       */
1378       struct {
1379          IREndness end;    /* Endian-ness of the load */
1380          IRType    ty;     /* Type of the loaded value */
1381          IRExpr*   addr;   /* Address being loaded from */
1382       } Load;
1383 
1384       /* A constant-valued expression.
1385          ppIRExpr output: <con>, eg. 0x4:I32
1386       */
1387       struct {
1388          IRConst* con;     /* The constant itself */
1389       } Const;
1390 
1391       /* A call to a pure (no side-effects) helper C function.
1392 
1393          With the 'cee' field, 'name' is the function's name.  It is
1394          only used for pretty-printing purposes.  The address to call
1395          (host address, of course) is stored in the 'addr' field
1396          inside 'cee'.
1397 
1398          The 'args' field is a NULL-terminated array of arguments.
1399          The stated return IRType, and the implied argument types,
1400          must match that of the function being called well enough so
1401          that the back end can actually generate correct code for the
1402          call.
1403 
1404          The called function **must** satisfy the following:
1405 
1406          * no side effects -- must be a pure function, the result of
1407            which depends only on the passed parameters.
1408 
1409          * it may not look at, nor modify, any of the guest state
1410            since that would hide guest state transitions from
1411            instrumenters
1412 
1413          * it may not access guest memory, since that would hide
1414            guest memory transactions from the instrumenters
1415 
1416          This is restrictive, but makes the semantics clean, and does
1417          not interfere with IR optimisation.
1418 
1419          If you want to call a helper which can mess with guest state
1420          and/or memory, instead use Ist_Dirty.  This is a lot more
1421          flexible, but you have to give a bunch of details about what
1422          the helper does (and you better be telling the truth,
1423          otherwise any derived instrumentation will be wrong).  Also
1424          Ist_Dirty inhibits various IR optimisations and so can cause
1425          quite poor code to be generated.  Try to avoid it.
1426 
1427          ppIRExpr output: <cee>(<args>):<retty>
1428                       eg. foo{0x80489304}(t1, t2):I32
1429       */
1430       struct {
1431          IRCallee* cee;    /* Function to call. */
1432          IRType    retty;  /* Type of return value. */
1433          IRExpr**  args;   /* Vector of argument expressions. */
1434       }  CCall;
1435 
1436       /* A ternary if-then-else operator.  It returns expr0 if cond is
1437          zero, exprX otherwise.  Note that it is STRICT, ie. both
1438          expr0 and exprX are evaluated in all cases.
1439 
1440          ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1441                          eg. Mux0X(t6,t7,t8)
1442       */
1443       struct {
1444          IRExpr* cond;     /* Condition */
1445          IRExpr* expr0;    /* True expression */
1446          IRExpr* exprX;    /* False expression */
1447       } Mux0X;
1448    } Iex;
1449 };
1450 
1451 /* Expression constructors. */
1452 extern IRExpr* IRExpr_Binder ( Int binder );
1453 extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
1454 extern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
1455 extern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
1456 extern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2,
1457                                         IRExpr* arg3, IRExpr* arg4 );
1458 extern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1,
1459                                         IRExpr* arg2, IRExpr* arg3 );
1460 extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1461 extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
1462 extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
1463 extern IRExpr* IRExpr_Const  ( IRConst* con );
1464 extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
1465 extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
1466 
1467 /* Deep-copy an IRExpr. */
1468 extern IRExpr* deepCopyIRExpr ( IRExpr* );
1469 
1470 /* Pretty-print an IRExpr. */
1471 extern void ppIRExpr ( IRExpr* );
1472 
1473 /* NULL-terminated IRExpr vector constructors, suitable for
1474    use as arg lists in clean/dirty helper calls. */
1475 extern IRExpr** mkIRExprVec_0 ( void );
1476 extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1477 extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1478 extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1479 extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
1480 extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1481                                 IRExpr* );
1482 extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1483                                 IRExpr*, IRExpr* );
1484 extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1485                                 IRExpr*, IRExpr*, IRExpr* );
1486 extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1487                                 IRExpr*, IRExpr*, IRExpr*, IRExpr*);
1488 
1489 /* IRExpr copiers:
1490    - shallowCopy: shallow-copy (ie. create a new vector that shares the
1491      elements with the original).
1492    - deepCopy: deep-copy (ie. create a completely new vector). */
1493 extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1494 extern IRExpr** deepCopyIRExprVec ( IRExpr** );
1495 
1496 /* Make a constant expression from the given host word taking into
1497    account (of course) the host word size. */
1498 extern IRExpr* mkIRExpr_HWord ( HWord );
1499 
1500 /* Convenience function for constructing clean helper calls. */
1501 extern
1502 IRExpr* mkIRExprCCall ( IRType retty,
1503                         Int regparms, HChar* name, void* addr,
1504                         IRExpr** args );
1505 
1506 
1507 /* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1508  * Iex_Const). */
isIRAtom(IRExpr * e)1509 static inline Bool isIRAtom ( IRExpr* e ) {
1510    return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
1511 }
1512 
1513 /* Are these two IR atoms identical?  Causes an assertion
1514    failure if they are passed non-atoms. */
1515 extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1516 
1517 
1518 /* ------------------ Jump kinds ------------------ */
1519 
1520 /* This describes hints which can be passed to the dispatcher at guest
1521    control-flow transfer points.
1522 
1523    Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1524    guest_TISTART and guest_TILEN, which specify the start and length
1525    of the region to be invalidated.  These are both the size of a
1526    guest word.  It is the responsibility of the relevant toIR.c to
1527    ensure that these are filled in with suitable values before issuing
1528    a jump of kind Ijk_TInval.
1529 
1530    Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
1531    pseudo-register guest_EMWARN, which is 32-bits regardless of the
1532    host or guest word size.  That register should be made to hold an
1533    EmWarn_* value to indicate the reason for the exit.
1534 
1535    In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1536    cannot continue) and so the jump destination can be anything.
1537 
1538    Re Ijk_Sys_ (syscall jumps): the guest state must have a
1539    pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1540    word.  Front ends should set this to be the IP at the most recently
1541    executed kernel-entering (system call) instruction.  This makes it
1542    very much easier (viz, actually possible at all) to back up the
1543    guest to restart a syscall that has been interrupted by a signal.
1544 */
1545 typedef
1546    enum {
1547       Ijk_Boring=0x16000, /* not interesting; just goto next */
1548       Ijk_Call,           /* guest is doing a call */
1549       Ijk_Ret,            /* guest is doing a return */
1550       Ijk_ClientReq,      /* do guest client req before continuing */
1551       Ijk_Yield,          /* client is yielding to thread scheduler */
1552       Ijk_YieldNoRedir,   /* client is yielding to thread scheduler AND jump to
1553                              un-redirected guest addr */
1554       Ijk_EmWarn,         /* report emulation warning before continuing */
1555       Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
1556       Ijk_NoDecode,       /* next instruction cannot be decoded */
1557       Ijk_MapFail,        /* Vex-provided address translation failed */
1558       Ijk_TInval,         /* Invalidate translations before continuing. */
1559       Ijk_NoRedir,        /* Jump to un-redirected guest addr */
1560       Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
1561       Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
1562       Ijk_SigBUS,         /* current instruction synths SIGBUS */
1563       /* Unfortunately, various guest-dependent syscall kinds.  They
1564 	 all mean: do a syscall before continuing. */
1565       Ijk_Sys_syscall,    /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
1566       Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
1567       Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
1568       Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
1569       Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
1570       Ijk_Sys_sysenter   /* x86 'sysenter'.  guest_EIP becomes
1571                              invalid at the point this happens. */
1572    }
1573    IRJumpKind;
1574 
1575 extern void ppIRJumpKind ( IRJumpKind );
1576 
1577 
1578 /* ------------------ Dirty helper calls ------------------ */
1579 
1580 /* A dirty call is a flexible mechanism for calling (possibly
1581    conditionally) a helper function or procedure.  The helper function
1582    may read, write or modify client memory, and may read, write or
1583    modify client state.  It can take arguments and optionally return a
1584    value.  It may return different results and/or do different things
1585    when called repeatedly with the same arguments, by means of storing
1586    private state.
1587 
1588    If a value is returned, it is assigned to the nominated return
1589    temporary.
1590 
1591    Dirty calls are statements rather than expressions for obvious
1592    reasons.  If a dirty call is marked as writing guest state, any
1593    values derived from the written parts of the guest state are
1594    invalid.  Similarly, if the dirty call is stated as writing
1595    memory, any loaded values are invalidated by it.
1596 
1597    In order that instrumentation is possible, the call must state, and
1598    state correctly:
1599 
1600    * whether it reads, writes or modifies memory, and if so where
1601      (only one chunk can be stated)
1602 
1603    * whether it reads, writes or modifies guest state, and if so which
1604      pieces (several pieces may be stated, and currently their extents
1605      must be known at translation-time).
1606 
1607    Normally, code is generated to pass just the args to the helper.
1608    However, if .needsBBP is set, then an extra first argument is
1609    passed, which is the baseblock pointer, so that the callee can
1610    access the guest state.  It is invalid for .nFxState to be zero
1611    but .needsBBP to be True, since .nFxState==0 is a claim that the
1612    call does not access guest state.
1613 
1614    IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
1615    arguments are evaluated REGARDLESS of the guard value.  It is
1616    unspecified the relative order of arg evaluation and guard
1617    evaluation.
1618 */
1619 
1620 #define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
1621 
1622 /* Effects on resources (eg. registers, memory locations) */
1623 typedef
1624    enum {
1625       Ifx_None = 0x17000,   /* no effect */
1626       Ifx_Read,             /* reads the resource */
1627       Ifx_Write,            /* writes the resource */
1628       Ifx_Modify,           /* modifies the resource */
1629    }
1630    IREffect;
1631 
1632 /* Pretty-print an IREffect */
1633 extern void ppIREffect ( IREffect );
1634 
1635 
1636 typedef
1637    struct {
1638       /* What to call, and details of args/results */
1639       IRCallee* cee;    /* where to call */
1640       IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
1641       IRExpr**  args;   /* arg list, ends in NULL */
1642       IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
1643 
1644       /* Mem effects; we allow only one R/W/M region to be stated */
1645       IREffect  mFx;    /* indicates memory effects, if any */
1646       IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
1647       Int       mSize;  /* of access, or zero if mFx==Ifx_None */
1648 
1649       /* Guest state effects; up to N allowed */
1650       Bool needsBBP; /* True => also pass guest state ptr to callee */
1651       Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
1652       struct {
1653          IREffect fx;   /* read, write or modify?  Ifx_None is invalid. */
1654          Int      offset;
1655          Int      size;
1656       } fxState[VEX_N_FXSTATE];
1657    }
1658    IRDirty;
1659 
1660 /* Pretty-print a dirty call */
1661 extern void     ppIRDirty ( IRDirty* );
1662 
1663 /* Allocate an uninitialised dirty call */
1664 extern IRDirty* emptyIRDirty ( void );
1665 
1666 /* Deep-copy a dirty call */
1667 extern IRDirty* deepCopyIRDirty ( IRDirty* );
1668 
1669 /* A handy function which takes some of the tedium out of constructing
1670    dirty helper calls.  The called function impliedly does not return
1671    any value and has a constant-True guard.  The call is marked as
1672    accessing neither guest state nor memory (hence the "unsafe"
1673    designation) -- you can change this marking later if need be.  A
1674    suitable IRCallee is constructed from the supplied bits. */
1675 extern
1676 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
1677                              IRExpr** args );
1678 
1679 /* Similarly, make a zero-annotation dirty call which returns a value,
1680    and assign that to the given temp. */
1681 extern
1682 IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1683                              Int regparms, HChar* name, void* addr,
1684                              IRExpr** args );
1685 
1686 
1687 /* --------------- Memory Bus Events --------------- */
1688 
1689 typedef
1690    enum {
1691       Imbe_Fence=0x18000,
1692    }
1693    IRMBusEvent;
1694 
1695 extern void ppIRMBusEvent ( IRMBusEvent );
1696 
1697 
1698 /* --------------- Compare and Swap --------------- */
1699 
1700 /* This denotes an atomic compare and swap operation, either
1701    a single-element one or a double-element one.
1702 
1703    In the single-element case:
1704 
1705      .addr is the memory address.
1706      .end  is the endianness with which memory is accessed
1707 
1708      If .addr contains the same value as .expdLo, then .dataLo is
1709      written there, else there is no write.  In both cases, the
1710      original value at .addr is copied into .oldLo.
1711 
1712      Types: .expdLo, .dataLo and .oldLo must all have the same type.
1713      It may be any integral type, viz: I8, I16, I32 or, for 64-bit
1714      guests, I64.
1715 
1716      .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
1717      be NULL.
1718 
1719    In the double-element case:
1720 
1721      .addr is the memory address.
1722      .end  is the endianness with which memory is accessed
1723 
1724      The operation is the same:
1725 
1726      If .addr contains the same value as .expdHi:.expdLo, then
1727      .dataHi:.dataLo is written there, else there is no write.  In
1728      both cases the original value at .addr is copied into
1729      .oldHi:.oldLo.
1730 
1731      Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
1732      all have the same type, which may be any integral type, viz: I8,
1733      I16, I32 or, for 64-bit guests, I64.
1734 
1735      The double-element case is complicated by the issue of
1736      endianness.  In all cases, the two elements are understood to be
1737      located adjacently in memory, starting at the address .addr.
1738 
1739        If .end is Iend_LE, then the .xxxLo component is at the lower
1740        address and the .xxxHi component is at the higher address, and
1741        each component is itself stored little-endianly.
1742 
1743        If .end is Iend_BE, then the .xxxHi component is at the lower
1744        address and the .xxxLo component is at the higher address, and
1745        each component is itself stored big-endianly.
1746 
1747    This allows representing more cases than most architectures can
1748    handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
1749 
1750    How to know if the CAS succeeded?
1751 
1752    * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
1753      then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
1754      stored at .addr, and the original value there was .oldLo (resp
1755      .oldHi:.oldLo).
1756 
1757    * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
1758      then the CAS failed, and the original value at .addr was .oldLo
1759      (resp. .oldHi:.oldLo).
1760 
1761    Hence it is easy to know whether or not the CAS succeeded.
1762 */
1763 typedef
1764    struct {
1765       IRTemp    oldHi;  /* old value of *addr is written here */
1766       IRTemp    oldLo;
1767       IREndness end;    /* endianness of the data in memory */
1768       IRExpr*   addr;   /* store address */
1769       IRExpr*   expdHi; /* expected old value at *addr */
1770       IRExpr*   expdLo;
1771       IRExpr*   dataHi; /* new value for *addr */
1772       IRExpr*   dataLo;
1773    }
1774    IRCAS;
1775 
1776 extern void ppIRCAS ( IRCAS* cas );
1777 
1778 extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1779                         IREndness end, IRExpr* addr,
1780                         IRExpr* expdHi, IRExpr* expdLo,
1781                         IRExpr* dataHi, IRExpr* dataLo );
1782 
1783 extern IRCAS* deepCopyIRCAS ( IRCAS* );
1784 
1785 /* ------------------ Statements ------------------ */
1786 
1787 /* The different kinds of statements.  Their meaning is explained
1788    below in the comments for IRStmt.
1789 
1790    Those marked META do not represent code, but rather extra
1791    information about the code.  These statements can be removed
1792    without affecting the functional behaviour of the code, however
1793    they are required by some IR consumers such as tools that
1794    instrument the code.
1795 */
1796 
1797 typedef
1798    enum {
1799       Ist_NoOp=0x19000,
1800       Ist_IMark,     /* META */
1801       Ist_AbiHint,   /* META */
1802       Ist_Put,
1803       Ist_PutI,
1804       Ist_WrTmp,
1805       Ist_Store,
1806       Ist_CAS,
1807       Ist_LLSC,
1808       Ist_Dirty,
1809       Ist_MBE,       /* META (maybe) */
1810       Ist_Exit
1811    }
1812    IRStmtTag;
1813 
1814 /* A statement.  Stored as a tagged union.  'tag' indicates what kind
1815    of expression this is.  'Ist' is the union that holds the fields.
1816    If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
1817    statement, and the fields can be accessed with
1818    'st.Ist.Store.<fieldname>'.
1819 
1820    For each kind of statement, we show what it looks like when
1821    pretty-printed with ppIRStmt().
1822 */
1823 typedef
1824    struct _IRStmt {
1825       IRStmtTag tag;
1826       union {
1827          /* A no-op (usually resulting from IR optimisation).  Can be
1828             omitted without any effect.
1829 
1830             ppIRStmt output: IR-NoOp
1831          */
1832          struct {
1833 	 } NoOp;
1834 
1835          /* META: instruction mark.  Marks the start of the statements
1836             that represent a single machine instruction (the end of
1837             those statements is marked by the next IMark or the end of
1838             the IRSB).  Contains the address and length of the
1839             instruction.
1840 
1841             ppIRStmt output: ------ IMark(<addr>, <len>) ------,
1842                          eg. ------ IMark(0x4000792, 5) ------,
1843          */
1844          struct {
1845             Addr64 addr;   /* instruction address */
1846             Int    len;    /* instruction length */
1847          } IMark;
1848 
1849          /* META: An ABI hint, which says something about this
1850             platform's ABI.
1851 
1852             At the moment, the only AbiHint is one which indicates
1853             that a given chunk of address space, [base .. base+len-1],
1854             has become undefined.  This is used on amd64-linux and
1855             some ppc variants to pass stack-redzoning hints to whoever
1856             wants to see them.  It also indicates the address of the
1857             next (dynamic) instruction that will be executed.  This is
1858             to help Memcheck to origin tracking.
1859 
1860             ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
1861                          eg. ====== AbiHint(t1, 16, t2) ======
1862          */
1863          struct {
1864             IRExpr* base;     /* Start  of undefined chunk */
1865             Int     len;      /* Length of undefined chunk */
1866             IRExpr* nia;      /* Address of next (guest) insn */
1867          } AbiHint;
1868 
1869          /* Write a guest register, at a fixed offset in the guest state.
1870             ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
1871          */
1872          struct {
1873             Int     offset;   /* Offset into the guest state */
1874             IRExpr* data;     /* The value to write */
1875          } Put;
1876 
1877          /* Write a guest register, at a non-fixed offset in the guest
1878             state.  See the comment for GetI expressions for more
1879             information.
1880 
1881             ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
1882                          eg. PUTI(64:8xF64)[t5,0] = t1
1883          */
1884          struct {
1885             IRRegArray* descr; /* Part of guest state treated as circular */
1886             IRExpr*     ix;    /* Variable part of index into array */
1887             Int         bias;  /* Constant offset part of index into array */
1888             IRExpr*     data;  /* The value to write */
1889          } PutI;
1890 
1891          /* Assign a value to a temporary.  Note that SSA rules require
1892             each tmp is only assigned to once.  IR sanity checking will
1893             reject any block containing a temporary which is not assigned
1894             to exactly once.
1895 
1896             ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
1897          */
1898          struct {
1899             IRTemp  tmp;   /* Temporary  (LHS of assignment) */
1900             IRExpr* data;  /* Expression (RHS of assignment) */
1901          } WrTmp;
1902 
1903          /* Write a value to memory.  This is a normal store, not a
1904             Store-Conditional.  To represent a Store-Conditional,
1905             instead use IRStmt.LLSC.
1906             ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
1907          */
1908          struct {
1909             IREndness end;    /* Endianness of the store */
1910             IRExpr*   addr;   /* store address */
1911             IRExpr*   data;   /* value to write */
1912          } Store;
1913 
1914          /* Do an atomic compare-and-swap operation.  Semantics are
1915             described above on a comment at the definition of IRCAS.
1916 
1917             ppIRStmt output:
1918                t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
1919             eg
1920                t1 = CASle(t2 :: t3->Add32(t3,1))
1921                which denotes a 32-bit atomic increment
1922                of a value at address t2
1923 
1924             A double-element CAS may also be denoted, in which case <tmp>,
1925             <expected> and <new> are all pairs of items, separated by
1926             commas.
1927          */
1928          struct {
1929             IRCAS* details;
1930          } CAS;
1931 
1932          /* Either Load-Linked or Store-Conditional, depending on
1933             STOREDATA.
1934 
1935             If STOREDATA is NULL then this is a Load-Linked, meaning
1936             that data is loaded from memory as normal, but a
1937             'reservation' for the address is also lodged in the
1938             hardware.
1939 
1940                result = Load-Linked(addr, end)
1941 
1942             The data transfer type is the type of RESULT (I32, I64,
1943             etc).  ppIRStmt output:
1944 
1945                result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
1946 
1947             If STOREDATA is not NULL then this is a Store-Conditional,
1948             hence:
1949 
1950                result = Store-Conditional(addr, storedata, end)
1951 
1952             The data transfer type is the type of STOREDATA and RESULT
1953             has type Ity_I1. The store may fail or succeed depending
1954             on the state of a previously lodged reservation on this
1955             address.  RESULT is written 1 if the store succeeds and 0
1956             if it fails.  eg ppIRStmt output:
1957 
1958                result = ( ST<end>-Cond(<addr>) = <storedata> )
1959                eg t3 = ( STbe-Cond(t1, t2) )
1960 
1961             In all cases, the address must be naturally aligned for
1962             the transfer type -- any misaligned addresses should be
1963             caught by a dominating IR check and side exit.  This
1964             alignment restriction exists because on at least some
1965             LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
1966             misaligned addresses, and we have to actually generate
1967             stwcx. on the host, and we don't want it trapping on the
1968             host.
1969 
1970             Summary of rules for transfer type:
1971               STOREDATA == NULL (LL):
1972                 transfer type = type of RESULT
1973               STOREDATA != NULL (SC):
1974                 transfer type = type of STOREDATA, and RESULT :: Ity_I1
1975          */
1976          struct {
1977             IREndness end;
1978             IRTemp    result;
1979             IRExpr*   addr;
1980             IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
1981          } LLSC;
1982 
1983          /* Call (possibly conditionally) a C function that has side
1984             effects (ie. is "dirty").  See the comments above the
1985             IRDirty type declaration for more information.
1986 
1987             ppIRStmt output:
1988                t<tmp> = DIRTY <guard> <effects>
1989                   ::: <callee>(<args>)
1990             eg.
1991                t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
1992                      ::: foo{0x380035f4}(t2)
1993          */
1994          struct {
1995             IRDirty* details;
1996          } Dirty;
1997 
1998          /* A memory bus event - a fence, or acquisition/release of the
1999             hardware bus lock.  IR optimisation treats all these as fences
2000             across which no memory references may be moved.
2001             ppIRStmt output: MBusEvent-Fence,
2002                              MBusEvent-BusLock, MBusEvent-BusUnlock.
2003          */
2004          struct {
2005             IRMBusEvent event;
2006          } MBE;
2007 
2008          /* Conditional exit from the middle of an IRSB.
2009             ppIRStmt output: if (<guard>) goto {<jk>} <dst>
2010                          eg. if (t69) goto {Boring} 0x4000AAA:I32
2011          */
2012          struct {
2013             IRExpr*    guard;    /* Conditional expression */
2014             IRJumpKind jk;       /* Jump kind */
2015             IRConst*   dst;      /* Jump target (constant only) */
2016          } Exit;
2017       } Ist;
2018    }
2019    IRStmt;
2020 
2021 /* Statement constructors. */
2022 extern IRStmt* IRStmt_NoOp    ( void );
2023 extern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len );
2024 extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
2025 extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
2026 extern IRStmt* IRStmt_PutI    ( IRRegArray* descr, IRExpr* ix, Int bias,
2027                                 IRExpr* data );
2028 extern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
2029 extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
2030 extern IRStmt* IRStmt_CAS     ( IRCAS* details );
2031 extern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
2032                                 IRExpr* addr, IRExpr* storedata );
2033 extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
2034 extern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
2035 extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
2036 
2037 /* Deep-copy an IRStmt. */
2038 extern IRStmt* deepCopyIRStmt ( IRStmt* );
2039 
2040 /* Pretty-print an IRStmt. */
2041 extern void ppIRStmt ( IRStmt* );
2042 
2043 
2044 /* ------------------ Basic Blocks ------------------ */
2045 
2046 /* Type environments: a bunch of statements, expressions, etc, are
2047    incomplete without an environment indicating the type of each
2048    IRTemp.  So this provides one.  IR temporaries are really just
2049    unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2050    them.
2051 */
2052 typedef
2053    struct {
2054       IRType* types;
2055       Int     types_size;
2056       Int     types_used;
2057    }
2058    IRTypeEnv;
2059 
2060 /* Obtain a new IRTemp */
2061 extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2062 
2063 /* Deep-copy a type environment */
2064 extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
2065 
2066 /* Pretty-print a type environment */
2067 extern void ppIRTypeEnv ( IRTypeEnv* );
2068 
2069 
2070 /* Code blocks, which in proper compiler terminology are superblocks
2071    (single entry, multiple exit code sequences) contain:
2072 
2073    - A table giving a type for each temp (the "type environment")
2074    - An expandable array of statements
2075    - An expression of type 32 or 64 bits, depending on the
2076      guest's word size, indicating the next destination if the block
2077      executes all the way to the end, without a side exit
2078    - An indication of any special actions (JumpKind) needed
2079      for this final jump.
2080 
2081    "IRSB" stands for "IR Super Block".
2082 */
2083 typedef
2084    struct {
2085       IRTypeEnv* tyenv;
2086       IRStmt**   stmts;
2087       Int        stmts_size;
2088       Int        stmts_used;
2089       IRExpr*    next;
2090       IRJumpKind jumpkind;
2091    }
2092    IRSB;
2093 
2094 /* Allocate a new, uninitialised IRSB */
2095 extern IRSB* emptyIRSB ( void );
2096 
2097 /* Deep-copy an IRSB */
2098 extern IRSB* deepCopyIRSB ( IRSB* );
2099 
2100 /* Deep-copy an IRSB, except for the statements list, which set to be
2101    a new, empty, list of statements. */
2102 extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
2103 
2104 /* Pretty-print an IRSB */
2105 extern void ppIRSB ( IRSB* );
2106 
2107 /* Append an IRStmt to an IRSB */
2108 extern void addStmtToIRSB ( IRSB*, IRStmt* );
2109 
2110 
2111 /*---------------------------------------------------------------*/
2112 /*--- Helper functions for the IR                             ---*/
2113 /*---------------------------------------------------------------*/
2114 
2115 /* For messing with IR type environments */
2116 extern IRTypeEnv* emptyIRTypeEnv  ( void );
2117 
2118 /* What is the type of this expression? */
2119 extern IRType typeOfIRConst ( IRConst* );
2120 extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
2121 extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
2122 
2123 /* Sanity check a BB of IR */
2124 extern void sanityCheckIRSB ( IRSB*  bb,
2125                               HChar* caller,
2126                               Bool   require_flatness,
2127                               IRType guest_word_size );
2128 extern Bool isFlatIRStmt ( IRStmt* );
2129 
2130 /* Is this any value actually in the enumeration 'IRType' ? */
2131 extern Bool isPlausibleIRType ( IRType ty );
2132 
2133 #endif /* ndef __LIBVEX_IR_H */
2134 
2135 
2136 /*---------------------------------------------------------------*/
2137 /*---                                             libvex_ir.h ---*/
2138 /*---------------------------------------------------------------*/
2139