libvex_ir.h revision f0de28cf1a762b0d6f74c93d3532c89a230673bb
1
2/*---------------------------------------------------------------*/
3/*---                                                         ---*/
4/*--- This file (libvex_ir.h) is                              ---*/
5/*--- Copyright (C) OpenWorks LLP.  All rights reserved.      ---*/
6/*---                                                         ---*/
7/*---------------------------------------------------------------*/
8
9/*
10   This file is part of LibVEX, a library for dynamic binary
11   instrumentation and translation.
12
13   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.
14
15   This library is made available under a dual licensing scheme.
16
17   If you link LibVEX against other code all of which is itself
18   licensed under the GNU General Public License, version 2 dated June
19   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
20   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL
21   is missing, you can obtain a copy of the GPL v2 from the Free
22   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
23   02110-1301, USA.
24
25   For any other uses of LibVEX, you must first obtain a commercial
26   license from OpenWorks LLP.  Please contact info@open-works.co.uk
27   for information about commercial licensing.
28
29   This software is provided by OpenWorks LLP "as is" and any express
30   or implied warranties, including, but not limited to, the implied
31   warranties of merchantability and fitness for a particular purpose
32   are disclaimed.  In no event shall OpenWorks LLP be liable for any
33   direct, indirect, incidental, special, exemplary, or consequential
34   damages (including, but not limited to, procurement of substitute
35   goods or services; loss of use, data, or profits; or business
36   interruption) however caused and on any theory of liability,
37   whether in contract, strict liability, or tort (including
38   negligence or otherwise) arising in any way out of the use of this
39   software, even if advised of the possibility of such damage.
40
41   Neither the names of the U.S. Department of Energy nor the
42   University of California nor the names of its contributors may be
43   used to endorse or promote products derived from this software
44   without prior written permission.
45*/
46
47#ifndef __LIBVEX_IR_H
48#define __LIBVEX_IR_H
49
50#include "libvex_basictypes.h"
51
52
53
54/*---------------------------------------------------------------*/
55/*--- Type definitions for the IR                             ---*/
56/*---------------------------------------------------------------*/
57
58/* General comments about naming schemes:
59
60   All publically visible functions contain the name of the primary
61   type on which they operate (IRFoo, IRBar, etc).  Hence you should
62   be able to identify these functions by grepping for "IR[A-Z]".
63
64   For some type 'IRFoo':
65
66   - ppIRFoo is the printing method for IRFoo, printing it to the
67     output channel specified in the LibVEX_Initialise call.
68
69   - eqIRFoo is a structural equality predicate for IRFoos.
70
71   - dopyIRFoo is a deep copy constructor for IRFoos.
72     It recursively traverses the entire argument tree and
73     produces a complete new tree.
74
75   - sopyIRFoo is the shallow copy constructor for IRFoos.
76     It creates a new top-level copy of the supplied object,
77     but does not copy any sub-objects.
78*/
79
80/* ------------------ Types ------------------ */
81
82typedef
83   enum {
84      Ity_INVALID=0x10FFF,
85      Ity_I1=0x11000,
86      Ity_I8,
87      Ity_I16,
88      Ity_I32,
89      Ity_I64,
90      Ity_I128,  /* 128-bit scalar */
91      Ity_F32,   /* IEEE 754 float */
92      Ity_F64,   /* IEEE 754 double */
93      Ity_V128   /* 128-bit SIMD */
94   }
95   IRType;
96
97extern void ppIRType ( IRType );
98extern Int  sizeofIRType ( IRType );
99
100
101/* ------------------ Endianness ------------------ */
102
103typedef
104   enum {
105      Iend_LE=22, /* little endian */
106      Iend_BE=33 /* big endian */
107   }
108   IREndness;
109
110
111/* ------------------ Constants ------------------ */
112
113typedef
114   enum {
115      Ico_U1=0x12000,
116      Ico_U8,
117      Ico_U16,
118      Ico_U32,
119      Ico_U64,
120      Ico_F64,   /* 64-bit IEEE754 floating */
121      Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
122                    as a IEEE754 double value. */
123      Ico_V128   /* 128-bit restricted vector constant, with 1 bit for
124                    each of 16 byte lanes */
125   }
126   IRConstTag;
127
128typedef
129   struct _IRConst {
130      IRConstTag tag;
131      union {
132         Bool   U1;
133         UChar  U8;
134         UShort U16;
135         UInt   U32;
136         ULong  U64;
137         Double F64;
138         ULong  F64i;
139         UShort V128;
140      } Ico;
141   }
142   IRConst;
143
144extern IRConst* IRConst_U1   ( Bool );
145extern IRConst* IRConst_U8   ( UChar );
146extern IRConst* IRConst_U16  ( UShort );
147extern IRConst* IRConst_U32  ( UInt );
148extern IRConst* IRConst_U64  ( ULong );
149extern IRConst* IRConst_F64  ( Double );
150extern IRConst* IRConst_F64i ( ULong );
151extern IRConst* IRConst_V128 ( UShort );
152
153extern IRConst* dopyIRConst ( IRConst* );
154
155extern void ppIRConst ( IRConst* );
156extern Bool eqIRConst ( IRConst*, IRConst* );
157
158
159/* ------------------ Call targets ------------------ */
160
161/* Describes a helper function to call.  The name part is purely for
162   pretty printing and not actually used.  regparms=n tells the back
163   end that the callee has been declared
164   "__attribute__((regparm(n)))".  On some targets (x86) the back end
165   will need to construct a non-standard sequence to call a function
166   declared like this.
167
168   mcx_mask is a sop to Memcheck.  It indicates which args should be
169   considered 'always defined' when lazily computing definedness of
170   the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
171   args[1], etc.  If a bit is set, the corresponding arg is excluded
172   (hence "x" in "mcx") from definedness checking.
173*/
174
175typedef
176   struct {
177      Int    regparms;
178      HChar* name;
179      void*  addr;
180      UInt   mcx_mask;
181   }
182   IRCallee;
183
184extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
185
186extern IRCallee* dopyIRCallee ( IRCallee* );
187
188extern void ppIRCallee ( IRCallee* );
189
190
191/* ------------------ Guest state arrays ------------------ */
192
193typedef
194   struct {
195      Int    base;
196      IRType elemTy;
197      Int    nElems;
198   }
199   IRArray;
200
201extern IRArray* mkIRArray ( Int, IRType, Int );
202
203extern IRArray* dopyIRArray ( IRArray* );
204
205extern void ppIRArray ( IRArray* );
206extern Bool eqIRArray ( IRArray*, IRArray* );
207
208
209/* ------------------ Temporaries ------------------ */
210
211/* The IR optimiser relies on the fact that IRTemps are 32-bit
212   ints.  Do not change them to be ints of any other size. */
213typedef UInt IRTemp;
214
215extern void ppIRTemp ( IRTemp );
216
217#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
218
219
220/* ------------------ Binary and unary ops ------------------ */
221
222typedef
223   enum {
224      /* -- Do not change this ordering.  The IR generators rely on
225            (eg) Iop_Add64 == IopAdd8 + 3. -- */
226
227      Iop_INVALID=0x13000,
228      Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
229      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
230      /* Signless mul.  MullS/MullU is elsewhere. */
231      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
232      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
233      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
234      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
235      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
236      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
237      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
238      /* Integer comparisons. */
239      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
240      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
241      /* Tags for unary ops */
242      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
243      Iop_Neg8,  Iop_Neg16,  Iop_Neg32,  Iop_Neg64,
244
245      /* -- Ordering not important after here. -- */
246
247      /* Widening multiplies */
248      Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
249      Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
250
251      /* Wierdo integer stuff */
252      Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
253      Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
254      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
255         zero.  You must ensure they are never given a zero argument.
256      */
257
258      /* Standard integer comparisons */
259      Iop_CmpLT32S, Iop_CmpLT64S,
260      Iop_CmpLE32S, Iop_CmpLE64S,
261      Iop_CmpLT32U, Iop_CmpLT64U,
262      Iop_CmpLE32U, Iop_CmpLE64U,
263
264      /* As a sop to Valgrind-Memcheck, the following are useful. */
265      Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
266
267      /* PowerPC-style 3-way integer comparisons.  Without them it is difficult
268         to simulate PPC efficiently.
269         op(x,y) | x < y  = 0x8 else
270                 | x > y  = 0x4 else
271                 | x == y = 0x2
272      */
273      Iop_CmpORD32U, Iop_CmpORD64U,
274      Iop_CmpORD32S, Iop_CmpORD64S,
275
276      /* Division */
277      /* TODO: clarify semantics wrt rounding, negative values, whatever */
278      Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
279      Iop_DivS32,   // ditto, signed
280      Iop_DivU64,   // :: I64,I64 -> I64 (simple div, no mod)
281      Iop_DivS64,   // ditto, signed
282
283      Iop_DivModU64to32, // :: I64,I32 -> I64
284                         // of which lo half is div and hi half is mod
285      Iop_DivModS64to32, // ditto, signed
286
287      Iop_DivModU128to64, // :: V128,I64 -> V128
288                          // of which lo half is div and hi half is mod
289      Iop_DivModS128to64, // ditto, signed
290
291      /* Integer conversions.  Some of these are redundant (eg
292         Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
293         having a complete set reduces the typical dynamic size of IR
294         and makes the instruction selectors easier to write. */
295
296      /* Widening conversions */
297      Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
298                  Iop_16Uto32, Iop_16Uto64,
299                               Iop_32Uto64,
300      Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
301                  Iop_16Sto32, Iop_16Sto64,
302                               Iop_32Sto64,
303
304      /* Narrowing conversions */
305      Iop_64to8, Iop_32to8, Iop_64to16,
306      /* 8 <-> 16 bit conversions */
307      Iop_16to8,      // :: I16 -> I8, low half
308      Iop_16HIto8,    // :: I16 -> I8, high half
309      Iop_8HLto16,    // :: (I8,I8) -> I16
310      /* 16 <-> 32 bit conversions */
311      Iop_32to16,     // :: I32 -> I16, low half
312      Iop_32HIto16,   // :: I32 -> I16, high half
313      Iop_16HLto32,   // :: (I16,I16) -> I32
314      /* 32 <-> 64 bit conversions */
315      Iop_64to32,     // :: I64 -> I32, low half
316      Iop_64HIto32,   // :: I64 -> I32, high half
317      Iop_32HLto64,   // :: (I32,I32) -> I64
318      /* 64 <-> 128 bit conversions */
319      Iop_128to64,    // :: I128 -> I64, low half
320      Iop_128HIto64,  // :: I128 -> I64, high half
321      Iop_64HLto128,  // :: (I64,I64) -> I128
322      /* 1-bit stuff */
323      Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
324      Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
325      Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
326      Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
327      Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
328      Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
329      Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
330      Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
331      Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
332      Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
333
334      /* ------ Floating point.  We try and be IEEE754 compliant. ------ */
335
336      /* Binary operations mandated by IEEE754. */
337      Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */
338
339      /* Binary ops supported by IA32 but not mandated by 754. */
340      Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
341      Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
342      Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
343      Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
344      Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
345      Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
346      Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
347      Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
348      /* Note that on x86 guest, PRem1{C3210} has the same behaviour
349         as the IEEE mandated RemF64, except it is limited in the
350         range of its operand.  Hence the partialness. */
351
352      /* Unary operations mandated by IEEE754. */
353      Iop_NegF64, Iop_SqrtF64,
354
355      /* Unary ops supported by IA32 but not mandated by 754. */
356      Iop_AbsF64,    /* FABS */
357      Iop_SinF64,    /* FSIN */
358      Iop_CosF64,    /* FCOS */
359      Iop_TanF64,    /* FTAN */
360      Iop_2xm1F64,   /* (2^arg - 1.0) */
361
362      /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
363            0x45 Unordered
364            0x01 LT
365            0x00 GT
366            0x40 EQ
367         This just happens to be the Intel encoding.  The values
368         are recorded in the type IRCmpF64Result.
369      */
370      Iop_CmpF64,
371
372      /* --- Int to/from FP conversions. --- */
373      /* For the most part, these take a first argument :: Ity_I32
374         (as IRRoundingMode) which is an indication of the rounding
375         mode to use, as per the following encoding:
376            00b  to nearest (the default)
377            01b  to -infinity
378            10b  to +infinity
379            11b  to zero
380         This just happens to be the Intel encoding.  For reference only,
381         the PPC encoding is:
382            00b  to nearest (the default)
383            01b  to zero
384            10b  to +infinity
385            11b  to -infinity
386         Any PPC -> IR front end will have to translate these PPC
387         encodings to the standard encodings.
388
389         If one of these conversions gets an out-of-range condition,
390         or a NaN, as an argument, the result is host-defined.  On x86
391         the "integer indefinite" value 0x80..00 is produced.
392         On PPC it is either 0x80..00 or 0x7F..FF depending on the sign
393         of the argument.
394
395         Rounding is required whenever the destination type cannot
396         represent exactly all values of the source type.
397      */
398      Iop_F64toI16,  /* IRRoundingMode(I32) x F64 -> I16 */
399      Iop_F64toI32,  /* IRRoundingMode(I32) x F64 -> I32 */
400      Iop_F64toI64,  /* IRRoundingMode(I32) x F64 -> I64 */
401
402      Iop_I16toF64,  /*                       I16 -> F64 */
403      Iop_I32toF64,  /*                       I32 -> F64 */
404      Iop_I64toF64,  /* IRRoundingMode(I32) x I64 -> F64 */
405
406      Iop_F32toF64,  /*                       F32 -> F64 */
407      Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
408
409      /* F64 -> F64, also takes an I32 first argument encoding the
410         rounding mode. */
411      Iop_RoundF64,
412
413      /* Reinterpretation.  Take an F64 and produce an I64 with
414         the same bit pattern, or vice versa. */
415      Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
416      Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
417
418      /* ------------------ 64-bit SIMD Integer. ------------------ */
419
420      /* MISC (vector integer cmp != 0) */
421      Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
422
423      /* ADDITION (normal / unsigned sat / signed sat) */
424      Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
425      Iop_QAdd8Ux8, Iop_QAdd16Ux4,
426      Iop_QAdd8Sx8, Iop_QAdd16Sx4,
427
428      /* SUBTRACTION (normal / unsigned sat / signed sat) */
429      Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
430      Iop_QSub8Ux8, Iop_QSub16Ux4,
431      Iop_QSub8Sx8, Iop_QSub16Sx4,
432
433      /* MULTIPLICATION (normal / high half of signed/unsigned) */
434      Iop_Mul16x4,
435      Iop_MulHi16Ux4,
436      Iop_MulHi16Sx4,
437
438      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
439      Iop_Avg8Ux8,
440      Iop_Avg16Ux4,
441
442      /* MIN/MAX */
443      Iop_Max16Sx4,
444      Iop_Max8Ux8,
445      Iop_Min16Sx4,
446      Iop_Min8Ux8,
447
448      /* COMPARISON */
449      Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
450      Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
451
452      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
453      Iop_ShlN16x4, Iop_ShlN32x2,
454      Iop_ShrN16x4, Iop_ShrN32x2,
455      Iop_SarN16x4, Iop_SarN32x2,
456
457      /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */
458      Iop_QNarrow16Ux4,
459      Iop_QNarrow16Sx4,
460      Iop_QNarrow32Sx2,
461
462      /* INTERLEAVING -- interleave lanes from low or high halves of
463         operands.  Most-significant result lane is from the left
464         arg. */
465      Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
466      Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
467
468      /* ------------------ 128-bit SIMD FP. ------------------ */
469
470      /* --- 32x4 vector FP --- */
471
472      /* binary */
473      Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
474      Iop_Max32Fx4, Iop_Min32Fx4,
475      /* Note: For the following compares, the ppc32 front-end assumes a
476         nan in a lane of either argument returns zero for that lane. */
477      Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
478      Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
479
480      /* unary */
481      Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
482
483      /* --- Int to/from FP conversion --- */
484      /* Unlike the standard fp conversions, these irops take no
485         rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
486         indicate the mode: {-inf, +inf, nearest, zero} respectively. */
487      Iop_I32UtoFx4,     Iop_I32StoFx4,       /* I32x4 -> F32x4       */
488      Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ,   /* F32x4 -> I32x4       */
489      Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
490      Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
491
492      /* --- 32x4 lowest-lane-only scalar FP --- */
493
494      /* In binary cases, upper 3/4 is copied from first operand.  In
495         unary cases, upper 3/4 is copied from the operand. */
496
497      /* binary */
498      Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
499      Iop_Max32F0x4, Iop_Min32F0x4,
500      Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
501
502      /* unary */
503      Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
504
505      /* --- 64x2 vector FP --- */
506
507      /* binary */
508      Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
509      Iop_Max64Fx2, Iop_Min64Fx2,
510      Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
511
512      /* unary */
513      Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
514
515      /* --- 64x2 lowest-lane-only scalar FP --- */
516
517      /* In binary cases, upper half is copied from first operand.  In
518         unary cases, upper half is copied from the operand. */
519
520      /* binary */
521      Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
522      Iop_Max64F0x2, Iop_Min64F0x2,
523      Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
524
525      /* unary */
526      Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
527
528      /* --- pack / unpack --- */
529
530      /* 64 <-> 128 bit vector */
531      Iop_V128to64,     // :: V128 -> I64, low half
532      Iop_V128HIto64,   // :: V128 -> I64, high half
533      Iop_64HLtoV128,   // :: (I64,I64) -> V128
534
535      Iop_64UtoV128,
536      Iop_SetV128lo64,
537
538      /* 32 <-> 128 bit vector */
539      Iop_32UtoV128,
540      Iop_V128to32,     // :: V128 -> I32, lowest lane
541      Iop_SetV128lo32,  // :: (V128,I32) -> V128
542
543      /* ------------------ 128-bit SIMD Integer. ------------------ */
544
545      /* BITWISE OPS */
546      Iop_NotV128,
547      Iop_AndV128, Iop_OrV128, Iop_XorV128,
548
549      /* VECTOR SHIFT (shift amt :: Ity_I8) */
550      Iop_ShlV128, Iop_ShrV128,
551
552      /* MISC (vector integer cmp != 0) */
553      Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
554
555      /* ADDITION (normal / unsigned sat / signed sat) */
556      Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,  Iop_Add64x2,
557      Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4,
558      Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4,
559
560      /* SUBTRACTION (normal / unsigned sat / signed sat) */
561      Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,  Iop_Sub64x2,
562      Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4,
563      Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4,
564
565      /* MULTIPLICATION (normal / high half of signed/unsigned) */
566      Iop_Mul16x8,
567      Iop_MulHi16Ux8, Iop_MulHi32Ux4,
568      Iop_MulHi16Sx8, Iop_MulHi32Sx4,
569      /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
570      Iop_MullEven8Ux16, Iop_MullEven16Ux8,
571      Iop_MullEven8Sx16, Iop_MullEven16Sx8,
572
573      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
574      Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
575      Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
576
577      /* MIN/MAX */
578      Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
579      Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
580      Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
581      Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
582
583      /* COMPARISON */
584      Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,
585      Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
586      Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
587
588      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
589      Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
590      Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
591      Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4,
592
593      /* VECTOR x VECTOR SHIFT / ROTATE */
594      Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4,
595      Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4,
596      Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4,
597      Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
598
599      /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */
600      /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */
601      Iop_QNarrow16Ux8, Iop_QNarrow32Ux4,
602      Iop_QNarrow16Sx8, Iop_QNarrow32Sx4,
603      Iop_Narrow16x8, Iop_Narrow32x4,
604
605      /* INTERLEAVING -- interleave lanes from low or high halves of
606         operands.  Most-significant result lane is from the left
607         arg. */
608      Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
609      Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
610      Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
611      Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
612
613      /* DUPLICATING -- copy value to all lanes */
614      Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
615
616      /* PERMUTING -- copy src bytes to dst,
617         as indexed by control vector bytes:
618            for i in 0 .. 15 . result[i] = argL[ argR[i] ]
619         argR[i] values may only be in the range 0 .. 15, else behaviour
620         is undefined. */
621      Iop_Perm8x16
622   }
623   IROp;
624
625extern void ppIROp ( IROp );
626
627
628/* Encoding of IEEE754-specified rounding modes in Float -> Int
629   conversions.  This is the same as the encoding used by Intel IA32
630   to indicate x87 rounding mode. */
631typedef
632   enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 }
633   IRRoundingMode;
634
635/* Floating point comparison result values, as created by Iop_CmpF64.
636   This is also derived from what IA32 does. */
637typedef
638   enum {
639      Ircr_UN = 0x45,
640      Ircr_LT = 0x01,
641      Ircr_GT = 0x00,
642      Ircr_EQ = 0x40
643   }
644   IRCmpF64Result;
645
646
647/* ------------------ Expressions ------------------ */
648/*
649   Some details of expression semantics:
650
651   IRExpr_GetI (also IRStmt_PutI)
652   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
653   These allow circular indexing into parts of the guest state, which
654   is essential for modelling situations where the identity of guest
655   registers is not known until run time.  One example is the x87 FP
656   register stack.
657
658   The part of the guest state to be treated as a circular array is
659   described in an IRArray structure attached to the GetI/PutI.
660   IRArray holds the offset of the first element in the array, the
661   type of each element, and the number of elements.
662
663   The array index is indicated rather indirectly, in a way which
664   makes optimisation easy: as the sum of variable part (the 'ix'
665   field) and a constant offset (the 'bias' field).
666
667   Since the indexing is circular, the actual array index to use
668   is computed as (ix + bias) % number-of-elements-in-the-array.
669
670   Here's an example.  The description
671
672      (96:8xF64)[t39,-7]
673
674   describes an array of 8 F64-typed values, the guest-state-offset
675   of the first being 96.  This array is being indexed at
676   (t39 - 7) % 8.
677
678   It is important to get the array size/type exactly correct since IR
679   optimisation looks closely at such info in order to establish
680   aliasing/non-aliasing between seperate GetI and PutI events, which
681   is used to establish when they can be reordered, etc.  Putting
682   incorrect info in will lead to obscure IR optimisation bugs.
683
684   IRExpr_CCall
685   ~~~~~~~~~~~~
686   The name is the C helper function; the backends will call back to
687   the front ends to get the address of a host-code helper function to
688   be called.
689
690   The args are a NULL-terminated array of arguments.  The stated
691   return IRType, and the implied argument types, must match that of
692   the function being called well enough so that the back end can
693   actually generate correct code for the call.
694
695   The called function **must** satisfy the following:
696
697   * no side effects -- must be a pure function, the result of which
698     depends only on the passed parameters.
699
700   * it may not look at, nor modify, any of the guest state since that
701     would hide guest state transitions from instrumenters
702
703   * it may not access guest memory, since that would hide guest
704     memory transactions from the instrumenters
705
706   This is restrictive, but makes the semantics clean, and does
707   not interfere with IR optimisation.
708
709   If you want to call a helper which can mess with guest state and/or
710   memory, instead use IRStmt_Dirty.  This is a lot more flexible, but
711   you pay for that flexibility in that you have to give a bunch of
712   details about what the helper does (and you better be telling the
713   truth, otherwise any derived instrumentation will be wrong).  Also
714   IRStmt_Dirty inhibits various IR optimisations and so can cause
715   quite poor code to be generated.  Try to avoid it.  */
716
717/* The possible kinds of expressions are as follows: */
718typedef
719   enum {
720      Iex_Binder,  /* Used only in pattern matching.
721                      Not an expression. */
722      Iex_Get,     /* read guest state, fixed offset */
723      Iex_GetI,    /* read guest state, run-time offset */
724      Iex_Tmp,     /* value of temporary */
725      Iex_Binop,   /* binary operation */
726      Iex_Unop,    /* unary operation */
727      Iex_Load,    /* read from memory */
728      Iex_Const,   /* constant-valued expression */
729      Iex_Mux0X,   /* ternary if-then-else operator (STRICT) */
730      Iex_CCall    /* call to pure (side-effect-free) helper fn */
731   }
732   IRExprTag;
733
734typedef
735   struct _IRExpr {
736      IRExprTag tag;
737      union {
738         struct {
739            Int binder;
740         } Binder;
741         struct {
742            Int    offset;
743            IRType ty;
744         } Get;
745         struct {
746            IRArray* descr;
747            struct _IRExpr* ix;
748            Int bias;
749         } GetI;
750         struct {
751            IRTemp tmp;
752         } Tmp;
753         struct {
754            IROp op;
755            struct _IRExpr* arg1;
756            struct _IRExpr* arg2;
757         } Binop;
758         struct {
759            IROp op;
760            struct _IRExpr* arg;
761         } Unop;
762         struct {
763            IREndness end;
764            IRType ty;
765            struct _IRExpr* addr;
766         } Load;
767         struct {
768            IRConst* con;
769         } Const;
770         struct {
771            IRCallee* cee;
772            IRType    retty;
773            struct _IRExpr** args;
774         }  CCall;
775         struct {
776            struct _IRExpr* cond;
777            struct _IRExpr* expr0;
778            struct _IRExpr* exprX;
779         } Mux0X;
780      } Iex;
781   }
782   IRExpr;
783
784extern IRExpr* IRExpr_Binder ( Int binder );
785extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
786extern IRExpr* IRExpr_GetI   ( IRArray* descr, IRExpr* ix, Int bias );
787extern IRExpr* IRExpr_Tmp    ( IRTemp tmp );
788extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
789extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
790extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
791extern IRExpr* IRExpr_Const  ( IRConst* con );
792extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
793extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
794
795extern IRExpr* dopyIRExpr ( IRExpr* );
796
797extern void ppIRExpr ( IRExpr* );
798
799/* NULL-terminated IRExpr expression vectors, suitable for use as arg
800   lists in clean/dirty helper calls. */
801
802extern IRExpr** mkIRExprVec_0 ( void );
803extern IRExpr** mkIRExprVec_1 ( IRExpr* );
804extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
805extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
806extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
807extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*,
808                                IRExpr*, IRExpr*, IRExpr* );
809
810extern IRExpr** sopyIRExprVec ( IRExpr** );
811extern IRExpr** dopyIRExprVec ( IRExpr** );
812
813/* Make a constant expression from the given host word taking into
814   account of course the host word size. */
815extern IRExpr* mkIRExpr_HWord ( HWord );
816
817/* Convenience function for constructing clean helper calls. */
818extern
819IRExpr* mkIRExprCCall ( IRType retty,
820                        Int regparms, HChar* name, void* addr,
821                        IRExpr** args );
822
823
824/* Convenience functions for atoms, that is, IRExprs which
825   are either Iex_Tmp or Iex_Const. */
826static inline Bool isIRAtom ( IRExpr* e ) {
827   return toBool(e->tag == Iex_Tmp || e->tag == Iex_Const);
828}
829
830/* Are these two IR atoms identical?  Causes an assertion
831   failure if they are passed non-atoms. */
832extern Bool eqIRAtom ( IRExpr*, IRExpr* );
833
834
835/* ------------------ Jump kinds ------------------ */
836
837/* This describes hints which can be passed to the dispatcher at guest
838   control-flow transfer points.
839
840   Re Ijk_Invalidate: the guest state _must_ have two
841   pseudo-registers, guest_TISTART and guest_TILEN, which specify the
842   start and length of the region to be invalidated.  These are both
843   the size of a guest word. It is the responsibility of the relevant
844   toIR.c to ensure that these are filled in with suitable values
845   before issuing a jump of kind Ijk_TInval.
846*/
847typedef
848   enum {
849      Ijk_Boring=0x14000, /* not interesting; just goto next */
850      Ijk_Call,           /* guest is doing a call */
851      Ijk_Ret,            /* guest is doing a return */
852      Ijk_ClientReq,      /* do guest client req before continuing */
853      Ijk_Yield,          /* client is yielding to thread scheduler */
854      Ijk_EmWarn,         /* report emulation warning before continuing */
855      Ijk_NoDecode,       /* next instruction cannot be decoded */
856      Ijk_MapFail,        /* Vex-provided address translation failed */
857      Ijk_TInval,         /* Invalidate translations before continuing. */
858      /* Unfortunately, various guest-dependent syscall kinds.  They
859	 all mean: do a syscall before continuing. */
860      Ijk_Sys_syscall,    /* amd64 'syscall', ppc32 'sc' */
861      Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
862      Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
863      Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes
864                             invalid at the point this happens. */
865   }
866   IRJumpKind;
867
868extern void ppIRJumpKind ( IRJumpKind );
869
870
871/* ------------------ Dirty helper calls ------------------ */
872
873/* A dirty call is a flexible mechanism for calling a helper function
874   or procedure.  The helper function may read, write or modify client
875   memory, and may read, write or modify client state.  It can take
876   arguments and optionally return a value.  It may return different
877   results and/or do different things when called repeated with the
878   same arguments, by means of storing private state.
879
880   If a value is returned, it is assigned to the nominated return
881   temporary.
882
883   Dirty calls are statements rather than expressions for obvious
884   reasons.  If a dirty call is stated as writing guest state, any
885   values derived from the written parts of the guest state are
886   invalid.  Similarly, if the dirty call is stated as writing
887   memory, any loaded values are invalidated by it.
888
889   In order that instrumentation is possible, the call must state, and
890   state correctly
891
892   * whether it reads, writes or modifies memory, and if so where
893     (only one chunk can be stated)
894
895   * whether it reads, writes or modifies guest state, and if so which
896     pieces (several pieces may be stated, and currently their extents
897     must be known at translation-time).
898
899   Normally, code is generated to pass just the args to the helper.
900   However, if .needsBBP is set, then an extra first argument is
901   passed, which is the baseblock pointer, so that the callee can
902   access the guest state.  It is invalid for .nFxState to be zero
903   but .needsBBP to be True, since .nFxState==0 is a claim that the
904   call does not access guest state.
905
906   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
907   arguments are evaluated REGARDLESS of the guard value.  It is
908   unspecified the relative order of arg evaluation and guard
909   evaluation.
910*/
911
912#define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
913
914typedef
915   enum {
916      Ifx_None = 0x15000,   /* no effect */
917      Ifx_Read,             /* reads the resource */
918      Ifx_Write,            /* writes the resource */
919      Ifx_Modify,           /* modifies the resource */
920   }
921   IREffect;
922
923extern void ppIREffect ( IREffect );
924
925
926typedef
927   struct {
928      /* What to call, and details of args/results */
929      IRCallee* cee;    /* where to call */
930      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
931      IRExpr**  args;   /* arg list, ends in NULL */
932      IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
933
934      /* Mem effects; we allow only one R/W/M region to be stated */
935      IREffect  mFx;    /* indicates memory effects, if any */
936      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
937      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
938
939      /* Guest state effects; up to N allowed */
940      Bool needsBBP; /* True => also pass guest state ptr to callee */
941      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
942      struct {
943         IREffect fx;   /* read, write or modify?  Ifx_None is invalid. */
944         Int      offset;
945         Int      size;
946      } fxState[VEX_N_FXSTATE];
947   }
948   IRDirty;
949
950extern void     ppIRDirty ( IRDirty* );
951extern IRDirty* emptyIRDirty ( void );
952
953extern IRDirty* dopyIRDirty ( IRDirty* );
954
955/* A handy function which takes some of the tedium out of constructing
956   dirty helper calls.  The called function impliedly does not return
957   any value and has a constant-True guard.  The call is marked as
958   accessing neither guest state nor memory (hence the "unsafe"
959   designation) -- you can mess with this later if need be.  A
960   suitable IRCallee is constructed from the supplied bits. */
961extern
962IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
963                             IRExpr** args );
964
965/* Similarly, make a zero-annotation dirty call which returns a value,
966   and assign that to the given temp. */
967extern
968IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
969                             Int regparms, HChar* name, void* addr,
970                             IRExpr** args );
971
972
973/* ------------------ Statements ------------------ */
974
975/* The possible kinds of statements are as follows.  Those marked
976   OPTIONAL are hints of one kind or another, and as such do not
977   denote any change in the guest state or of IR temporaries.  They
978   can therefore be omitted without changing the meaning denoted by
979   the IR.
980
981   At the moment, the only AbiHint is one which indicates that a given
982   chunk of address space has become undefined.  This is used on
983   amd64-linux to pass stack-redzoning hints to whoever wants to see
984   them.
985*/
986typedef
987   enum {
988      Ist_NoOp,    /* OPTIONAL: no-op (usually resulting from IR
989                      optimisation) */
990      Ist_IMark,   /* OPTIONAL: instruction mark: describe addr/len of
991                      guest insn whose IR follows.  */
992      Ist_AbiHint, /* OPTIONAL: tell me something about this
993                      platform's ABI */
994      Ist_Put,     /* write guest state, fixed offset */
995      Ist_PutI,    /* write guest state, run-time offset */
996      Ist_Tmp,     /* assign value to temporary */
997      Ist_Store,   /* write to memory */
998      Ist_Dirty,   /* call complex ("dirty") helper function */
999      Ist_MFence,  /* memory fence */
1000      Ist_Exit     /* conditional exit from BB */
1001   }
1002   IRStmtTag;
1003
1004typedef
1005   struct _IRStmt {
1006      IRStmtTag tag;
1007      union {
1008         struct {
1009	 } NoOp;
1010         struct {
1011            Addr64 addr;
1012            Int    len;
1013         } IMark;
1014         struct {
1015            /* [base .. base+len-1] has become uninitialised */
1016            IRExpr* base;
1017            Int     len;
1018         } AbiHint;
1019         struct {
1020            Int     offset;
1021            IRExpr* data;
1022         } Put;
1023         struct {
1024            IRArray* descr;
1025            IRExpr*  ix;
1026            Int      bias;
1027            IRExpr*  data;
1028         } PutI;
1029         struct {
1030            IRTemp  tmp;
1031            IRExpr* data;
1032         } Tmp;
1033         struct {
1034            IREndness end;
1035            IRExpr*   addr;
1036            IRExpr*   data;
1037         } Store;
1038         struct {
1039            IRDirty* details;
1040         } Dirty;
1041         struct {
1042         } MFence;
1043         struct {
1044            IRExpr*    guard;
1045            IRJumpKind jk;
1046            IRConst*   dst;
1047         } Exit;
1048      } Ist;
1049   }
1050   IRStmt;
1051
1052extern IRStmt* IRStmt_NoOp    ( void );
1053extern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len );
1054extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len );
1055extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
1056extern IRStmt* IRStmt_PutI    ( IRArray* descr, IRExpr* ix, Int bias,
1057                                IRExpr* data );
1058extern IRStmt* IRStmt_Tmp     ( IRTemp tmp, IRExpr* data );
1059extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
1060extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
1061extern IRStmt* IRStmt_MFence  ( void );
1062extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
1063
1064extern IRStmt* dopyIRStmt ( IRStmt* );
1065
1066extern void ppIRStmt ( IRStmt* );
1067
1068
1069/* ------------------ Basic Blocks ------------------ */
1070
1071/* A bunch of statements, expressions, etc, are incomplete without an
1072   environment indicating the type of each IRTemp.  So this provides
1073   one.  IR temporaries are really just unsigned ints and so this
1074   provides an array, 0 .. n_types_used-1 of them.
1075*/
1076typedef
1077   struct {
1078      IRType* types;
1079      Int     types_size;
1080      Int     types_used;
1081   }
1082   IRTypeEnv;
1083
1084extern IRTemp     newIRTemp     ( IRTypeEnv*, IRType );
1085extern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* );
1086
1087extern void ppIRTypeEnv ( IRTypeEnv* );
1088
1089
1090/* Basic blocks contain:
1091   - A table giving a type for each temp
1092   - An expandable array of statements
1093   - An expression of type 32 or 64 bits, depending on the
1094     guest's word size, indicating the next destination.
1095   - An indication of any special actions (JumpKind) needed
1096     for this final jump.
1097*/
1098typedef
1099   struct _IRBB {
1100      IRTypeEnv* tyenv;
1101      IRStmt**   stmts;
1102      Int        stmts_size;
1103      Int        stmts_used;
1104      IRExpr*    next;
1105      IRJumpKind jumpkind;
1106   }
1107   IRBB;
1108
1109extern IRBB* emptyIRBB ( void );
1110
1111extern IRBB* dopyIRBB ( IRBB* );
1112
1113extern void ppIRBB ( IRBB* );
1114
1115extern void addStmtToIRBB ( IRBB*, IRStmt* );
1116
1117
1118/*---------------------------------------------------------------*/
1119/*--- Helper functions for the IR                             ---*/
1120/*---------------------------------------------------------------*/
1121
1122/* For messing with IR type environments */
1123extern IRTypeEnv* emptyIRTypeEnv  ( void );
1124
1125/* What is the type of this expression? */
1126extern IRType typeOfIRConst ( IRConst* );
1127extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
1128extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
1129
1130/* Sanity check a BB of IR */
1131extern void sanityCheckIRBB ( IRBB*  bb,
1132                              HChar* caller,
1133                              Bool   require_flatness,
1134                              IRType guest_word_size );
1135extern Bool isFlatIRStmt ( IRStmt* );
1136
1137/* Is this any value actually in the enumeration 'IRType' ? */
1138extern Bool isPlausibleIRType ( IRType ty );
1139
1140#endif /* ndef __LIBVEX_IR_H */
1141
1142
1143/*---------------------------------------------------------------*/
1144/*---                                             libvex_ir.h ---*/
1145/*---------------------------------------------------------------*/
1146