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