libvex_ir.h revision e739ac0589b4fb43561f801c4faba8c1b89f8680
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. */
219typedef
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 */
235extern void ppIRType ( IRType );
236
237/* Get the size (in bytes) of an IRType */
238extern Int sizeofIRType ( IRType );
239
240
241/* ------------------ Endianness ------------------ */
242
243/* IREndness is used in load IRExprs and store IRStmts. */
244typedef
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. */
257typedef
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'. */
276typedef
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 */
293extern IRConst* IRConst_U1   ( Bool );
294extern IRConst* IRConst_U8   ( UChar );
295extern IRConst* IRConst_U16  ( UShort );
296extern IRConst* IRConst_U32  ( UInt );
297extern IRConst* IRConst_U64  ( ULong );
298extern IRConst* IRConst_F64  ( Double );
299extern IRConst* IRConst_F64i ( ULong );
300extern IRConst* IRConst_V128 ( UShort );
301
302/* Deep-copy an IRConst */
303extern IRConst* deepCopyIRConst ( IRConst* );
304
305/* Pretty-print an IRConst */
306extern void ppIRConst ( IRConst* );
307
308/* Compare two IRConsts for equality */
309extern 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
328typedef
329   struct {
330      Int    regparms;
331      HChar* name;
332      void*  addr;
333      UInt   mcx_mask;
334   }
335   IRCallee;
336
337/* Create an IRCallee. */
338extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
339
340/* Deep-copy an IRCallee. */
341extern IRCallee* deepCopyIRCallee ( IRCallee* );
342
343/* Pretty-print an IRCallee. */
344extern 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. */
352typedef
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
360extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
361
362extern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
363
364extern void ppIRRegArray ( IRRegArray* );
365extern 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. */
373typedef UInt IRTemp;
374
375/* Pretty-print an IRTemp. */
376extern 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*/
393typedef
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. */
1204extern 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. */
1211typedef
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. */
1222typedef
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. */
1236typedef
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*/
1262typedef
1263   struct _IRExpr
1264   IRExpr;
1265
1266struct _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. */
1452extern IRExpr* IRExpr_Binder ( Int binder );
1453extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
1454extern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
1455extern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
1456extern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2,
1457                                        IRExpr* arg3, IRExpr* arg4 );
1458extern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1,
1459                                        IRExpr* arg2, IRExpr* arg3 );
1460extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1461extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
1462extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
1463extern IRExpr* IRExpr_Const  ( IRConst* con );
1464extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
1465extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
1466
1467/* Deep-copy an IRExpr. */
1468extern IRExpr* deepCopyIRExpr ( IRExpr* );
1469
1470/* Pretty-print an IRExpr. */
1471extern void ppIRExpr ( IRExpr* );
1472
1473/* NULL-terminated IRExpr vector constructors, suitable for
1474   use as arg lists in clean/dirty helper calls. */
1475extern IRExpr** mkIRExprVec_0 ( void );
1476extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1477extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1478extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1479extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
1480extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1481                                IRExpr* );
1482extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1483                                IRExpr*, IRExpr* );
1484extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1485                                IRExpr*, IRExpr*, IRExpr* );
1486extern 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). */
1493extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1494extern IRExpr** deepCopyIRExprVec ( IRExpr** );
1495
1496/* Make a constant expression from the given host word taking into
1497   account (of course) the host word size. */
1498extern IRExpr* mkIRExpr_HWord ( HWord );
1499
1500/* Convenience function for constructing clean helper calls. */
1501extern
1502IRExpr* 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). */
1509static 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. */
1515extern 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*/
1545typedef
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_EmWarn,         /* report emulation warning before continuing */
1553      Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
1554      Ijk_NoDecode,       /* next instruction cannot be decoded */
1555      Ijk_MapFail,        /* Vex-provided address translation failed */
1556      Ijk_TInval,         /* Invalidate translations before continuing. */
1557      Ijk_NoRedir,        /* Jump to un-redirected guest addr */
1558      Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
1559      Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
1560      Ijk_SigBUS,         /* current instruction synths SIGBUS */
1561      /* Unfortunately, various guest-dependent syscall kinds.  They
1562	 all mean: do a syscall before continuing. */
1563      Ijk_Sys_syscall,    /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
1564      Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
1565      Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
1566      Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
1567      Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
1568      Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes
1569                             invalid at the point this happens. */
1570   }
1571   IRJumpKind;
1572
1573extern void ppIRJumpKind ( IRJumpKind );
1574
1575
1576/* ------------------ Dirty helper calls ------------------ */
1577
1578/* A dirty call is a flexible mechanism for calling (possibly
1579   conditionally) a helper function or procedure.  The helper function
1580   may read, write or modify client memory, and may read, write or
1581   modify client state.  It can take arguments and optionally return a
1582   value.  It may return different results and/or do different things
1583   when called repeatedly with the same arguments, by means of storing
1584   private state.
1585
1586   If a value is returned, it is assigned to the nominated return
1587   temporary.
1588
1589   Dirty calls are statements rather than expressions for obvious
1590   reasons.  If a dirty call is marked as writing guest state, any
1591   values derived from the written parts of the guest state are
1592   invalid.  Similarly, if the dirty call is stated as writing
1593   memory, any loaded values are invalidated by it.
1594
1595   In order that instrumentation is possible, the call must state, and
1596   state correctly:
1597
1598   * whether it reads, writes or modifies memory, and if so where
1599     (only one chunk can be stated)
1600
1601   * whether it reads, writes or modifies guest state, and if so which
1602     pieces (several pieces may be stated, and currently their extents
1603     must be known at translation-time).
1604
1605   Normally, code is generated to pass just the args to the helper.
1606   However, if .needsBBP is set, then an extra first argument is
1607   passed, which is the baseblock pointer, so that the callee can
1608   access the guest state.  It is invalid for .nFxState to be zero
1609   but .needsBBP to be True, since .nFxState==0 is a claim that the
1610   call does not access guest state.
1611
1612   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
1613   arguments are evaluated REGARDLESS of the guard value.  It is
1614   unspecified the relative order of arg evaluation and guard
1615   evaluation.
1616*/
1617
1618#define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
1619
1620/* Effects on resources (eg. registers, memory locations) */
1621typedef
1622   enum {
1623      Ifx_None = 0x17000,   /* no effect */
1624      Ifx_Read,             /* reads the resource */
1625      Ifx_Write,            /* writes the resource */
1626      Ifx_Modify,           /* modifies the resource */
1627   }
1628   IREffect;
1629
1630/* Pretty-print an IREffect */
1631extern void ppIREffect ( IREffect );
1632
1633
1634typedef
1635   struct {
1636      /* What to call, and details of args/results */
1637      IRCallee* cee;    /* where to call */
1638      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
1639      IRExpr**  args;   /* arg list, ends in NULL */
1640      IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
1641
1642      /* Mem effects; we allow only one R/W/M region to be stated */
1643      IREffect  mFx;    /* indicates memory effects, if any */
1644      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
1645      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
1646
1647      /* Guest state effects; up to N allowed */
1648      Bool needsBBP; /* True => also pass guest state ptr to callee */
1649      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
1650      struct {
1651         IREffect fx;   /* read, write or modify?  Ifx_None is invalid. */
1652         Int      offset;
1653         Int      size;
1654      } fxState[VEX_N_FXSTATE];
1655   }
1656   IRDirty;
1657
1658/* Pretty-print a dirty call */
1659extern void     ppIRDirty ( IRDirty* );
1660
1661/* Allocate an uninitialised dirty call */
1662extern IRDirty* emptyIRDirty ( void );
1663
1664/* Deep-copy a dirty call */
1665extern IRDirty* deepCopyIRDirty ( IRDirty* );
1666
1667/* A handy function which takes some of the tedium out of constructing
1668   dirty helper calls.  The called function impliedly does not return
1669   any value and has a constant-True guard.  The call is marked as
1670   accessing neither guest state nor memory (hence the "unsafe"
1671   designation) -- you can change this marking later if need be.  A
1672   suitable IRCallee is constructed from the supplied bits. */
1673extern
1674IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
1675                             IRExpr** args );
1676
1677/* Similarly, make a zero-annotation dirty call which returns a value,
1678   and assign that to the given temp. */
1679extern
1680IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1681                             Int regparms, HChar* name, void* addr,
1682                             IRExpr** args );
1683
1684
1685/* --------------- Memory Bus Events --------------- */
1686
1687typedef
1688   enum {
1689      Imbe_Fence=0x18000,
1690   }
1691   IRMBusEvent;
1692
1693extern void ppIRMBusEvent ( IRMBusEvent );
1694
1695
1696/* --------------- Compare and Swap --------------- */
1697
1698/* This denotes an atomic compare and swap operation, either
1699   a single-element one or a double-element one.
1700
1701   In the single-element case:
1702
1703     .addr is the memory address.
1704     .end  is the endianness with which memory is accessed
1705
1706     If .addr contains the same value as .expdLo, then .dataLo is
1707     written there, else there is no write.  In both cases, the
1708     original value at .addr is copied into .oldLo.
1709
1710     Types: .expdLo, .dataLo and .oldLo must all have the same type.
1711     It may be any integral type, viz: I8, I16, I32 or, for 64-bit
1712     guests, I64.
1713
1714     .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
1715     be NULL.
1716
1717   In the double-element case:
1718
1719     .addr is the memory address.
1720     .end  is the endianness with which memory is accessed
1721
1722     The operation is the same:
1723
1724     If .addr contains the same value as .expdHi:.expdLo, then
1725     .dataHi:.dataLo is written there, else there is no write.  In
1726     both cases the original value at .addr is copied into
1727     .oldHi:.oldLo.
1728
1729     Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
1730     all have the same type, which may be any integral type, viz: I8,
1731     I16, I32 or, for 64-bit guests, I64.
1732
1733     The double-element case is complicated by the issue of
1734     endianness.  In all cases, the two elements are understood to be
1735     located adjacently in memory, starting at the address .addr.
1736
1737       If .end is Iend_LE, then the .xxxLo component is at the lower
1738       address and the .xxxHi component is at the higher address, and
1739       each component is itself stored little-endianly.
1740
1741       If .end is Iend_BE, then the .xxxHi component is at the lower
1742       address and the .xxxLo component is at the higher address, and
1743       each component is itself stored big-endianly.
1744
1745   This allows representing more cases than most architectures can
1746   handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
1747
1748   How to know if the CAS succeeded?
1749
1750   * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
1751     then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
1752     stored at .addr, and the original value there was .oldLo (resp
1753     .oldHi:.oldLo).
1754
1755   * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
1756     then the CAS failed, and the original value at .addr was .oldLo
1757     (resp. .oldHi:.oldLo).
1758
1759   Hence it is easy to know whether or not the CAS succeeded.
1760*/
1761typedef
1762   struct {
1763      IRTemp    oldHi;  /* old value of *addr is written here */
1764      IRTemp    oldLo;
1765      IREndness end;    /* endianness of the data in memory */
1766      IRExpr*   addr;   /* store address */
1767      IRExpr*   expdHi; /* expected old value at *addr */
1768      IRExpr*   expdLo;
1769      IRExpr*   dataHi; /* new value for *addr */
1770      IRExpr*   dataLo;
1771   }
1772   IRCAS;
1773
1774extern void ppIRCAS ( IRCAS* cas );
1775
1776extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1777                        IREndness end, IRExpr* addr,
1778                        IRExpr* expdHi, IRExpr* expdLo,
1779                        IRExpr* dataHi, IRExpr* dataLo );
1780
1781extern IRCAS* deepCopyIRCAS ( IRCAS* );
1782
1783/* ------------------ Statements ------------------ */
1784
1785/* The different kinds of statements.  Their meaning is explained
1786   below in the comments for IRStmt.
1787
1788   Those marked META do not represent code, but rather extra
1789   information about the code.  These statements can be removed
1790   without affecting the functional behaviour of the code, however
1791   they are required by some IR consumers such as tools that
1792   instrument the code.
1793*/
1794
1795typedef
1796   enum {
1797      Ist_NoOp=0x19000,
1798      Ist_IMark,     /* META */
1799      Ist_AbiHint,   /* META */
1800      Ist_Put,
1801      Ist_PutI,
1802      Ist_WrTmp,
1803      Ist_Store,
1804      Ist_CAS,
1805      Ist_LLSC,
1806      Ist_Dirty,
1807      Ist_MBE,       /* META (maybe) */
1808      Ist_Exit
1809   }
1810   IRStmtTag;
1811
1812/* A statement.  Stored as a tagged union.  'tag' indicates what kind
1813   of expression this is.  'Ist' is the union that holds the fields.
1814   If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
1815   statement, and the fields can be accessed with
1816   'st.Ist.Store.<fieldname>'.
1817
1818   For each kind of statement, we show what it looks like when
1819   pretty-printed with ppIRStmt().
1820*/
1821typedef
1822   struct _IRStmt {
1823      IRStmtTag tag;
1824      union {
1825         /* A no-op (usually resulting from IR optimisation).  Can be
1826            omitted without any effect.
1827
1828            ppIRStmt output: IR-NoOp
1829         */
1830         struct {
1831	 } NoOp;
1832
1833         /* META: instruction mark.  Marks the start of the statements
1834            that represent a single machine instruction (the end of
1835            those statements is marked by the next IMark or the end of
1836            the IRSB).  Contains the address and length of the
1837            instruction.
1838
1839            ppIRStmt output: ------ IMark(<addr>, <len>) ------,
1840                         eg. ------ IMark(0x4000792, 5) ------,
1841         */
1842         struct {
1843            Addr64 addr;   /* instruction address */
1844            Int    len;    /* instruction length */
1845         } IMark;
1846
1847         /* META: An ABI hint, which says something about this
1848            platform's ABI.
1849
1850            At the moment, the only AbiHint is one which indicates
1851            that a given chunk of address space, [base .. base+len-1],
1852            has become undefined.  This is used on amd64-linux and
1853            some ppc variants to pass stack-redzoning hints to whoever
1854            wants to see them.  It also indicates the address of the
1855            next (dynamic) instruction that will be executed.  This is
1856            to help Memcheck to origin tracking.
1857
1858            ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
1859                         eg. ====== AbiHint(t1, 16, t2) ======
1860         */
1861         struct {
1862            IRExpr* base;     /* Start  of undefined chunk */
1863            Int     len;      /* Length of undefined chunk */
1864            IRExpr* nia;      /* Address of next (guest) insn */
1865         } AbiHint;
1866
1867         /* Write a guest register, at a fixed offset in the guest state.
1868            ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
1869         */
1870         struct {
1871            Int     offset;   /* Offset into the guest state */
1872            IRExpr* data;     /* The value to write */
1873         } Put;
1874
1875         /* Write a guest register, at a non-fixed offset in the guest
1876            state.  See the comment for GetI expressions for more
1877            information.
1878
1879            ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
1880                         eg. PUTI(64:8xF64)[t5,0] = t1
1881         */
1882         struct {
1883            IRRegArray* descr; /* Part of guest state treated as circular */
1884            IRExpr*     ix;    /* Variable part of index into array */
1885            Int         bias;  /* Constant offset part of index into array */
1886            IRExpr*     data;  /* The value to write */
1887         } PutI;
1888
1889         /* Assign a value to a temporary.  Note that SSA rules require
1890            each tmp is only assigned to once.  IR sanity checking will
1891            reject any block containing a temporary which is not assigned
1892            to exactly once.
1893
1894            ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
1895         */
1896         struct {
1897            IRTemp  tmp;   /* Temporary  (LHS of assignment) */
1898            IRExpr* data;  /* Expression (RHS of assignment) */
1899         } WrTmp;
1900
1901         /* Write a value to memory.  This is a normal store, not a
1902            Store-Conditional.  To represent a Store-Conditional,
1903            instead use IRStmt.LLSC.
1904            ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
1905         */
1906         struct {
1907            IREndness end;    /* Endianness of the store */
1908            IRExpr*   addr;   /* store address */
1909            IRExpr*   data;   /* value to write */
1910         } Store;
1911
1912         /* Do an atomic compare-and-swap operation.  Semantics are
1913            described above on a comment at the definition of IRCAS.
1914
1915            ppIRStmt output:
1916               t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
1917            eg
1918               t1 = CASle(t2 :: t3->Add32(t3,1))
1919               which denotes a 32-bit atomic increment
1920               of a value at address t2
1921
1922            A double-element CAS may also be denoted, in which case <tmp>,
1923            <expected> and <new> are all pairs of items, separated by
1924            commas.
1925         */
1926         struct {
1927            IRCAS* details;
1928         } CAS;
1929
1930         /* Either Load-Linked or Store-Conditional, depending on
1931            STOREDATA.
1932
1933            If STOREDATA is NULL then this is a Load-Linked, meaning
1934            that data is loaded from memory as normal, but a
1935            'reservation' for the address is also lodged in the
1936            hardware.
1937
1938               result = Load-Linked(addr, end)
1939
1940            The data transfer type is the type of RESULT (I32, I64,
1941            etc).  ppIRStmt output:
1942
1943               result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
1944
1945            If STOREDATA is not NULL then this is a Store-Conditional,
1946            hence:
1947
1948               result = Store-Conditional(addr, storedata, end)
1949
1950            The data transfer type is the type of STOREDATA and RESULT
1951            has type Ity_I1. The store may fail or succeed depending
1952            on the state of a previously lodged reservation on this
1953            address.  RESULT is written 1 if the store succeeds and 0
1954            if it fails.  eg ppIRStmt output:
1955
1956               result = ( ST<end>-Cond(<addr>) = <storedata> )
1957               eg t3 = ( STbe-Cond(t1, t2) )
1958
1959            In all cases, the address must be naturally aligned for
1960            the transfer type -- any misaligned addresses should be
1961            caught by a dominating IR check and side exit.  This
1962            alignment restriction exists because on at least some
1963            LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
1964            misaligned addresses, and we have to actually generate
1965            stwcx. on the host, and we don't want it trapping on the
1966            host.
1967
1968            Summary of rules for transfer type:
1969              STOREDATA == NULL (LL):
1970                transfer type = type of RESULT
1971              STOREDATA != NULL (SC):
1972                transfer type = type of STOREDATA, and RESULT :: Ity_I1
1973         */
1974         struct {
1975            IREndness end;
1976            IRTemp    result;
1977            IRExpr*   addr;
1978            IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
1979         } LLSC;
1980
1981         /* Call (possibly conditionally) a C function that has side
1982            effects (ie. is "dirty").  See the comments above the
1983            IRDirty type declaration for more information.
1984
1985            ppIRStmt output:
1986               t<tmp> = DIRTY <guard> <effects>
1987                  ::: <callee>(<args>)
1988            eg.
1989               t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
1990                     ::: foo{0x380035f4}(t2)
1991         */
1992         struct {
1993            IRDirty* details;
1994         } Dirty;
1995
1996         /* A memory bus event - a fence, or acquisition/release of the
1997            hardware bus lock.  IR optimisation treats all these as fences
1998            across which no memory references may be moved.
1999            ppIRStmt output: MBusEvent-Fence,
2000                             MBusEvent-BusLock, MBusEvent-BusUnlock.
2001         */
2002         struct {
2003            IRMBusEvent event;
2004         } MBE;
2005
2006         /* Conditional exit from the middle of an IRSB.
2007            ppIRStmt output: if (<guard>) goto {<jk>} <dst>
2008                         eg. if (t69) goto {Boring} 0x4000AAA:I32
2009         */
2010         struct {
2011            IRExpr*    guard;    /* Conditional expression */
2012            IRJumpKind jk;       /* Jump kind */
2013            IRConst*   dst;      /* Jump target (constant only) */
2014         } Exit;
2015      } Ist;
2016   }
2017   IRStmt;
2018
2019/* Statement constructors. */
2020extern IRStmt* IRStmt_NoOp    ( void );
2021extern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len );
2022extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
2023extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
2024extern IRStmt* IRStmt_PutI    ( IRRegArray* descr, IRExpr* ix, Int bias,
2025                                IRExpr* data );
2026extern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
2027extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
2028extern IRStmt* IRStmt_CAS     ( IRCAS* details );
2029extern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
2030                                IRExpr* addr, IRExpr* storedata );
2031extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
2032extern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
2033extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
2034
2035/* Deep-copy an IRStmt. */
2036extern IRStmt* deepCopyIRStmt ( IRStmt* );
2037
2038/* Pretty-print an IRStmt. */
2039extern void ppIRStmt ( IRStmt* );
2040
2041
2042/* ------------------ Basic Blocks ------------------ */
2043
2044/* Type environments: a bunch of statements, expressions, etc, are
2045   incomplete without an environment indicating the type of each
2046   IRTemp.  So this provides one.  IR temporaries are really just
2047   unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2048   them.
2049*/
2050typedef
2051   struct {
2052      IRType* types;
2053      Int     types_size;
2054      Int     types_used;
2055   }
2056   IRTypeEnv;
2057
2058/* Obtain a new IRTemp */
2059extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2060
2061/* Deep-copy a type environment */
2062extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
2063
2064/* Pretty-print a type environment */
2065extern void ppIRTypeEnv ( IRTypeEnv* );
2066
2067
2068/* Code blocks, which in proper compiler terminology are superblocks
2069   (single entry, multiple exit code sequences) contain:
2070
2071   - A table giving a type for each temp (the "type environment")
2072   - An expandable array of statements
2073   - An expression of type 32 or 64 bits, depending on the
2074     guest's word size, indicating the next destination if the block
2075     executes all the way to the end, without a side exit
2076   - An indication of any special actions (JumpKind) needed
2077     for this final jump.
2078
2079   "IRSB" stands for "IR Super Block".
2080*/
2081typedef
2082   struct {
2083      IRTypeEnv* tyenv;
2084      IRStmt**   stmts;
2085      Int        stmts_size;
2086      Int        stmts_used;
2087      IRExpr*    next;
2088      IRJumpKind jumpkind;
2089   }
2090   IRSB;
2091
2092/* Allocate a new, uninitialised IRSB */
2093extern IRSB* emptyIRSB ( void );
2094
2095/* Deep-copy an IRSB */
2096extern IRSB* deepCopyIRSB ( IRSB* );
2097
2098/* Deep-copy an IRSB, except for the statements list, which set to be
2099   a new, empty, list of statements. */
2100extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
2101
2102/* Pretty-print an IRSB */
2103extern void ppIRSB ( IRSB* );
2104
2105/* Append an IRStmt to an IRSB */
2106extern void addStmtToIRSB ( IRSB*, IRStmt* );
2107
2108
2109/*---------------------------------------------------------------*/
2110/*--- Helper functions for the IR                             ---*/
2111/*---------------------------------------------------------------*/
2112
2113/* For messing with IR type environments */
2114extern IRTypeEnv* emptyIRTypeEnv  ( void );
2115
2116/* What is the type of this expression? */
2117extern IRType typeOfIRConst ( IRConst* );
2118extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
2119extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
2120
2121/* Sanity check a BB of IR */
2122extern void sanityCheckIRSB ( IRSB*  bb,
2123                              HChar* caller,
2124                              Bool   require_flatness,
2125                              IRType guest_word_size );
2126extern Bool isFlatIRStmt ( IRStmt* );
2127
2128/* Is this any value actually in the enumeration 'IRType' ? */
2129extern Bool isPlausibleIRType ( IRType ty );
2130
2131#endif /* ndef __LIBVEX_IR_H */
2132
2133
2134/*---------------------------------------------------------------*/
2135/*---                                             libvex_ir.h ---*/
2136/*---------------------------------------------------------------*/
2137