Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:30

0001 
0002 /*---------------------------------------------------------------*/
0003 /*--- begin                                       libvex_ir.h ---*/
0004 /*---------------------------------------------------------------*/
0005 
0006 /*
0007    This file is part of Valgrind, a dynamic binary instrumentation
0008    framework.
0009 
0010    Copyright (C) 2004-2017 OpenWorks LLP
0011       info@open-works.net
0012 
0013    This program is free software; you can redistribute it and/or
0014    modify it under the terms of the GNU General Public License as
0015    published by the Free Software Foundation; either version 2 of the
0016    License, or (at your option) any later version.
0017 
0018    This program is distributed in the hope that it will be useful, but
0019    WITHOUT ANY WARRANTY; without even the implied warranty of
0020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0021    General Public License for more details.
0022 
0023    You should have received a copy of the GNU General Public License
0024    along with this program; if not, see <http://www.gnu.org/licenses/>.
0025 
0026    The GNU General Public License is contained in the file COPYING.
0027 
0028    Neither the names of the U.S. Department of Energy nor the
0029    University of California nor the names of its contributors may be
0030    used to endorse or promote products derived from this software
0031    without prior written permission.
0032 */
0033 
0034 #ifndef __LIBVEX_IR_H
0035 #define __LIBVEX_IR_H
0036 
0037 #include "libvex_basictypes.h"
0038 
0039    
0040 /*---------------------------------------------------------------*/
0041 /*--- High-level IR description                               ---*/
0042 /*---------------------------------------------------------------*/
0043 
0044 /* Vex IR is an architecture-neutral intermediate representation.
0045    Unlike some IRs in systems similar to Vex, it is not like assembly
0046    language (ie. a list of instructions).  Rather, it is more like the
0047    IR that might be used in a compiler.
0048 
0049    Code blocks
0050    ~~~~~~~~~~~
0051    The code is broken into small code blocks ("superblocks", type:
0052    'IRSB').  Each code block typically represents from 1 to perhaps 50
0053    instructions.  IRSBs are single-entry, multiple-exit code blocks.
0054    Each IRSB contains three things:
0055    - a type environment, which indicates the type of each temporary
0056      value present in the IRSB
0057    - a list of statements, which represent code
0058    - a jump that exits from the end the IRSB
0059    Because the blocks are multiple-exit, there can be additional
0060    conditional exit statements that cause control to leave the IRSB
0061    before the final exit.  Also because of this, IRSBs can cover
0062    multiple non-consecutive sequences of code (up to 3).  These are
0063    recorded in the type VexGuestExtents (see libvex.h).
0064 
0065    Statements and expressions
0066    ~~~~~~~~~~~~~~~~~~~~~~~~~~
0067    Statements (type 'IRStmt') represent operations with side-effects,
0068    eg.  guest register writes, stores, and assignments to temporaries.
0069    Expressions (type 'IRExpr') represent operations without
0070    side-effects, eg. arithmetic operations, loads, constants.
0071    Expressions can contain sub-expressions, forming expression trees,
0072    eg. (3 + (4 * load(addr1)).
0073 
0074    Storage of guest state
0075    ~~~~~~~~~~~~~~~~~~~~~~
0076    The "guest state" contains the guest registers of the guest machine
0077    (ie.  the machine that we are simulating).  It is stored by default
0078    in a block of memory supplied by the user of the VEX library,
0079    generally referred to as the guest state (area).  To operate on
0080    these registers, one must first read ("Get") them from the guest
0081    state into a temporary value.  Afterwards, one can write ("Put")
0082    them back into the guest state.
0083 
0084    Get and Put are characterised by a byte offset into the guest
0085    state, a small integer which effectively gives the identity of the
0086    referenced guest register, and a type, which indicates the size of
0087    the value to be transferred.
0088 
0089    The basic "Get" and "Put" operations are sufficient to model normal
0090    fixed registers on the guest.  Selected areas of the guest state
0091    can be treated as a circular array of registers (type:
0092    'IRRegArray'), which can be indexed at run-time.  This is done with
0093    the "GetI" and "PutI" primitives.  This is necessary to describe
0094    rotating register files, for example the x87 FPU stack, SPARC
0095    register windows, and the Itanium register files.
0096 
0097    Examples, and flattened vs. unflattened code
0098    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0099    For example, consider this x86 instruction:
0100      
0101      addl %eax, %ebx
0102 
0103    One Vex IR translation for this code would be this:
0104 
0105      ------ IMark(0x24F275, 7, 0) ------
0106      t3 = GET:I32(0)             # get %eax, a 32-bit integer
0107      t2 = GET:I32(12)            # get %ebx, a 32-bit integer
0108      t1 = Add32(t3,t2)           # addl
0109      PUT(0) = t1                 # put %eax
0110 
0111    (For simplicity, this ignores the effects on the condition codes, and
0112    the update of the instruction pointer.)
0113 
0114    The "IMark" is an IR statement that doesn't represent actual code.
0115    Instead it indicates the address and length of the original
0116    instruction.  The numbers 0 and 12 are offsets into the guest state
0117    for %eax and %ebx.  The full list of offsets for an architecture
0118    <ARCH> can be found in the type VexGuest<ARCH>State in the file
0119    VEX/pub/libvex_guest_<ARCH>.h.
0120 
0121    The five statements in this example are:
0122    - the IMark
0123    - three assignments to temporaries
0124    - one register write (put)
0125 
0126    The six expressions in this example are:
0127    - two register reads (gets)
0128    - one arithmetic (add) operation
0129    - three temporaries (two nested within the Add32, one in the PUT)
0130 
0131    The above IR is "flattened", ie. all sub-expressions are "atoms",
0132    either constants or temporaries.  An equivalent, unflattened version
0133    would be:
0134    
0135      PUT(0) = Add32(GET:I32(0), GET:I32(12))
0136 
0137    IR is guaranteed to be flattened at instrumentation-time.  This makes
0138    instrumentation easier.  Equivalent flattened and unflattened IR
0139    typically results in the same generated code.
0140 
0141    Another example, this one showing loads and stores:
0142 
0143      addl %edx,4(%eax)
0144 
0145    This becomes (again ignoring condition code and instruction pointer
0146    updates):
0147 
0148      ------ IMark(0x4000ABA, 3, 0) ------
0149      t3 = Add32(GET:I32(0),0x4:I32)
0150      t2 = LDle:I32(t3)
0151      t1 = GET:I32(8)
0152      t0 = Add32(t2,t1)
0153      STle(t3) = t0
0154 
0155    The "le" in "LDle" and "STle" is short for "little-endian".
0156 
0157    No need for deallocations
0158    ~~~~~~~~~~~~~~~~~~~~~~~~~
0159    Although there are allocation functions for various data structures
0160    in this file, there are no deallocation functions.  This is because
0161    Vex uses a memory allocation scheme that automatically reclaims the
0162    memory used by allocated structures once translation is completed.
0163    This makes things easier for tools that instruments/transforms code
0164    blocks.
0165 
0166    SSAness and typing
0167    ~~~~~~~~~~~~~~~~~~
0168    The IR is fully typed.  For every IRSB (IR block) it is possible to
0169    say unambiguously whether or not it is correctly typed.
0170    Incorrectly typed IR has no meaning and the VEX will refuse to
0171    process it.  At various points during processing VEX typechecks the
0172    IR and aborts if any violations are found.  This seems overkill but
0173    makes it a great deal easier to build a reliable JIT.
0174 
0175    IR also has the SSA property.  SSA stands for Static Single
0176    Assignment, and what it means is that each IR temporary may be
0177    assigned to only once.  This idea became widely used in compiler
0178    construction in the mid to late 90s.  It makes many IR-level
0179    transformations/code improvements easier, simpler and faster.
0180    Whenever it typechecks an IR block, VEX also checks the SSA
0181    property holds, and will abort if not so.  So SSAness is
0182    mechanically and rigidly enforced.
0183 */
0184 
0185 /*---------------------------------------------------------------*/
0186 /*--- Type definitions for the IR                             ---*/
0187 /*---------------------------------------------------------------*/
0188 
0189 /* General comments about naming schemes:
0190 
0191    All publically visible functions contain the name of the primary
0192    type on which they operate (IRFoo, IRBar, etc).  Hence you should
0193    be able to identify these functions by grepping for "IR[A-Z]".
0194 
0195    For some type 'IRFoo':
0196 
0197    - ppIRFoo is the printing method for IRFoo, printing it to the
0198      output channel specified in the LibVEX_Initialise call.
0199 
0200    - eqIRFoo is a structural equality predicate for IRFoos.
0201 
0202    - deepCopyIRFoo is a deep copy constructor for IRFoos. 
0203      It recursively traverses the entire argument tree and
0204      produces a complete new tree.  All types have a deep copy
0205      constructor.
0206 
0207    - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
0208      It creates a new top-level copy of the supplied object,
0209      but does not copy any sub-objects.  Only some types have a
0210      shallow copy constructor.
0211 */
0212 
0213 /* ------------------ Types ------------------ */
0214 
0215 /* A type indicates the size of a value, and whether it's an integer, a
0216    float, or a vector (SIMD) value. */
0217 typedef 
0218    enum { 
0219       Ity_INVALID=0x1100,
0220       Ity_I1, 
0221       Ity_I8, 
0222       Ity_I16, 
0223       Ity_I32, 
0224       Ity_I64,
0225       Ity_I128,  /* 128-bit scalar */
0226       Ity_F16,   /* 16 bit float */
0227       Ity_F32,   /* IEEE 754 float */
0228       Ity_F64,   /* IEEE 754 double */
0229       Ity_D32,   /* 32-bit Decimal floating point */
0230       Ity_D64,   /* 64-bit Decimal floating point */
0231       Ity_D128,  /* 128-bit Decimal floating point */
0232       Ity_F128,  /* 128-bit floating point; implementation defined */
0233       Ity_V128,  /* 128-bit SIMD */
0234       Ity_V256   /* 256-bit SIMD */
0235    }
0236    IRType;
0237 
0238 /* Pretty-print an IRType */
0239 extern void ppIRType ( IRType );
0240 
0241 /* Get the size (in bytes) of an IRType */ 
0242 extern Int sizeofIRType ( IRType );
0243 
0244 /* Translate 1/2/4/8 into Ity_I{8,16,32,64} respectively.  Asserts on
0245    any other input. */
0246 extern IRType integerIRTypeOfSize ( Int szB );
0247 
0248 
0249 /* ------------------ Endianness ------------------ */
0250 
0251 /* IREndness is used in load IRExprs and store IRStmts. */
0252 typedef
0253    enum { 
0254       Iend_LE=0x1200, /* little endian */
0255       Iend_BE          /* big endian */
0256    }
0257    IREndness;
0258 
0259 
0260 /* ------------------ Constants ------------------ */
0261 
0262 /* IRConsts are used within 'Const' and 'Exit' IRExprs. */
0263 
0264 /* The various kinds of constant. */
0265 typedef
0266    enum { 
0267       Ico_U1=0x1300,
0268       Ico_U8, 
0269       Ico_U16, 
0270       Ico_U32, 
0271       Ico_U64,
0272       Ico_U128,  /* 128-bit restricted integer constant,
0273                     same encoding scheme as V128 */
0274       Ico_F32,   /* 32-bit IEEE754 floating */
0275       Ico_F32i,  /* 32-bit unsigned int to be interpreted literally
0276                     as a IEEE754 single value. */
0277       Ico_F64,   /* 64-bit IEEE754 floating */
0278       Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
0279                     as a IEEE754 double value. */
0280       Ico_V128,  /* 128-bit restricted vector constant, with 1 bit
0281                     (repeated 8 times) for each of the 16 x 1-byte lanes */
0282       Ico_V256   /* 256-bit restricted vector constant, with 1 bit
0283                     (repeated 8 times) for each of the 32 x 1-byte lanes */
0284    }
0285    IRConstTag;
0286 
0287 /* A constant.  Stored as a tagged union.  'tag' indicates what kind of
0288    constant this is.  'Ico' is the union that holds the fields.  If an
0289    IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
0290    and its value can be accessed with 'c.Ico.U32'. */
0291 typedef
0292    struct _IRConst {
0293       IRConstTag tag;
0294       union {
0295          Bool   U1;
0296          UChar  U8;
0297          UShort U16;
0298          UInt   U32;
0299          ULong  U64;
0300          UShort U128;
0301          Float  F32;
0302          UInt   F32i;
0303          Double F64;
0304          ULong  F64i;
0305          UShort V128;   /* 16-bit value; see Ico_V128 comment above */
0306          UInt   V256;   /* 32-bit value; see Ico_V256 comment above */
0307       } Ico;
0308    }
0309    IRConst;
0310 
0311 /* IRConst constructors */
0312 extern IRConst* IRConst_U1   ( Bool );
0313 extern IRConst* IRConst_U8   ( UChar );
0314 extern IRConst* IRConst_U16  ( UShort );
0315 extern IRConst* IRConst_U32  ( UInt );
0316 extern IRConst* IRConst_U64  ( ULong );
0317 extern IRConst* IRConst_U128 ( UShort );
0318 extern IRConst* IRConst_F32  ( Float );
0319 extern IRConst* IRConst_F32i ( UInt );
0320 extern IRConst* IRConst_F64  ( Double );
0321 extern IRConst* IRConst_F64i ( ULong );
0322 extern IRConst* IRConst_V128 ( UShort );
0323 extern IRConst* IRConst_V256 ( UInt );
0324 
0325 /* Deep-copy an IRConst */
0326 extern IRConst* deepCopyIRConst ( const IRConst* );
0327 
0328 /* Pretty-print an IRConst */
0329 extern void ppIRConst ( const IRConst* );
0330 
0331 /* Compare two IRConsts for equality */
0332 extern Bool eqIRConst ( const IRConst*, const IRConst* );
0333 
0334 
0335 /* ------------------ Call targets ------------------ */
0336 
0337 /* Describes a helper function to call.  The name part is purely for
0338    pretty printing and not actually used.  regparms=n tells the back
0339    end that the callee has been declared
0340    "__attribute__((regparm(n)))", although indirectly using the
0341    VEX_REGPARM(n) macro.  On some targets (x86) the back end will need
0342    to construct a non-standard sequence to call a function declared
0343    like this.
0344 
0345    mcx_mask is a sop to Memcheck.  It indicates which args should be
0346    considered 'always defined' when lazily computing definedness of
0347    the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
0348    args[1], etc.  If a bit is set, the corresponding arg is excluded
0349    (hence "x" in "mcx") from definedness checking.  
0350 */
0351 
0352 typedef
0353    struct {
0354       Int          regparms;
0355       const HChar* name;
0356       void*        addr;
0357       UInt         mcx_mask;
0358    }
0359    IRCallee;
0360 
0361 /* Create an IRCallee. */
0362 extern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr );
0363 
0364 /* Deep-copy an IRCallee. */
0365 extern IRCallee* deepCopyIRCallee ( const IRCallee* );
0366 
0367 /* Pretty-print an IRCallee. */
0368 extern void ppIRCallee ( const IRCallee* );
0369 
0370 
0371 /* ------------------ Guest state arrays ------------------ */
0372 
0373 /* This describes a section of the guest state that we want to
0374    be able to index at run time, so as to be able to describe 
0375    indexed or rotating register files on the guest. */
0376 typedef
0377    struct {
0378       Int    base;   /* guest state offset of start of indexed area */
0379       IRType elemTy; /* type of each element in the indexed area */
0380       Int    nElems; /* number of elements in the indexed area */
0381    }
0382    IRRegArray;
0383 
0384 extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
0385 
0386 extern IRRegArray* deepCopyIRRegArray ( const IRRegArray* );
0387 
0388 extern void ppIRRegArray ( const IRRegArray* );
0389 extern Bool eqIRRegArray ( const IRRegArray*, const IRRegArray* );
0390 
0391 
0392 /* ------------------ Temporaries ------------------ */
0393 
0394 /* This represents a temporary, eg. t1.  The IR optimiser relies on the
0395    fact that IRTemps are 32-bit ints.  Do not change them to be ints of
0396    any other size. */
0397 typedef UInt IRTemp;
0398 
0399 /* Pretty-print an IRTemp. */
0400 extern void ppIRTemp ( IRTemp );
0401 
0402 #define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
0403 
0404 
0405 /* --------------- Primops (arity 1,2,3 and 4) --------------- */
0406 
0407 /* Primitive operations that are used in Unop, Binop, Triop and Qop
0408    IRExprs.  Once we take into account integer, floating point and SIMD
0409    operations of all the different sizes, there are quite a lot of them.
0410    Most instructions supported by the architectures that Vex supports
0411    (x86, PPC, etc) are represented.  Some more obscure ones (eg. cpuid)
0412    are not;  they are instead handled with dirty helpers that emulate
0413    their functionality.  Such obscure ones are thus not directly visible
0414    in the IR, but their effects on guest state (memory and registers) 
0415    are made visible via the annotations in IRDirty structures.
0416 
0417    2018-Dec-27: some of int<->fp conversion operations have been renamed so as
0418    to have a trailing _DEP, meaning "deprecated".  This is because they don't
0419    specify a rounding mode to be used for the conversion and so are
0420    underspecified.  Their use should be replaced with equivalents that do
0421    specify a rounding mode, either as a first argument or using a suffix on the
0422    name, that indicates the rounding mode to use.
0423 */
0424 typedef
0425    enum { 
0426       /* -- Do not change this ordering.  The IR generators rely on
0427             (eg) Iop_Add64 == IopAdd8 + 3. -- */
0428 
0429       Iop_INVALID=0x1400,
0430       Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
0431       Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
0432       /* Signless mul.  MullS/MullU is elsewhere. */
0433       Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
0434       Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
0435       Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
0436       Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
0437       Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
0438       Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
0439       Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
0440       /* Integer comparisons. */
0441       Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
0442       Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
0443       /* Tags for unary ops */
0444       Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
0445 
0446       /* Exactly like CmpEQ8/16/32/64, but carrying the additional
0447          hint that these compute the success/failure of a CAS
0448          operation, and hence are almost certainly applied to two
0449          copies of the same value, which in turn has implications for
0450          Memcheck's instrumentation. */
0451       Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
0452       Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
0453 
0454       /* Exactly like CmpNE8/16/32/64, but carrying the additional
0455          hint that these needs expensive definedness tracking. */
0456       Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
0457 
0458       /* -- Ordering not important after here. -- */
0459 
0460       /* Widening multiplies */
0461       Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
0462       Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
0463 
0464       /* Counting bits */
0465       /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of zero.
0466          You must ensure they are never given a zero argument.  As of
0467          2018-Nov-14 they are deprecated.  Try to use the Nat variants
0468          immediately below, if you can.
0469       */
0470       Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
0471       Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
0472       /* Count leading/trailing zeroes, with "natural" semantics for the
0473          case where the input is zero: then the result is the number of bits
0474          in the word. */
0475       Iop_ClzNat64, Iop_ClzNat32,
0476       Iop_CtzNat64, Iop_CtzNat32,
0477       /* Population count -- compute the number of 1 bits in the argument. */
0478       Iop_PopCount64, Iop_PopCount32,
0479 
0480       /* Standard integer comparisons */
0481       Iop_CmpLT32S, Iop_CmpLT64S,
0482       Iop_CmpLE32S, Iop_CmpLE64S,
0483       Iop_CmpLT32U, Iop_CmpLT64U,
0484       Iop_CmpLE32U, Iop_CmpLE64U,
0485 
0486       /* As a sop to Valgrind-Memcheck, the following are useful. */
0487       Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
0488       Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
0489       Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /*  \x -> x | -x */
0490       Iop_Max32U, /* unsigned max */
0491 
0492       /* PowerPC-style 3-way integer comparisons.  Without them it is
0493          difficult to simulate PPC efficiently.
0494          op(x,y) | x < y  = 0x8 else 
0495                  | x > y  = 0x4 else
0496                  | x == y = 0x2
0497       */
0498       Iop_CmpORD32U, Iop_CmpORD64U,
0499       Iop_CmpORD32S, Iop_CmpORD64S,
0500 
0501       /* Division */
0502       /* TODO: clarify semantics wrt rounding, negative values, whatever */
0503       Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
0504       Iop_DivS32,   // ditto, signed
0505       Iop_DivU64,   // :: I64,I64 -> I64 (simple div, no mod)
0506       Iop_DivS64,   // ditto, signed
0507       Iop_DivU128,   // :: I128,I128 -> I128 (simple div, no mod)
0508       Iop_DivS128,   // ditto, signed
0509 
0510       Iop_DivU32E,  // :: I32,I32 -> I32 (dividend is 32-bit arg (hi)
0511                     // concat with 32 0's (low))
0512       Iop_DivS32E,  // ditto, signed
0513       Iop_DivU64E,  // :: I64,I64 -> I64 (dividend is 64-bit arg (hi)
0514                     //                    concat with 64 0's (low))
0515       Iop_DivS64E,  // ditto, signed
0516       Iop_DivU128E, // :: I128,I128 -> I128 (dividend is 128-bit arg (hi)
0517                     //                    concat with 128 0's (low))
0518       Iop_DivS128E, // ditto, signed
0519 
0520       Iop_DivModU64to32, // :: I64,I32 -> I64
0521                          // of which lo half is div and hi half is mod
0522       Iop_DivModS64to32, // ditto, signed
0523 
0524       Iop_DivModU128to64, // :: V128,I64 -> V128
0525                           // of which lo half is div and hi half is mod
0526       Iop_DivModS128to64, // ditto, signed
0527 
0528       Iop_DivModS64to64, // :: I64,I64 -> I128
0529                          // of which lo half is div and hi half is mod
0530       Iop_DivModU64to64, // :: I64,I64 -> I128
0531                          // of which lo half is div and hi half is mod
0532       Iop_DivModS32to32, // :: I32,I32 -> I64
0533                          // of which lo half is div and hi half is mod
0534       Iop_DivModU32to32, // :: I32,I32 -> I64
0535                          // of which lo half is div and hi half is mod
0536 
0537       Iop_ModU128,     // :: I128,I128 -> I128  normal modulo operation
0538       Iop_ModS128,     // ditto, signed
0539 
0540       /* Integer conversions.  Some of these are redundant (eg
0541          Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
0542          having a complete set reduces the typical dynamic size of IR
0543          and makes the instruction selectors easier to write. */
0544 
0545       /* Widening conversions */
0546       Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
0547                   Iop_16Uto32, Iop_16Uto64,
0548                                Iop_32Uto64,
0549       Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
0550                   Iop_16Sto32, Iop_16Sto64,
0551                                Iop_32Sto64,
0552 
0553       /* Narrowing conversions */
0554       Iop_64to8, Iop_32to8, Iop_64to16,
0555       /* 8 <-> 16 bit conversions */
0556       Iop_16to8,      // :: I16 -> I8, low half
0557       Iop_16HIto8,    // :: I16 -> I8, high half
0558       Iop_8HLto16,    // :: (I8,I8) -> I16
0559       /* 16 <-> 32 bit conversions */
0560       Iop_32to16,     // :: I32 -> I16, low half
0561       Iop_32HIto16,   // :: I32 -> I16, high half
0562       Iop_16HLto32,   // :: (I16,I16) -> I32
0563       /* 32 <-> 64 bit conversions */
0564       Iop_64to32,     // :: I64 -> I32, low half
0565       Iop_64HIto32,   // :: I64 -> I32, high half
0566       Iop_32HLto64,   // :: (I32,I32) -> I64
0567       /* 64 <-> 128 bit conversions */
0568       Iop_128to64,    // :: I128 -> I64, low half
0569       Iop_128HIto64,  // :: I128 -> I64, high half
0570       Iop_64HLto128,  // :: (I64,I64) -> I128
0571       /* 1-bit stuff */
0572       Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
0573       Iop_And1,   /* :: (Ity_Bit, Ity_Bit) -> Ity_Bit.  Evaluates both args! */
0574       Iop_Or1,    /* :: (Ity_Bit, Ity_Bit) -> Ity_Bit.  Evaluates both args! */
0575       Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
0576       Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
0577       Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
0578       Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
0579       Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
0580       Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
0581       Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
0582       Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
0583       Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
0584 
0585       /* ------ Floating point.  We try to be IEEE754 compliant. ------ */
0586 
0587       /* --- Simple stuff as mandated by 754. --- */
0588 
0589       /* Binary operations, with rounding. */
0590       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
0591       Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
0592 
0593       /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */ 
0594       Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
0595 
0596       /* Variants of the above which produce a 64-bit result but which
0597          round their result to a IEEE float range first. */
0598       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
0599       Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32, 
0600 
0601       /* Unary operations, without rounding. */
0602       /* :: F64 -> F64 */
0603       Iop_NegF64, Iop_AbsF64,
0604 
0605       /* :: F32 -> F32 */
0606       Iop_NegF32, Iop_AbsF32,
0607 
0608       /* :: F16 -> F16 */
0609       Iop_NegF16, Iop_AbsF16,
0610 
0611       /* Unary operations, with rounding. */
0612       /* :: IRRoundingMode(I32) x F64 -> F64 */
0613       Iop_SqrtF64,
0614 
0615       /* :: IRRoundingMode(I32) x F32 -> F32 */
0616       Iop_SqrtF32,
0617 
0618       /* :: IRRoundingMode(I32) x F16 -> F16 */
0619       Iop_SqrtF16,
0620 
0621       /* :: IRRoundingMode(I32) x F16 x F16 -> F16 */
0622       Iop_SubF16, Iop_AddF16,
0623 
0624       /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
0625             0x45 Unordered
0626             0x01 LT
0627             0x00 GT
0628             0x40 EQ
0629          This just happens to be the Intel encoding.  The values
0630          are recorded in the type IRCmpF64Result.
0631       */
0632       /* :: F64 x F64 -> IRCmpF64Result(I32) */
0633       Iop_CmpF64,
0634       Iop_CmpF32,
0635       Iop_CmpF16,
0636       Iop_CmpF128,
0637 
0638       /* --- Int to/from FP conversions. --- */
0639 
0640       /* For the most part, these take a first argument :: Ity_I32 (as
0641          IRRoundingMode) which is an indication of the rounding mode
0642          to use, as per the following encoding ("the standard
0643          encoding"):
0644             00b  to nearest (the default)
0645             01b  to -infinity
0646             10b  to +infinity
0647             11b  to zero
0648          This just happens to be the Intel encoding.  For reference only,
0649          the PPC encoding is:
0650             00b  to nearest (the default)
0651             01b  to zero
0652             10b  to +infinity
0653             11b  to -infinity
0654          Any PPC -> IR front end will have to translate these PPC
0655          encodings, as encoded in the guest state, to the standard
0656          encodings, to pass to the primops.
0657          For reference only, the ARM VFP encoding is:
0658             00b  to nearest
0659             01b  to +infinity
0660             10b  to -infinity
0661             11b  to zero
0662          Again, this will have to be converted to the standard encoding
0663          to pass to primops.
0664 
0665          If one of these conversions gets an out-of-range condition,
0666          or a NaN, as an argument, the result is host-defined.  On x86
0667          the "integer indefinite" value 0x80..00 is produced.  On PPC
0668          it is either 0x80..00 or 0x7F..FF depending on the sign of
0669          the argument.
0670 
0671          On ARMvfp, when converting to a signed integer result, the
0672          overflow result is 0x80..00 for negative args and 0x7F..FF
0673          for positive args.  For unsigned integer results it is
0674          0x00..00 and 0xFF..FF respectively.
0675 
0676          Rounding is required whenever the destination type cannot
0677          represent exactly all values of the source type.
0678       */
0679       Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
0680       Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
0681       Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
0682       Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
0683 
0684       Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
0685 
0686       Iop_I32StoF64, /*                       signed I32 -> F64 */
0687       Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
0688       Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
0689       Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
0690 
0691       Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */
0692       Iop_I32UtoF64, /*                       unsigned I32 -> F64 */
0693 
0694       Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
0695       Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
0696       Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */
0697       Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */
0698 
0699       Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
0700       Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
0701 
0702       /* Conversion between floating point formats */
0703       Iop_F32toF64,  /*                       F32 -> F64 */
0704       Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
0705 
0706       /* Reinterpretation.  Take an F32/64/128 and produce an I32/64/128
0707          with the same bit pattern, or vice versa. */
0708       Iop_ReinterpV128asI128, Iop_ReinterpI128asV128,
0709       Iop_ReinterpF128asI128, Iop_ReinterpI128asF128,
0710       Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
0711       Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
0712 
0713       /* Support for 128-bit floating point */
0714       Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
0715       Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
0716       Iop_F128LOtoF64,/* F128 -> low  half of F128 into a F64 register */
0717 
0718       /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
0719       Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
0720       Iop_MAddF128,    // (A * B) + C
0721       Iop_MSubF128,    // (A * B) - C
0722       Iop_NegMAddF128, // -((A * B) + C)
0723       Iop_NegMSubF128, // -((A * B) - C)
0724 
0725       /* :: F128 -> F128 */
0726       Iop_NegF128, Iop_AbsF128,
0727 
0728       /* :: IRRoundingMode(I32) x F128 -> F128 */
0729       Iop_SqrtF128,
0730 
0731       Iop_I32StoF128, /*                signed I32  -> F128 */
0732       Iop_I64StoF128, /*                signed I64  -> F128 */
0733       Iop_I32UtoF128, /*              unsigned I32  -> F128 */
0734       Iop_I64UtoF128, /*              unsigned I64  -> F128 */
0735       Iop_F32toF128,  /*                       F32  -> F128 */
0736       Iop_F64toF128,  /*                       F64  -> F128 */
0737       Iop_I128UtoF128, /*             unsigned I128 -> F128 */
0738       Iop_I128StoF128, /*               signed I128 -> F128 */
0739 
0740       Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32  */
0741       Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64  */
0742       Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32  */
0743       Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64  */
0744       Iop_F128toI128S,/* IRRoundingMode(I32) x F128 -> signed I128 */
0745       Iop_F128toF64,  /* IRRoundingMode(I32) x F128 -> F64         */
0746       Iop_F128toF32,  /* IRRoundingMode(I32) x F128 -> F32         */
0747       Iop_RndF128,    /* IRRoundingMode(I32) x F128 -> F128         */
0748 
0749       /* Truncate to the specified value, source and result
0750        * are stroed in a F128 register.
0751        */
0752       Iop_TruncF128toI32S,  /* truncate F128 -> I32         */
0753       Iop_TruncF128toI32U,  /* truncate F128 -> I32         */
0754       Iop_TruncF128toI64U,  /* truncate F128 -> I64         */
0755       Iop_TruncF128toI64S,  /* truncate F128 -> I64         */
0756       Iop_TruncF128toI128U, /* truncate F128 -> I128        */
0757       Iop_TruncF128toI128S, /* truncate F128 -> I128        */
0758 
0759       /* --- guest x86/amd64 specifics, not mandated by 754. --- */
0760 
0761       /* Binary ops, with rounding. */
0762       /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 
0763       Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
0764       Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
0765       Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
0766       Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
0767       Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
0768       Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
0769       Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
0770       Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
0771       /* Note that on x86 guest, PRem1{C3210} has the same behaviour
0772          as the IEEE mandated RemF64, except it is limited in the
0773          range of its operand.  Hence the partialness. */
0774 
0775       /* Unary ops, with rounding. */
0776       /* :: IRRoundingMode(I32) x F64 -> F64 */
0777       Iop_SinF64,    /* FSIN */
0778       Iop_CosF64,    /* FCOS */
0779       Iop_TanF64,    /* FTAN */
0780       Iop_2xm1F64,   /* (2^arg - 1.0) */
0781       Iop_RoundF128toInt, /* F128 value to nearest integral value (still
0782                              as F128) */
0783       Iop_RoundF64toInt, /* F64 value to nearest integral value (still
0784                             as F64) */
0785       Iop_RoundF32toInt, /* F32 value to nearest integral value (still
0786                             as F32) */
0787 
0788       /* --- guest s390 specifics, not mandated by 754. --- */
0789 
0790       /* Fused multiply-add/sub */
0791       /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
0792             (computes arg2 * arg3 +/- arg4) */ 
0793       Iop_MAddF32, Iop_MSubF32,
0794 
0795       /* --- guest ppc32/64 specifics, not mandated by 754. --- */
0796 
0797       /* Ternary operations, with rounding. */
0798       /* Fused multiply-add/sub, with 112-bit intermediate
0799          precision for ppc.
0800          Also used to implement fused multiply-add/sub for s390. */
0801       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 
0802             (computes arg2 * arg3 +/- arg4) */ 
0803       Iop_MAddF64, Iop_MSubF64,
0804 
0805       /* Variants of the above which produce a 64-bit result but which
0806          round their result to a IEEE float range first. */
0807       /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */ 
0808       Iop_MAddF64r32, Iop_MSubF64r32,
0809 
0810       /* :: F64 -> F64 */
0811       Iop_RSqrtEst5GoodF64, /* reciprocal square root estimate, 5 good bits */
0812       Iop_RoundF64toF64_NEAREST, /* frin */
0813       Iop_RoundF64toF64_NegINF,  /* frim */ 
0814       Iop_RoundF64toF64_PosINF,  /* frip */
0815       Iop_RoundF64toF64_ZERO,    /* friz */
0816 
0817       /* :: F64 -> F32 */
0818       Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
0819 
0820       /* :: IRRoundingMode(I32) x F64 -> F64 */
0821       Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
0822       /* NB: pretty much the same as Iop_F64toF32, except no change 
0823          of type. */
0824 
0825       /* --- guest arm64 specifics, not mandated by 754. --- */
0826 
0827       Iop_RecpExpF64,  /* FRECPX d  :: IRRoundingMode(I32) x F64 -> F64 */
0828       Iop_RecpExpF32,  /* FRECPX s  :: IRRoundingMode(I32) x F32 -> F32 */
0829 
0830       /* --------- Possibly required by IEEE 754-2008. --------- */
0831 
0832       Iop_MaxNumF64,  /* max, F64, numerical operand if other is a qNaN */
0833       Iop_MinNumF64,  /* min, F64, ditto */
0834       Iop_MaxNumF32,  /* max, F32, ditto */
0835       Iop_MinNumF32,  /* min, F32, ditto */
0836 
0837       /* ------------------ 16-bit scalar FP ------------------ */
0838 
0839       Iop_F16toF64,  /*                       F16 -> F64 */
0840       Iop_F64toF16,  /* IRRoundingMode(I32) x F64 -> F16 */
0841 
0842       Iop_F16toF32,  /*                       F16 -> F32 */
0843       Iop_F32toF16,  /* IRRoundingMode(I32) x F32 -> F16 */
0844 
0845       /* ------------------ 32-bit SIMD Integer ------------------ */
0846 
0847       /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
0848       Iop_QAdd32S,
0849       Iop_QSub32S,
0850 
0851       /* 16x2 add/sub, also signed/unsigned saturating variants */
0852       Iop_Add16x2, Iop_Sub16x2,
0853       Iop_QAdd16Sx2, Iop_QAdd16Ux2,
0854       Iop_QSub16Sx2, Iop_QSub16Ux2,
0855 
0856       /* 16x2 signed/unsigned halving add/sub.  For each lane, these
0857          compute bits 16:1 of (eg) sx(argL) + sx(argR),
0858          or zx(argL) - zx(argR) etc. */
0859       Iop_HAdd16Ux2, Iop_HAdd16Sx2,
0860       Iop_HSub16Ux2, Iop_HSub16Sx2,
0861 
0862       /* 8x4 add/sub, also signed/unsigned saturating variants */
0863       Iop_Add8x4, Iop_Sub8x4,
0864       Iop_QAdd8Sx4, Iop_QAdd8Ux4,
0865       Iop_QSub8Sx4, Iop_QSub8Ux4,
0866 
0867       /* 8x4 signed/unsigned halving add/sub.  For each lane, these
0868          compute bits 8:1 of (eg) sx(argL) + sx(argR),
0869          or zx(argL) - zx(argR) etc. */
0870       Iop_HAdd8Ux4, Iop_HAdd8Sx4,
0871       Iop_HSub8Ux4, Iop_HSub8Sx4,
0872 
0873       /* 8x4 sum of absolute unsigned differences. */
0874       Iop_Sad8Ux4,
0875 
0876       /* MISC (vector integer cmp != 0) */
0877       Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
0878 
0879       /* Byte swap in a 32-bit word */
0880       Iop_Reverse8sIn32_x1,
0881 
0882       /* ------------------ 64-bit SIMD FP ------------------------ */
0883 
0884       /* Conversion to/from int */
0885       // Deprecated: these don't specify a rounding mode
0886       Iop_I32UtoF32x2_DEP,  Iop_I32StoF32x2_DEP,    /* I32x2 -> F32x2 */
0887 
0888       Iop_F32toI32Ux2_RZ,  Iop_F32toI32Sx2_RZ,    /* F32x2 -> I32x2 */
0889 
0890       /* Fixed32 format is floating-point number with fixed number of fraction
0891          bits. The number of fraction bits is passed as a second argument of
0892          type I8. */
0893       Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
0894       Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
0895 
0896       /* Binary operations */
0897       Iop_Max32Fx2,      Iop_Min32Fx2,
0898       /* Pairwise Min and Max. See integer pairwise operations for more
0899          details. */
0900       Iop_PwMax32Fx2,    Iop_PwMin32Fx2,
0901       /* Note: For the following compares, the arm front-end assumes a
0902          nan in a lane of either argument returns zero for that lane. */
0903       Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
0904 
0905       /* Vector Reciprocal Estimate finds an approximate reciprocal of each
0906       element in the operand vector, and places the results in the destination
0907       vector.  */
0908       Iop_RecipEst32Fx2,
0909 
0910       /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
0911          Note, that if one of the arguments is zero and another one is infinity
0912          of arbitrary sign the result of the operation is 2.0. */
0913       Iop_RecipStep32Fx2,
0914 
0915       /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
0916          square root of each element in the operand vector. */
0917       Iop_RSqrtEst32Fx2,
0918 
0919       /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
0920          Note, that of one of the arguments is zero and another one is infiinty
0921          of arbitrary sign the result of the operation is 1.5. */
0922       Iop_RSqrtStep32Fx2,
0923 
0924       /* Unary */
0925       Iop_Neg32Fx2, Iop_Abs32Fx2,
0926 
0927       /* ------------------ 64-bit SIMD Integer. ------------------ */
0928 
0929       /* MISC (vector integer cmp != 0) */
0930       Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
0931 
0932       /* ADDITION (normal / unsigned sat / signed sat) */
0933       Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
0934       Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
0935       Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
0936 
0937       /* PAIRWISE operations */
0938       /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
0939             [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
0940       Iop_PwAdd8x8,  Iop_PwAdd16x4,  Iop_PwAdd32x2,
0941       Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
0942       Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
0943       Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
0944       Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
0945       /* Longening variant is unary. The resulting vector contains two times
0946          less elements than operand, but they are two times wider.
0947          Example:
0948             Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
0949                where a+b and c+d are unsigned 32-bit values. */
0950       Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
0951       Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
0952 
0953       /* SUBTRACTION (normal / unsigned sat / signed sat) */
0954       Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
0955       Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
0956       Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
0957 
0958       /* ABSOLUTE VALUE */
0959       Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
0960 
0961       /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
0962       Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
0963       Iop_Mul32Fx2,
0964       Iop_MulHi16Ux4,
0965       Iop_MulHi16Sx4,
0966       /* Plynomial multiplication treats it's arguments as coefficients of
0967          polynoms over {0, 1}. */
0968       Iop_PolynomialMul8x8,
0969 
0970       /* Vector Saturating Doubling Multiply Returning High Half and
0971          Vector Saturating Rounding Doubling Multiply Returning High Half */
0972       /* These IROp's multiply corresponding elements in two vectors, double
0973          the results, and place the most significant half of the final results
0974          in the destination vector. The results are truncated or rounded. If
0975          any of the results overflow, they are saturated. */
0976       Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
0977       Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
0978 
0979       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
0980       Iop_Avg8Ux8,
0981       Iop_Avg16Ux4,
0982 
0983       /* MIN/MAX */
0984       Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
0985       Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
0986       Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
0987       Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
0988 
0989       /* COMPARISON */
0990       Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
0991       Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
0992       Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
0993 
0994       /* COUNT ones / leading zeroes / leading sign bits (not including topmost
0995          bit) */
0996       Iop_Cnt8x8,
0997       Iop_Clz8x8, Iop_Clz16x4, Iop_Clz32x2,
0998       Iop_Cls8x8, Iop_Cls16x4, Iop_Cls32x2,
0999       Iop_Clz64x2,
1000 
1001       /*Vector COUNT trailing zeros */
1002       Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2, 
1003 
1004       /* VECTOR x VECTOR SHIFT / ROTATE */
1005       Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
1006       Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
1007       Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
1008       Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
1009 
1010       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1011       Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
1012       Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
1013       Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
1014 
1015       /* VECTOR x VECTOR SATURATING SHIFT */
1016       Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
1017       Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
1018       /* VECTOR x INTEGER SATURATING SHIFT */
1019       Iop_QShlNsatSU8x8,  Iop_QShlNsatSU16x4,
1020       Iop_QShlNsatSU32x2, Iop_QShlNsatSU64x1,
1021       Iop_QShlNsatUU8x8,  Iop_QShlNsatUU16x4,
1022       Iop_QShlNsatUU32x2, Iop_QShlNsatUU64x1,
1023       Iop_QShlNsatSS8x8,  Iop_QShlNsatSS16x4,
1024       Iop_QShlNsatSS32x2, Iop_QShlNsatSS64x1,
1025 
1026       /* NARROWING (binary) 
1027          -- narrow 2xI64 into 1xI64, hi half from left arg */
1028       /* For saturated narrowing, I believe there are 4 variants of
1029          the basic arithmetic operation, depending on the signedness
1030          of argument and result.  Here are examples that exemplify
1031          what I mean:
1032 
1033          QNarrow16Uto8U ( UShort x )  if (x >u 255) x = 255;
1034                                       return x[7:0];
1035 
1036          QNarrow16Sto8S ( Short x )   if (x <s -128) x = -128;
1037                                       if (x >s  127) x = 127;
1038                                       return x[7:0];
1039 
1040          QNarrow16Uto8S ( UShort x )  if (x >u 127) x = 127;
1041                                       return x[7:0];
1042 
1043          QNarrow16Sto8U ( Short x )   if (x <s 0)   x = 0;
1044                                       if (x >s 255) x = 255;
1045                                       return x[7:0];
1046       */
1047       Iop_QNarrowBin16Sto8Ux8,
1048       Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
1049       Iop_NarrowBin16to8x8,    Iop_NarrowBin32to16x4,
1050 
1051       /* INTERLEAVING */
1052       /* Interleave lanes from low or high halves of
1053          operands.  Most-significant result lane is from the left
1054          arg. */
1055       Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
1056       Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
1057       /* Interleave odd/even lanes of operands.  Most-significant result lane
1058          is from the left arg.  Note that Interleave{Odd,Even}Lanes32x2 are
1059          identical to Interleave{HI,LO}32x2 and so are omitted.*/
1060       Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
1061       Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
1062 
1063       /* CONCATENATION -- build a new value by concatenating either
1064          the even or odd lanes of both operands.  Note that
1065          Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
1066          and so are omitted. */
1067       Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
1068       Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
1069 
1070       /* GET / SET elements of VECTOR
1071          GET is binop (I64, I8) -> I<elem_size>
1072          SET is triop (I64, I8, I<elem_size>) -> I64 */
1073       /* Note: the arm back-end handles only constant second argument */
1074       Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
1075       Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
1076 
1077       /* DUPLICATING -- copy value to all lanes */
1078       Iop_Dup8x8,   Iop_Dup16x4,   Iop_Dup32x2,
1079 
1080       /* SLICE -- produces the lowest 64 bits of (arg1:arg2) >> (8 * arg3).
1081          arg3 is a shift amount in bytes and may be between 0 and 8
1082          inclusive.  When 0, the result is arg2; when 8, the result is arg1.
1083          Not all back ends handle all values.  The arm32 and arm64 back
1084          ends handle only immediate arg3 values. */
1085       Iop_Slice64,  // (I64, I64, I8) -> I64
1086 
1087       /* REVERSE the order of chunks in vector lanes.  Chunks must be
1088          smaller than the vector lanes (obviously) and so may be 8-, 16- and
1089          32-bit in size.  Note that the degenerate case,
1090          Iop_Reverse8sIn64_x1, is a simply a vanilla byte-swap. */
1091       /* Examples:
1092             Reverse8sIn16_x4([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1093             Reverse8sIn32_x2([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
1094             Reverse8sIn64_x1([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
1095       Iop_Reverse8sIn16_x4,
1096       Iop_Reverse8sIn32_x2, Iop_Reverse16sIn32_x2,
1097       Iop_Reverse8sIn64_x1, Iop_Reverse16sIn64_x1, Iop_Reverse32sIn64_x1,
1098 
1099       /* PERMUTING -- copy src bytes to dst,
1100          as indexed by control vector bytes:
1101             for i in 0 .. 7 . result[i] = argL[ argR[i] ] 
1102          argR[i] values may only be in the range 0 .. 7, else behaviour
1103          is undefined.  That is, argR[i][7:3] must be zero. */
1104       Iop_Perm8x8,
1105 
1106       /* PERMUTING with optional zeroing:
1107             for i in 0 .. 7 . result[i] = if argR[i] bit 7 is set
1108                                           then zero else argL[ argR[i] ]
1109          argR[i][6:3] must be zero, else behaviour is undefined.
1110       */
1111       Iop_PermOrZero8x8,
1112 
1113       /* MISC CONVERSION -- get high bits of each byte lane, a la
1114          x86/amd64 pmovmskb */
1115       Iop_GetMSBs8x8, /* I64 -> I8 */
1116 
1117       /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1118          See floating-point equivalents for details. */
1119       Iop_RecipEst32Ux2, Iop_RSqrtEst32Ux2,
1120 
1121       /* ------------------ Decimal Floating Point ------------------ */
1122 
1123       /* ARITHMETIC INSTRUCTIONS   64-bit
1124      ----------------------------------
1125      IRRoundingMode(I32) X D64 X D64 -> D64
1126       */
1127       Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1128 
1129       /* ARITHMETIC INSTRUCTIONS  128-bit
1130      ----------------------------------
1131      IRRoundingMode(I32) X D128 X D128 -> D128
1132       */
1133       Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1134 
1135       /* SHIFT SIGNIFICAND INSTRUCTIONS
1136        *    The DFP significand is shifted by the number of digits specified
1137        *    by the U8 operand.  Digits shifted out of the leftmost digit are
1138        *    lost. Zeros are supplied to the vacated positions on the right.
1139        *    The sign of the result is the same as the sign of the original
1140        *    operand.
1141        *
1142        * D64 x U8  -> D64    left shift and right shift respectively */
1143       Iop_ShlD64, Iop_ShrD64,
1144 
1145       /* D128 x U8  -> D128  left shift and right shift respectively */
1146       Iop_ShlD128, Iop_ShrD128,
1147 
1148 
1149       /* FORMAT CONVERSION INSTRUCTIONS
1150        *   D32 -> D64
1151        */
1152       Iop_D32toD64,
1153 
1154       /*   D64 -> D128 */
1155       Iop_D64toD128, 
1156 
1157       /*   I32S -> D128 */
1158       Iop_I32StoD128,
1159 
1160       /*   I32U -> D128 */
1161       Iop_I32UtoD128,
1162 
1163       /*   I64S -> D128 */
1164       Iop_I64StoD128, 
1165 
1166       /*   I64U -> D128 */
1167       Iop_I64UtoD128,
1168 
1169       /*   IRRoundingMode(I32) x I128S -> D128 */
1170       Iop_I128StoD128,
1171 
1172       /*   IRRoundingMode(I32) x D64 -> D32 */
1173       Iop_D64toD32,
1174 
1175       /*   IRRoundingMode(I32) x D128 -> D64 */
1176       Iop_D128toD64,
1177 
1178       /*   I32S -> D64 */
1179       Iop_I32StoD64,
1180 
1181       /*   I32U -> D64 */
1182       Iop_I32UtoD64,
1183 
1184       /*   IRRoundingMode(I32) x I64 -> D64 */
1185       Iop_I64StoD64,
1186 
1187       /*   IRRoundingMode(I32) x I64 -> D64 */
1188       Iop_I64UtoD64,
1189 
1190       /*   IRRoundingMode(I32) x D64 -> I32 */
1191       Iop_D64toI32S,
1192 
1193       /*   IRRoundingMode(I32) x D64 -> I32 */
1194       Iop_D64toI32U,
1195 
1196       /*   IRRoundingMode(I32) x D64 -> I64 */
1197       Iop_D64toI64S,
1198 
1199       /*   IRRoundingMode(I32) x D64 -> I64 */
1200       Iop_D64toI64U,
1201 
1202       /*   IRRoundingMode(I32) x D128 -> I32 */
1203       Iop_D128toI32S,
1204 
1205       /*   IRRoundingMode(I32) x D128 -> I32 */
1206       Iop_D128toI32U,
1207 
1208       /*   IRRoundingMode(I32) x D128 -> I64 */
1209       Iop_D128toI64S,
1210 
1211       /*   IRRoundingMode(I32) x D128 -> I64 */
1212       Iop_D128toI64U,
1213 
1214       /*   IRRoundingMode(I32) x D128 -> I128 */
1215       Iop_D128toI128S,
1216 
1217       /*   IRRoundingMode(I32) x F32 -> D32 */
1218       Iop_F32toD32,
1219 
1220       /*   IRRoundingMode(I32) x F32 -> D64 */
1221       Iop_F32toD64,
1222 
1223       /*   IRRoundingMode(I32) x F32 -> D128 */
1224       Iop_F32toD128,
1225 
1226       /*   IRRoundingMode(I32) x F64 -> D32 */
1227       Iop_F64toD32,
1228 
1229       /*   IRRoundingMode(I32) x F64 -> D64 */
1230       Iop_F64toD64,
1231 
1232       /*   IRRoundingMode(I32) x F64 -> D128 */
1233       Iop_F64toD128,
1234 
1235       /*   IRRoundingMode(I32) x F128 -> D32 */
1236       Iop_F128toD32,
1237 
1238       /*   IRRoundingMode(I32) x F128 -> D64 */
1239       Iop_F128toD64,
1240 
1241       /*   IRRoundingMode(I32) x F128 -> D128 */
1242       Iop_F128toD128,
1243 
1244       /*   IRRoundingMode(I32) x D32 -> F32 */
1245       Iop_D32toF32,
1246 
1247       /*   IRRoundingMode(I32) x D32 -> F64 */
1248       Iop_D32toF64,
1249 
1250       /*   IRRoundingMode(I32) x D32 -> F128 */
1251       Iop_D32toF128,
1252 
1253       /*   IRRoundingMode(I32) x D64 -> F32 */
1254       Iop_D64toF32,
1255 
1256       /*   IRRoundingMode(I32) x D64 -> F64 */
1257       Iop_D64toF64,
1258 
1259       /*   IRRoundingMode(I32) x D64 -> F128 */
1260       Iop_D64toF128,
1261 
1262       /*   IRRoundingMode(I32) x D128 -> F32 */
1263       Iop_D128toF32,
1264 
1265       /*   IRRoundingMode(I32) x D128 -> F64 */
1266       Iop_D128toF64,
1267 
1268       /*   IRRoundingMode(I32) x D128 -> F128 */
1269       Iop_D128toF128,
1270 
1271       /* ROUNDING INSTRUCTIONS
1272        * IRRoundingMode(I32) x D64 -> D64
1273        * The D64 operand, if a finite number, it is rounded to a
1274        * floating point integer value, i.e. no fractional part.
1275        */
1276       Iop_RoundD64toInt,
1277 
1278       /* IRRoundingMode(I32) x D128 -> D128 */
1279       Iop_RoundD128toInt,
1280 
1281       /* COMPARE INSTRUCTIONS
1282        * D64 x D64 -> IRCmpD64Result(I32) */
1283       Iop_CmpD64,
1284 
1285       /* D128 x D128 -> IRCmpD128Result(I32) */
1286       Iop_CmpD128,
1287 
1288       /* COMPARE BIASED EXPONENET INSTRUCTIONS
1289        * D64 x D64 -> IRCmpD64Result(I32) */
1290       Iop_CmpExpD64,
1291 
1292       /* D128 x D128 -> IRCmpD128Result(I32) */
1293       Iop_CmpExpD128,
1294 
1295       /* QUANTIZE AND ROUND INSTRUCTIONS
1296        * The source operand is converted and rounded to the form with the 
1297        * immediate exponent specified by the rounding and exponent parameter.
1298        *
1299        * The second operand is converted and rounded to the form
1300        * of the first operand's exponent and the rounded based on the specified
1301        * rounding mode parameter.
1302        *
1303        * IRRoundingMode(I32) x D64 x D64-> D64 */
1304       Iop_QuantizeD64,
1305 
1306       /* IRRoundingMode(I32) x D128 x D128 -> D128 */
1307       Iop_QuantizeD128,
1308 
1309       /* IRRoundingMode(I32) x I8 x D64 -> D64
1310        *    The Decimal Floating point operand is rounded to the requested 
1311        *    significance given by the I8 operand as specified by the rounding 
1312        *    mode.
1313        */
1314       Iop_SignificanceRoundD64,
1315 
1316       /* IRRoundingMode(I32) x I8 x D128 -> D128 */
1317       Iop_SignificanceRoundD128,
1318 
1319       /* EXTRACT AND INSERT INSTRUCTIONS
1320        * D64 -> I64
1321        *    The exponent of the D32 or D64 operand is extracted.  The 
1322        *    extracted exponent is converted to a 64-bit signed binary integer.
1323        */
1324       Iop_ExtractExpD64,
1325 
1326       /* D128 -> I64 */
1327       Iop_ExtractExpD128,
1328 
1329       /* D64 -> I64
1330        * The number of significand digits of the D64 operand is extracted.
1331        * The number is stored as a 64-bit signed binary integer.
1332        */
1333       Iop_ExtractSigD64,
1334 
1335       /* D128 -> I64 */
1336       Iop_ExtractSigD128,
1337 
1338       /* I64 x D64  -> D64
1339        *    The exponent is specified by the first I64 operand the signed
1340        *    significand is given by the second I64 value.  The result is a D64
1341        *    value consisting of the specified significand and exponent whose 
1342        *    sign is that of the specified significand.
1343        */
1344       Iop_InsertExpD64,
1345 
1346       /* I64 x D128 -> D128 */
1347       Iop_InsertExpD128,
1348 
1349       /* Support for 128-bit DFP type */
1350       Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1351 
1352       /*  I64 -> I64  
1353        *     Convert 50-bit densely packed BCD string to 60 bit BCD string
1354        */
1355       Iop_DPBtoBCD,
1356 
1357       /* I64 -> I64
1358        *     Convert 60 bit BCD string to 50-bit densely packed BCD string
1359        */
1360       Iop_BCDtoDPB,
1361 
1362       /* BCD arithmetic instructions, (V128, V128) -> V128
1363        * The BCD format is the same as that used in the BCD<->DPB conversion
1364        * routines, except using 124 digits (vs 60) plus the trailing 4-bit
1365        * signed code. */
1366       Iop_BCDAdd, Iop_BCDSub,
1367 
1368       /* Conversion signed 128-bit integer to signed BCD 128-bit */
1369       Iop_I128StoBCD128,
1370 
1371       /* Conversion signed BCD 128-bit to 128-bit integer */
1372       Iop_BCD128toI128S,
1373 
1374       /* Conversion I64 -> D64 */
1375       Iop_ReinterpI64asD64,
1376 
1377       /* Conversion D64 -> I64 */
1378       Iop_ReinterpD64asI64,
1379 
1380       /* ------------------ 128-bit SIMD FP. ------------------ */
1381 
1382       /* --- 16x8 vector FP --- */
1383 
1384       /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1385       Iop_Sqrt16Fx8,
1386 
1387       /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1388       Iop_Add16Fx8, Iop_Sub16Fx8,
1389 
1390       /* binary */
1391       Iop_CmpLT16Fx8, Iop_CmpLE16Fx8, Iop_CmpEQ16Fx8,
1392 
1393       /* unary */
1394       Iop_Abs16Fx8,
1395       Iop_Neg16Fx8,
1396 
1397       /* --- 32x4 vector FP --- */
1398 
1399       /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1400       Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 
1401 
1402       /* binary */
1403       Iop_Max32Fx4, Iop_Min32Fx4,
1404       Iop_Add32Fx2, Iop_Sub32Fx2,
1405       /* Note: For the following compares, the ppc and arm front-ends assume a
1406          nan in a lane of either argument returns zero for that lane. */
1407       Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
1408       Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
1409 
1410       /* Pairwise Max and Min. See integer pairwise operations for details. */
1411       Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1412 
1413       /* unary */
1414       Iop_Abs32Fx4,
1415       Iop_Neg32Fx4,
1416 
1417       /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1418       Iop_Sqrt32Fx4,
1419 
1420       /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1421          element in the operand vector, and places the results in the
1422          destination vector.  */
1423       Iop_RecipEst32Fx4,
1424 
1425       /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1426          Note, that if one of the arguments is zero and another one is infinity
1427          of arbitrary sign the result of the operation is 2.0. */
1428       Iop_RecipStep32Fx4,
1429 
1430       /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1431          square root of each element in the operand vector. */
1432       Iop_RSqrtEst32Fx4,
1433 
1434       /* Scaling of vector with a power of 2  (wd[i] <- ws[i] * 2^wt[i]) */
1435       Iop_Scale2_32Fx4,
1436 
1437       /* Vector floating-point base 2 logarithm */
1438       Iop_Log2_32Fx4,
1439 
1440       /* Vector floating-point exponential 2^x */
1441       Iop_Exp2_32Fx4,
1442 
1443       /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1444          Note, that of one of the arguments is zero and another one is infiinty
1445          of arbitrary sign the result of the operation is 1.5. */
1446       Iop_RSqrtStep32Fx4,
1447 
1448       /* --- Int to/from FP conversion --- */
1449       /* Unlike the standard fp conversions, these irops take no
1450          rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1451          indicate the mode: {-inf, +inf, nearest, zero} respectively. */
1452 
1453       // These carry no rounding mode and are therefore deprecated
1454       Iop_I32UtoF32x4_DEP, Iop_I32StoF32x4_DEP,  /* I32x4 -> F32x4 */
1455 
1456       Iop_I32StoF32x4, /* IRRoundingMode(I32) x V128 -> V128 */
1457       Iop_F32toI32Sx4, /* IRRoundingMode(I32) x V128 -> V128 */
1458 
1459       Iop_F32toI32Ux4_RZ,  Iop_F32toI32Sx4_RZ,  /* F32x4 -> I32x4       */
1460       Iop_QF32toI32Ux4_RZ, Iop_QF32toI32Sx4_RZ, /* F32x4 -> I32x4 (saturating) */
1461       Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
1462       Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
1463       /* Fixed32 format is floating-point number with fixed number of fraction
1464          bits. The number of fraction bits is passed as a second argument of
1465          type I8. */
1466       Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1467       Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1468 
1469       /* --- Single to/from half conversion --- */
1470       /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
1471       // FIXME these carry no rounding mode
1472       Iop_F32toF16x4_DEP, /* F32x4(==V128) -> F16x4(==I64), NO ROUNDING MODE */
1473       Iop_F32toF16x4,     /* IRRoundingMode(I32) x V128 -> I64 */
1474       Iop_F16toF32x4,     /* F16x4 -> F32x4 */
1475 
1476       /* -- Double to/from half conversion -- */
1477       Iop_F64toF16x2_DEP, // F64x2 -> F16x2, NO ROUNDING MODE
1478       Iop_F16toF64x2,
1479 
1480       /* Values from two registers converted in smaller type and put in one
1481        IRRoundingMode(I32) x (F32x4 | F32x4) -> Q16x8 */
1482       Iop_F32x4_2toQ16x8,
1483 
1484 
1485       /* --- 32x4 lowest-lane-only scalar FP --- */
1486 
1487       /* In binary cases, upper 3/4 is copied from first operand.  In
1488          unary cases, upper 3/4 is copied from the operand. */
1489 
1490       /* binary */
1491       Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 
1492       Iop_Max32F0x4, Iop_Min32F0x4,
1493       Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 
1494 
1495       /* unary */
1496       Iop_RecipEst32F0x4, Iop_Sqrt32F0x4, Iop_RSqrtEst32F0x4,
1497 
1498       /* --- 64x2 vector FP --- */
1499 
1500       /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1501       Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 
1502 
1503       /* binary */
1504       Iop_Max64Fx2, Iop_Min64Fx2,
1505       Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 
1506 
1507       /* unary */
1508       Iop_Abs64Fx2,
1509       Iop_Neg64Fx2,
1510 
1511       /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1512       Iop_Sqrt64Fx2,
1513 
1514       /* Scaling of vector with a power of 2  (wd[i] <- ws[i] * 2^wt[i]) */
1515       Iop_Scale2_64Fx2,
1516 
1517       /* Vector floating-point base 2 logarithm */
1518       Iop_Log2_64Fx2,
1519 
1520       /* see 32Fx4 variants for description */
1521       Iop_RecipEst64Fx2,    // unary
1522       Iop_RecipStep64Fx2,   // binary
1523       Iop_RSqrtEst64Fx2,    // unary
1524       Iop_RSqrtStep64Fx2,   // binary
1525 
1526 
1527       /* Values from two registers converted in smaller type and put in one
1528        IRRoundingMode(I32) x (F64x2 | F64x2) -> Q32x4 */
1529       Iop_F64x2_2toQ32x4,
1530 
1531       /* --- 64x2 lowest-lane-only scalar FP --- */
1532 
1533       /* In binary cases, upper half is copied from first operand.  In
1534          unary cases, upper half is copied from the operand. */
1535 
1536       /* binary */
1537       Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 
1538       Iop_Max64F0x2, Iop_Min64F0x2,
1539       Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 
1540 
1541       /* unary */
1542       Iop_Sqrt64F0x2,
1543 
1544       /* --- pack / unpack --- */
1545 
1546       /* 64 <-> 128 bit vector */
1547       Iop_V128to64,     // :: V128 -> I64, low half
1548       Iop_V128HIto64,   // :: V128 -> I64, high half
1549       Iop_64HLtoV128,   // :: (I64,I64) -> V128
1550 
1551       Iop_64UtoV128,
1552       Iop_SetV128lo64,
1553 
1554       /* Copies lower 64/32/16/8 bits, zeroes out the rest. */
1555       Iop_ZeroHI64ofV128,    // :: V128 -> V128
1556       Iop_ZeroHI96ofV128,    // :: V128 -> V128
1557       Iop_ZeroHI112ofV128,   // :: V128 -> V128
1558       Iop_ZeroHI120ofV128,   // :: V128 -> V128
1559 
1560       /* 32 <-> 128 bit vector */
1561       Iop_32UtoV128,
1562       Iop_V128to32,     // :: V128 -> I32, lowest lane
1563       Iop_SetV128lo32,  // :: (V128,I32) -> V128
1564 
1565       /* ------------------ 128-bit SIMD Integer. ------------------ */
1566 
1567       /* BITWISE OPS */
1568       Iop_NotV128,
1569       Iop_AndV128, Iop_OrV128, Iop_XorV128, 
1570 
1571       /* VECTOR SHIFT (shift amt :: Ity_I8) */
1572       Iop_ShlV128, Iop_ShrV128, Iop_SarV128,
1573 
1574       /* MISC (vector integer cmp != 0) */
1575       Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
1576       Iop_CmpNEZ128x1,
1577 
1578       /* ADDITION (normal / U->U sat / S->S sat) */
1579       Iop_Add8x16,    Iop_Add16x8,    Iop_Add32x4,    Iop_Add64x2,   Iop_Add128x1,
1580       Iop_QAdd8Ux16,  Iop_QAdd16Ux8,  Iop_QAdd32Ux4,  Iop_QAdd64Ux2,
1581       Iop_QAdd8Sx16,  Iop_QAdd16Sx8,  Iop_QAdd32Sx4,  Iop_QAdd64Sx2,
1582 
1583       /* ADDITION, ARM64 specific saturating variants. */
1584       /* Unsigned widen left arg, signed widen right arg, add, saturate S->S.
1585          This corresponds to SUQADD. */
1586       Iop_QAddExtUSsatSS8x16, Iop_QAddExtUSsatSS16x8,
1587       Iop_QAddExtUSsatSS32x4, Iop_QAddExtUSsatSS64x2,
1588       /* Signed widen left arg, unsigned widen right arg, add, saturate U->U.
1589          This corresponds to USQADD. */
1590       Iop_QAddExtSUsatUU8x16, Iop_QAddExtSUsatUU16x8,
1591       Iop_QAddExtSUsatUU32x4, Iop_QAddExtSUsatUU64x2,
1592 
1593       /* SUBTRACTION (normal / unsigned sat / signed sat) */
1594       Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,   Iop_Sub64x2,   Iop_Sub128x1,
1595       Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1596       Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
1597 
1598       /* MULTIPLICATION (normal / high half of signed/unsigned) */
1599       Iop_Mul8x16,  Iop_Mul16x8,    Iop_Mul32x4,
1600       Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1601       Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4,
1602       /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
1603       Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4,
1604       Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4,
1605 
1606       /* Widening multiplies, all of the form (I64, I64) -> V128 */
1607       Iop_Mull8Ux8, Iop_Mull8Sx8,
1608       Iop_Mull16Ux4, Iop_Mull16Sx4,
1609       Iop_Mull32Ux2, Iop_Mull32Sx2,
1610 
1611       /* Signed doubling saturating widening multiplies, (I64, I64) -> V128 */
1612       Iop_QDMull16Sx4, Iop_QDMull32Sx2,
1613 
1614       /* Vector Saturating Doubling Multiply Returning High Half and
1615          Vector Saturating Rounding Doubling Multiply Returning High Half.
1616          These IROps multiply corresponding elements in two vectors, double
1617          the results, and place the most significant half of the final results
1618          in the destination vector.  The results are truncated or rounded.  If
1619          any of the results overflow, they are saturated.  To be more precise,
1620          for each lane, the computed result is: 
1621            QDMulHi:  
1622              hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2 )
1623            QRDMulHi:
1624              hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2
1625                       +q (1 << (lane-width-in-bits - 1)) )
1626       */
1627       Iop_QDMulHi16Sx8,  Iop_QDMulHi32Sx4,  /* (V128, V128) -> V128 */
1628       Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, /* (V128, V128) -> V128 */
1629 
1630       /* Polynomial multiplication treats its arguments as
1631          coefficients of polynomials over {0, 1}. */
1632       Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1633       Iop_PolynomialMull8x8, /*   (I64, I64) -> V128 */
1634 
1635       /* Vector Polynomial multiplication add.   (V128, V128) -> V128
1636 
1637        *** Below is the algorithm for the instructions. These Iops could
1638            be emulated to get this functionality, but the emulation would
1639            be long and messy.
1640 
1641         Example for polynomial multiply add for vector of bytes
1642         do i = 0 to 15
1643             prod[i].bit[0:14] <- 0
1644             srcA <- VR[argL].byte[i]
1645             srcB <- VR[argR].byte[i]
1646             do j = 0 to 7
1647                 do k = 0 to j
1648                     gbit <- srcA.bit[k] & srcB.bit[j-k]
1649                     prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1650                 end
1651             end
1652 
1653             do j = 8 to 14
1654                 do k = j-7 to 7
1655                      gbit <- (srcA.bit[k] & srcB.bit[j-k])
1656                      prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1657                 end
1658             end
1659         end
1660 
1661         do i = 0 to 7
1662             VR[dst].hword[i] <- 0b0 || (prod[2×i] ^ prod[2×i+1])
1663         end
1664       */
1665       Iop_PolynomialMulAdd8x16, Iop_PolynomialMulAdd16x8,
1666       Iop_PolynomialMulAdd32x4, Iop_PolynomialMulAdd64x2,
1667 
1668       /* PAIRWISE operations */
1669       /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1670             [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1671       Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1672       Iop_PwAdd32Fx2,
1673 
1674       /* Longening variant is unary. The resulting vector contains two times
1675          less elements than operand, but they are two times wider.
1676          Example:
1677             Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1678                where a+b and c+d are unsigned 32-bit values. */
1679       Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4, Iop_PwAddL64Ux2,
1680       Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1681 
1682       /* This is amd64 PMADDUBSW, (V128, V128) -> V128.  For each adjacent pair
1683          of bytes [a,b] in the first arg and [c,d] in the second, computes:
1684             signed/signed sat to 16 bits ( zxTo16(a) * sxTo16(b) 
1685                                            + zxTo16(c) * sxTo16(d) )
1686          This exists because it's frequently used and there's no reasonably
1687          concise way to express it using other IROps.
1688       */
1689       Iop_PwExtUSMulQAdd8x16,
1690 
1691       /* Other unary pairwise ops */
1692 
1693       /* Vector bit matrix transpose.  (V128) -> V128 */
1694       /* For each doubleword element of the source vector, an 8-bit x 8-bit
1695        * matrix transpose is performed. */
1696       Iop_PwBitMtxXpose64x2,
1697 
1698       /* ABSOLUTE VALUE */
1699       Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2,
1700 
1701       /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
1702       Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2,
1703       Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2,
1704 
1705       /* MIN/MAX */
1706       Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2,
1707       Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2,
1708       Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2,
1709       Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2,
1710 
1711       /* COMPARISON */
1712       Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,  Iop_CmpEQ64x2,
1713       Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
1714       Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, Iop_CmpGT64Ux2,
1715 
1716       /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1717          bit) */
1718       Iop_Cnt8x16,
1719       Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4,
1720       Iop_Cls8x16, Iop_Cls16x8, Iop_Cls32x4,
1721 
1722       /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1723       Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1724       Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
1725       Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
1726 
1727       /* VECTOR x VECTOR SHIFT / ROTATE */
1728       /* FIXME: I'm pretty sure the ARM32 front/back ends interpret these
1729          differently from all other targets.  The intention is that
1730          the shift amount (2nd arg) is interpreted as unsigned and
1731          only the lowest log2(lane-bits) bits are relevant.  But the
1732          ARM32 versions treat the shift amount as an 8 bit signed
1733          number.  The ARM32 uses should be replaced by the relevant
1734          vector x vector bidirectional shifts instead. */
1735       Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1736       Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1737       Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1738       Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
1739       Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2,
1740 
1741       /* VECTOR x VECTOR SATURATING SHIFT */
1742       Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1743       Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1744       /* VECTOR x INTEGER SATURATING SHIFT */
1745       Iop_QShlNsatSU8x16, Iop_QShlNsatSU16x8,
1746       Iop_QShlNsatSU32x4, Iop_QShlNsatSU64x2,
1747       Iop_QShlNsatUU8x16, Iop_QShlNsatUU16x8,
1748       Iop_QShlNsatUU32x4, Iop_QShlNsatUU64x2,
1749       Iop_QShlNsatSS8x16, Iop_QShlNsatSS16x8,
1750       Iop_QShlNsatSS32x4, Iop_QShlNsatSS64x2,
1751 
1752       /* VECTOR x VECTOR BIDIRECTIONAL SATURATING (& MAYBE ROUNDING) SHIFT */
1753       /* All of type (V128, V128) -> V256. */
1754       /* The least significant 8 bits of each lane of the second
1755          operand are used as the shift amount, and interpreted signedly.
1756          Positive values mean a shift left, negative a shift right.  The
1757          result is signedly or unsignedly saturated.  There are also
1758          rounding variants, which add 2^(shift_amount-1) to the value before
1759          shifting, but only in the shift-right case.  Vacated positions
1760          are filled with zeroes.  IOW, it's either SHR or SHL, but not SAR.
1761 
1762          These operations return 129 bits: one bit ("Q") indicating whether
1763          saturation occurred, and the shift result.  The result type is V256,
1764          of which the lower V128 is the shift result, and Q occupies the
1765          least significant bit of the upper V128.  All other bits of the
1766          upper V128 are zero. */
1767       // Unsigned saturation, no rounding
1768       Iop_QandUQsh8x16, Iop_QandUQsh16x8,
1769       Iop_QandUQsh32x4, Iop_QandUQsh64x2,
1770       // Signed saturation, no rounding
1771       Iop_QandSQsh8x16, Iop_QandSQsh16x8,
1772       Iop_QandSQsh32x4, Iop_QandSQsh64x2,
1773 
1774       // Unsigned saturation, rounding
1775       Iop_QandUQRsh8x16, Iop_QandUQRsh16x8,
1776       Iop_QandUQRsh32x4, Iop_QandUQRsh64x2,
1777       // Signed saturation, rounding
1778       Iop_QandSQRsh8x16, Iop_QandSQRsh16x8,
1779       Iop_QandSQRsh32x4, Iop_QandSQRsh64x2,
1780 
1781       /* VECTOR x VECTOR BIDIRECTIONAL (& MAYBE ROUNDING) SHIFT */
1782       /* All of type (V128, V128) -> V128 */
1783       /* The least significant 8 bits of each lane of the second
1784          operand are used as the shift amount, and interpreted signedly.
1785          Positive values mean a shift left, negative a shift right.
1786          There are also rounding variants, which add 2^(shift_amount-1)
1787          to the value before shifting, but only in the shift-right case.
1788 
1789          For left shifts, the vacated places are filled with zeroes.
1790          For right shifts, the vacated places are filled with zeroes
1791          for the U variants and sign bits for the S variants. */
1792       // Signed and unsigned, non-rounding
1793       Iop_Sh8Sx16, Iop_Sh16Sx8, Iop_Sh32Sx4, Iop_Sh64Sx2,
1794       Iop_Sh8Ux16, Iop_Sh16Ux8, Iop_Sh32Ux4, Iop_Sh64Ux2,
1795 
1796       // Signed and unsigned, rounding
1797       Iop_Rsh8Sx16, Iop_Rsh16Sx8, Iop_Rsh32Sx4, Iop_Rsh64Sx2,
1798       Iop_Rsh8Ux16, Iop_Rsh16Ux8, Iop_Rsh32Ux4, Iop_Rsh64Ux2,
1799 
1800       /* The least significant 8 bits of each lane of the second
1801          operand are used as the shift amount, and interpreted signedly.
1802          Positive values mean a shift left, negative a shift right.  The
1803          result is signedly or unsignedly saturated.  There are also
1804          rounding variants, which add 2^(shift_amount-1) to the value before
1805          shifting, but only in the shift-right case.  Vacated positions
1806          are filled with zeroes.  IOW, it's either SHR or SHL, but not SAR.
1807       */
1808 
1809       /* VECTOR x SCALAR SATURATING (& MAYBE ROUNDING) NARROWING SHIFT RIGHT */
1810       /* All of type (V128, I8) -> V128 */
1811       /* The first argument is shifted right, then narrowed to half the width
1812          by saturating it.  The second argument is a scalar shift amount that
1813          applies to all lanes, and must be a value in the range 1 to lane_width.
1814          The shift may be done signedly (Sar variants) or unsignedly (Shr
1815          variants).  The saturation is done according to the two signedness
1816          indicators at the end of the name.  For example 64Sto32U means a
1817          signed 64 bit value is saturated into an unsigned 32 bit value.
1818          Additionally, the QRS variants do rounding, that is, they add the
1819          value (1 << (shift_amount-1)) to each source lane before shifting.
1820 
1821          These operations return 65 bits: one bit ("Q") indicating whether
1822          saturation occurred, and the shift result.  The result type is V128,
1823          of which the lower half is the shift result, and Q occupies the
1824          least significant bit of the upper half.  All other bits of the
1825          upper half are zero. */
1826       // No rounding, sat U->U
1827       Iop_QandQShrNnarrow16Uto8Ux8,
1828       Iop_QandQShrNnarrow32Uto16Ux4, Iop_QandQShrNnarrow64Uto32Ux2,
1829       // No rounding, sat S->S
1830       Iop_QandQSarNnarrow16Sto8Sx8,
1831       Iop_QandQSarNnarrow32Sto16Sx4, Iop_QandQSarNnarrow64Sto32Sx2,
1832       // No rounding, sat S->U
1833       Iop_QandQSarNnarrow16Sto8Ux8,
1834       Iop_QandQSarNnarrow32Sto16Ux4, Iop_QandQSarNnarrow64Sto32Ux2,
1835 
1836       // Rounding, sat U->U
1837       Iop_QandQRShrNnarrow16Uto8Ux8,
1838       Iop_QandQRShrNnarrow32Uto16Ux4, Iop_QandQRShrNnarrow64Uto32Ux2,
1839       // Rounding, sat S->S
1840       Iop_QandQRSarNnarrow16Sto8Sx8,
1841       Iop_QandQRSarNnarrow32Sto16Sx4, Iop_QandQRSarNnarrow64Sto32Sx2,
1842       // Rounding, sat S->U
1843       Iop_QandQRSarNnarrow16Sto8Ux8,
1844       Iop_QandQRSarNnarrow32Sto16Ux4, Iop_QandQRSarNnarrow64Sto32Ux2,
1845 
1846       /* NARROWING (binary) 
1847          -- narrow 2xV128 into 1xV128, hi half from left arg */
1848       /* See comments above w.r.t. U vs S issues in saturated narrowing. */
1849       Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1850       Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1851       Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1852       Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
1853       Iop_QNarrowBin64Sto32Sx4, Iop_QNarrowBin64Uto32Ux4,
1854       Iop_NarrowBin64to32x4,
1855 
1856       /* NARROWING (unary) -- narrow V128 into I64 */
1857       Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1858       /* Saturating narrowing from signed source to signed/unsigned
1859          destination */
1860       Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1861       Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1862       /* Saturating narrowing from unsigned source to unsigned destination */
1863       Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1864 
1865       /* WIDENING -- sign or zero extend each element of the argument
1866          vector to the twice original size.  The resulting vector consists of
1867          the same number of elements but each element and the vector itself
1868          are twice as wide.
1869          All operations are I64->V128.
1870          Example
1871             Iop_Widen32Sto64x2( [a, b] ) = [c, d]
1872                where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
1873       Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1874       Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
1875 
1876       /* INTERLEAVING */
1877       /* Interleave lanes from low or high halves of
1878          operands.  Most-significant result lane is from the left
1879          arg. */
1880       Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1881       Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
1882       Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
1883       Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
1884       /* Interleave odd/even lanes of operands.  Most-significant result lane
1885          is from the left arg. */
1886       Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1887       Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1888       Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1889 
1890       /* Pack even/odd lanes. */
1891       Iop_PackOddLanes8x16, Iop_PackEvenLanes8x16,
1892       Iop_PackOddLanes16x8, Iop_PackEvenLanes16x8,
1893       Iop_PackOddLanes32x4, Iop_PackEvenLanes32x4,
1894 
1895       /* CONCATENATION -- build a new value by concatenating either
1896          the even or odd lanes of both operands.  Note that
1897          Cat{Odd,Even}Lanes64x2 are identical to Interleave{HI,LO}64x2
1898          and so are omitted. */
1899       Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1900       Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1901 
1902       /* GET elements of VECTOR
1903          GET is binop (V128, I8) -> I<elem_size>
1904          SET is triop (V128, I8, I<elem_size>) -> V128 */
1905       /* Note: the arm back-end handles only constant second argument. */
1906       Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
1907       Iop_SetElem8x16, Iop_SetElem16x8, Iop_SetElem32x4, Iop_SetElem64x2,
1908 
1909       /* DUPLICATING -- copy value to all lanes */
1910       Iop_Dup8x16,   Iop_Dup16x8,   Iop_Dup32x4,
1911 
1912       /* SLICE -- produces the lowest 128 bits of (arg1:arg2) >> (8 * arg3).
1913          arg3 is a shift amount in bytes and may be between 0 and 16
1914          inclusive.  When 0, the result is arg2; when 16, the result is arg1.
1915          Not all back ends handle all values.  The arm64 back
1916          end handles only immediate arg3 values. */
1917       Iop_SliceV128,  // (V128, V128, I8) -> V128
1918 
1919       /* REVERSE the order of chunks in vector lanes.  Chunks must be
1920          smaller than the vector lanes (obviously) and so may be 8-,
1921          16- and 32-bit in size.  See definitions of 64-bit SIMD
1922          versions above for examples. */
1923       Iop_Reverse8sIn16_x8,
1924       Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
1925       Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
1926       Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
1927 
1928       /* PERMUTING -- copy src bytes to dst,
1929          as indexed by control vector bytes:
1930             for i in 0 .. 15 . result[i] = argL[ argR[i] ] 
1931          argR[i] values may only be in the range 0 .. 15, else behaviour
1932          is undefined.  That is, argR[i][7:4] must be zero. */
1933       Iop_Perm8x16,
1934       Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
1935 
1936       /* PERMUTING with optional zeroing:
1937             for i in 0 .. 15 . result[i] = if argR[i] bit 7 is set
1938                                            then zero else argL[ argR[i] ]
1939          argR[i][6:4] must be zero, else behaviour is undefined.
1940       */
1941       Iop_PermOrZero8x16,
1942 
1943       /* same, but Triop (argL consists of two 128-bit parts) */
1944       /* correct range for argR values is 0..31 */
1945       /* (V128, V128, V128) -> V128 */
1946       /* (ArgL_first, ArgL_second, ArgR) -> result */
1947       Iop_Perm8x16x2,
1948 
1949       /* MISC CONVERSION -- get high bits of each byte lane, a la
1950          x86/amd64 pmovmskb */
1951       Iop_GetMSBs8x16, /* V128 -> I16 */
1952 
1953       /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1954          See floating-point equivalents for details. */
1955       Iop_RecipEst32Ux4, Iop_RSqrtEst32Ux4,
1956 
1957       /* 128-bit multipy by 10 instruction, result is lower 128-bits */
1958       Iop_MulI128by10,
1959 
1960       /* 128-bit multipy by 10 instruction, result is carry out from the MSB */
1961       Iop_MulI128by10Carry,
1962 
1963       /* 128-bit multipy by 10 instruction, result is lower 128-bits of the
1964        * source times 10 plus the carry in
1965        */
1966       Iop_MulI128by10E,
1967 
1968       /* 128-bit multipy by 10 instruction, result is carry out from the MSB
1969        * of the source times 10 plus the carry in
1970        */
1971       Iop_MulI128by10ECarry,
1972 
1973      /* 128-bit carry out from ((U64 * U64 -> U128) + (U64 * U64 -> U128)) */
1974       Iop_2xMultU64Add128CarryOut,
1975 
1976       /* ------------------ 256-bit SIMD Integer. ------------------ */
1977 
1978       /* Pack/unpack */
1979       Iop_V256to64_0,  // V256 -> I64, extract least significant lane
1980       Iop_V256to64_1,
1981       Iop_V256to64_2,
1982       Iop_V256to64_3,  // V256 -> I64, extract most significant lane
1983 
1984       Iop_64x4toV256,  // (I64,I64,I64,I64)->V256
1985                        // first arg is most significant lane
1986 
1987       Iop_V256toV128_0, // V256 -> V128, less significant lane
1988       Iop_V256toV128_1, // V256 -> V128, more significant lane
1989       Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1990 
1991       Iop_AndV256,
1992       Iop_OrV256,
1993       Iop_XorV256,
1994       Iop_NotV256,
1995 
1996       /* MISC (vector integer cmp != 0) */
1997       Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1998 
1999       Iop_Add8x32,    Iop_Add16x16,    Iop_Add32x8,    Iop_Add64x4,
2000       Iop_Sub8x32,    Iop_Sub16x16,    Iop_Sub32x8,    Iop_Sub64x4,
2001 
2002       Iop_CmpEQ8x32,  Iop_CmpEQ16x16,  Iop_CmpEQ32x8,  Iop_CmpEQ64x4,
2003       Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4,
2004 
2005       Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4,
2006       Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4,
2007       Iop_SarN16x16, Iop_SarN32x8,
2008 
2009       Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8,
2010       Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8,
2011       Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8,
2012       Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8,
2013 
2014       Iop_Mul16x16, Iop_Mul32x8,
2015       Iop_MulHi16Ux16, Iop_MulHi16Sx16,
2016 
2017       Iop_QAdd8Ux32, Iop_QAdd16Ux16,
2018       Iop_QAdd8Sx32, Iop_QAdd16Sx16,
2019       Iop_QSub8Ux32, Iop_QSub16Ux16,
2020       Iop_QSub8Sx32, Iop_QSub16Sx16,
2021 
2022       Iop_Avg8Ux32, Iop_Avg16Ux16,
2023 
2024       Iop_Perm32x8,
2025 
2026       /* (V128, V128) -> V128 */
2027       Iop_CipherV128, Iop_CipherLV128, Iop_CipherSV128,
2028       Iop_NCipherV128, Iop_NCipherLV128,
2029 
2030       /* Hash instructions, Federal Information Processing Standards
2031        * Publication 180-3 Secure Hash Standard. */
2032       /* (V128, I8) -> V128; The I8 input arg is (ST | SIX), where ST and
2033        * SIX are fields from the insn. See ISA 2.07 description of
2034        * vshasigmad and vshasigmaw insns.*/
2035       Iop_SHA512, Iop_SHA256,
2036 
2037       /* ------------------ 256-bit SIMD FP. ------------------ */
2038 
2039       /* ternary :: IRRoundingMode(I32) x V256 x V256 -> V256 */
2040       Iop_Add64Fx4, Iop_Sub64Fx4, Iop_Mul64Fx4, Iop_Div64Fx4,
2041       Iop_Add32Fx8, Iop_Sub32Fx8, Iop_Mul32Fx8, Iop_Div32Fx8,
2042 
2043       Iop_I32StoF32x8, /* IRRoundingMode(I32) x V256 -> V256 */
2044       Iop_F32toI32Sx8, /* IRRoundingMode(I32) x V256 -> V256 */
2045 
2046       Iop_F32toF16x8,  /* IRRoundingMode(I32) x V256 -> V128 */
2047       Iop_F16toF32x8,  /* F16x8(==V128) -> F32x8(==V256) */
2048 
2049       Iop_Sqrt32Fx8,
2050       Iop_Sqrt64Fx4,
2051       Iop_RSqrtEst32Fx8,
2052       Iop_RecipEst32Fx8,
2053 
2054       Iop_Max32Fx8, Iop_Min32Fx8,
2055       Iop_Max64Fx4, Iop_Min64Fx4,
2056       Iop_Rotx32, Iop_Rotx64,
2057       Iop_LAST      /* must be the last enumerator */
2058    }
2059    IROp;
2060 
2061 /* Pretty-print an op. */
2062 extern void ppIROp ( IROp );
2063 
2064 /* For a given operand return the types of its arguments and its result. */
2065 extern void typeOfPrimop ( IROp op,
2066                            /*OUTs*/ IRType* t_dst, IRType* t_arg1,
2067                            IRType* t_arg2, IRType* t_arg3, IRType* t_arg4 );
2068 
2069 /* Might the given primop trap (eg, attempt integer division by zero)?  If in
2070    doubt returns True.  However, the vast majority of primops will never
2071    trap. */
2072 extern Bool primopMightTrap ( IROp op );
2073 
2074 /* Encoding of IEEE754-specified rounding modes.
2075    Note, various front and back ends rely on the actual numerical
2076    values of these, so do not change them. */
2077 typedef
2078    enum { 
2079       Irrm_NEAREST              = 0,  // Round to nearest, ties to even
2080       Irrm_NegINF               = 1,  // Round to negative infinity
2081       Irrm_PosINF               = 2,  // Round to positive infinity
2082       Irrm_ZERO                 = 3,  // Round toward zero
2083       Irrm_NEAREST_TIE_AWAY_0   = 4,  // Round to nearest, ties away from 0
2084       Irrm_PREPARE_SHORTER      = 5,  // Round to prepare for shorter 
2085                                       // precision
2086       Irrm_AWAY_FROM_ZERO       = 6,  // Round to away from 0
2087       Irrm_NEAREST_TIE_TOWARD_0 = 7   // Round to nearest, ties towards 0
2088    }
2089    IRRoundingMode;
2090 
2091 /* Binary floating point comparison result values.
2092    This is also derived from what IA32 does. */
2093 typedef
2094    enum {
2095       Ircr_UN = 0x45,
2096       Ircr_LT = 0x01,
2097       Ircr_GT = 0x00,
2098       Ircr_EQ = 0x40
2099    }
2100    IRCmpFResult;
2101 
2102 typedef IRCmpFResult IRCmpF32Result;
2103 typedef IRCmpFResult IRCmpF64Result;
2104 typedef IRCmpFResult IRCmpF128Result;
2105 
2106 /* Decimal floating point result values. */
2107 typedef IRCmpFResult IRCmpDResult;
2108 typedef IRCmpDResult IRCmpD64Result;
2109 typedef IRCmpDResult IRCmpD128Result;
2110 
2111 /* ------------------ Expressions ------------------ */
2112 
2113 typedef struct _IRQop   IRQop;   /* forward declaration */
2114 typedef struct _IRTriop IRTriop; /* forward declaration */
2115 
2116 
2117 /* The different kinds of expressions.  Their meaning is explained below
2118    in the comments for IRExpr. */
2119 typedef
2120    enum { 
2121       Iex_Binder=0x1900,
2122       Iex_Get,
2123       Iex_GetI,
2124       Iex_RdTmp,
2125       Iex_Qop,
2126       Iex_Triop,
2127       Iex_Binop,
2128       Iex_Unop,
2129       Iex_Load,
2130       Iex_Const,
2131       Iex_ITE,
2132       Iex_CCall,
2133       Iex_VECRET,
2134       Iex_GSPTR
2135    }
2136    IRExprTag;
2137 
2138 /* An expression.  Stored as a tagged union.  'tag' indicates what kind
2139    of expression this is.  'Iex' is the union that holds the fields.  If
2140    an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
2141    expression, and the fields can be accessed with
2142    'e.Iex.Load.<fieldname>'.
2143 
2144    For each kind of expression, we show what it looks like when
2145    pretty-printed with ppIRExpr().
2146 */
2147 typedef
2148    struct _IRExpr
2149    IRExpr;
2150 
2151 struct _IRExpr {
2152    IRExprTag tag;
2153    union {
2154       /* Used only in pattern matching within Vex.  Should not be seen
2155          outside of Vex. */
2156       struct {
2157          Int binder;
2158       } Binder;
2159 
2160       /* Read a guest register, at a fixed offset in the guest state.
2161          ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
2162       */
2163       struct {
2164          Int    offset;    /* Offset into the guest state */
2165          IRType ty;        /* Type of the value being read */
2166       } Get;
2167 
2168       /* Read a guest register at a non-fixed offset in the guest
2169          state.  This allows circular indexing into parts of the guest
2170          state, which is essential for modelling situations where the
2171          identity of guest registers is not known until run time.  One
2172          example is the x87 FP register stack.
2173 
2174          The part of the guest state to be treated as a circular array
2175          is described in the IRRegArray 'descr' field.  It holds the
2176          offset of the first element in the array, the type of each
2177          element, and the number of elements.
2178 
2179          The array index is indicated rather indirectly, in a way
2180          which makes optimisation easy: as the sum of variable part
2181          (the 'ix' field) and a constant offset (the 'bias' field).
2182 
2183          Since the indexing is circular, the actual array index to use
2184          is computed as (ix + bias) % num-of-elems-in-the-array.
2185 
2186          Here's an example.  The description
2187 
2188             (96:8xF64)[t39,-7]
2189 
2190          describes an array of 8 F64-typed values, the
2191          guest-state-offset of the first being 96.  This array is
2192          being indexed at (t39 - 7) % 8.
2193 
2194          It is important to get the array size/type exactly correct
2195          since IR optimisation looks closely at such info in order to
2196          establish aliasing/non-aliasing between seperate GetI and
2197          PutI events, which is used to establish when they can be
2198          reordered, etc.  Putting incorrect info in will lead to
2199          obscure IR optimisation bugs.
2200 
2201             ppIRExpr output: GETI<descr>[<ix>,<bias]
2202                          eg. GETI(128:8xI8)[t1,0]
2203       */
2204       struct {
2205          IRRegArray* descr; /* Part of guest state treated as circular */
2206          IRExpr*     ix;    /* Variable part of index into array */
2207          Int         bias;  /* Constant offset part of index into array */
2208       } GetI;
2209 
2210       /* The value held by a temporary.
2211          ppIRExpr output: t<tmp>, eg. t1
2212       */
2213       struct {
2214          IRTemp tmp;       /* The temporary number */
2215       } RdTmp;
2216 
2217       /* A quaternary operation.
2218          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
2219                       eg. MAddF64r32(t1, t2, t3, t4)
2220       */
2221       struct {
2222         IRQop* details;
2223       } Qop;
2224 
2225       /* A ternary operation.
2226          ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
2227                       eg. MulF64(1, 2.0, 3.0)
2228       */
2229       struct {
2230         IRTriop* details;
2231       } Triop;
2232 
2233       /* A binary operation.
2234          ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
2235       */
2236       struct {
2237          IROp op;          /* op-code   */
2238          IRExpr* arg1;     /* operand 1 */
2239          IRExpr* arg2;     /* operand 2 */
2240       } Binop;
2241 
2242       /* A unary operation.
2243          ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
2244       */
2245       struct {
2246          IROp    op;       /* op-code */
2247          IRExpr* arg;      /* operand */
2248       } Unop;
2249 
2250       /* A load from memory -- a normal load, not a load-linked.
2251          Load-Linkeds (and Store-Conditionals) are instead represented
2252          by IRStmt.LLSC since Load-Linkeds have side effects and so
2253          are not semantically valid IRExpr's.
2254          ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
2255       */
2256       struct {
2257          IREndness end;    /* Endian-ness of the load */
2258          IRType    ty;     /* Type of the loaded value */
2259          IRExpr*   addr;   /* Address being loaded from */
2260       } Load;
2261 
2262       /* A constant-valued expression.
2263          ppIRExpr output: <con>, eg. 0x4:I32
2264       */
2265       struct {
2266          IRConst* con;     /* The constant itself */
2267       } Const;
2268 
2269       /* A call to a pure (no side-effects) helper C function.
2270 
2271          With the 'cee' field, 'name' is the function's name.  It is
2272          only used for pretty-printing purposes.  The address to call
2273          (host address, of course) is stored in the 'addr' field
2274          inside 'cee'.
2275 
2276          The 'args' field is a NULL-terminated array of arguments.
2277          The stated return IRType, and the implied argument types,
2278          must match that of the function being called well enough so
2279          that the back end can actually generate correct code for the
2280          call.
2281 
2282          The called function **must** satisfy the following:
2283 
2284          * no side effects -- must be a pure function, the result of
2285            which depends only on the passed parameters.
2286 
2287          * it may not look at, nor modify, any of the guest state
2288            since that would hide guest state transitions from
2289            instrumenters
2290 
2291          * it may not access guest memory, since that would hide
2292            guest memory transactions from the instrumenters
2293 
2294          * it must not assume that arguments are being evaluated in a
2295            particular order. The oder of evaluation is unspecified.
2296 
2297          This is restrictive, but makes the semantics clean, and does
2298          not interfere with IR optimisation.
2299 
2300          If you want to call a helper which can mess with guest state
2301          and/or memory, instead use Ist_Dirty.  This is a lot more
2302          flexible, but you have to give a bunch of details about what
2303          the helper does (and you better be telling the truth,
2304          otherwise any derived instrumentation will be wrong).  Also
2305          Ist_Dirty inhibits various IR optimisations and so can cause
2306          quite poor code to be generated.  Try to avoid it.
2307 
2308          In principle it would be allowable to have the arg vector
2309          contain an IRExpr_VECRET(), although not IRExpr_GSPTR(). However,
2310          at the moment there is no requirement for clean helper calls to
2311          be able to return V128 or V256 values.  Hence this is not allowed.
2312 
2313          ppIRExpr output: <cee>(<args>):<retty>
2314                       eg. foo{0x80489304}(t1, t2):I32
2315       */
2316       struct {
2317          IRCallee* cee;    /* Function to call. */
2318          IRType    retty;  /* Type of return value. */
2319          IRExpr**  args;   /* Vector of argument expressions. */
2320       }  CCall;
2321 
2322       /* A ternary if-then-else operator.  It returns iftrue if cond is
2323          nonzero, iffalse otherwise.  Note that it is STRICT, ie. both
2324          iftrue and iffalse are evaluated in all cases.
2325 
2326          ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>),
2327                          eg. ITE(t6,t7,t8)
2328       */
2329       struct {
2330          IRExpr* cond;     /* Condition */
2331          IRExpr* iftrue;   /* True expression */
2332          IRExpr* iffalse;  /* False expression */
2333       } ITE;
2334    } Iex;
2335 };
2336 
2337 /* Expression auxiliaries: a ternary expression. */
2338 struct _IRTriop {
2339    IROp op;          /* op-code   */
2340    IRExpr* arg1;     /* operand 1 */
2341    IRExpr* arg2;     /* operand 2 */
2342    IRExpr* arg3;     /* operand 3 */
2343 };
2344 
2345 /* Expression auxiliaries: a quarternary expression. */
2346 struct _IRQop {
2347    IROp op;          /* op-code   */
2348    IRExpr* arg1;     /* operand 1 */
2349    IRExpr* arg2;     /* operand 2 */
2350    IRExpr* arg3;     /* operand 3 */
2351    IRExpr* arg4;     /* operand 4 */
2352 };
2353 
2354 
2355 /* Two special kinds of IRExpr, which can ONLY be used in
2356    argument lists for dirty helper calls (IRDirty.args) and in NO
2357    OTHER PLACES.  And then only in very limited ways.  */
2358 
2359 /* Denotes an argument which (in the helper) takes a pointer to a
2360    (naturally aligned) V128 or V256, into which the helper is expected
2361    to write its result.  Use of IRExpr_VECRET() is strictly
2362    controlled.  If the helper returns a V128 or V256 value then
2363    IRExpr_VECRET() must appear exactly once in the arg list, although
2364    it can appear anywhere, and the helper must have a C 'void' return
2365    type.  If the helper returns any other type, IRExpr_VECRET() may
2366    not appear in the argument list. */
2367 
2368 /* Denotes an void* argument which is passed to the helper, which at
2369    run time will point to the thread's guest state area.  This can
2370    only appear at most once in an argument list, and it may not appear
2371    at all in argument lists for clean helper calls. */
2372 
2373 static inline Bool is_IRExpr_VECRET_or_GSPTR ( const IRExpr* e ) {
2374    return e->tag == Iex_VECRET || e->tag == Iex_GSPTR;
2375 }
2376 
2377 
2378 /* Expression constructors. */
2379 extern IRExpr* IRExpr_Binder ( Int binder );
2380 extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
2381 extern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
2382 extern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
2383 extern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2, 
2384                                         IRExpr* arg3, IRExpr* arg4 );
2385 extern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1, 
2386                                         IRExpr* arg2, IRExpr* arg3 );
2387 extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
2388 extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
2389 extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
2390 extern IRExpr* IRExpr_Const  ( IRConst* con );
2391 extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
2392 extern IRExpr* IRExpr_ITE    ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse );
2393 extern IRExpr* IRExpr_VECRET ( void );
2394 extern IRExpr* IRExpr_GSPTR  ( void );
2395 
2396 /* Deep-copy an IRExpr. */
2397 extern IRExpr* deepCopyIRExpr ( const IRExpr* );
2398 
2399 /* Pretty-print an IRExpr. */
2400 extern void ppIRExpr ( const IRExpr* );
2401 
2402 /* NULL-terminated IRExpr vector constructors, suitable for
2403    use as arg lists in clean/dirty helper calls. */
2404 extern IRExpr** mkIRExprVec_0 ( void );
2405 extern IRExpr** mkIRExprVec_1 ( IRExpr* );
2406 extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
2407 extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
2408 extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2409 extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2410                                 IRExpr* );
2411 extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2412                                 IRExpr*, IRExpr* );
2413 extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2414                                 IRExpr*, IRExpr*, IRExpr* );
2415 extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2416                                 IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2417 extern IRExpr** mkIRExprVec_9 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2418                                 IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2419 extern IRExpr** mkIRExprVec_13 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2420                                  IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2421                                  IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2422 
2423 /* IRExpr copiers:
2424    - shallowCopy: shallow-copy (ie. create a new vector that shares the
2425      elements with the original).
2426    - deepCopy: deep-copy (ie. create a completely new vector). */
2427 extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
2428 extern IRExpr** deepCopyIRExprVec ( IRExpr *const * );
2429 
2430 /* Make a constant expression from the given host word taking into
2431    account (of course) the host word size. */
2432 extern IRExpr* mkIRExpr_HWord ( HWord );
2433 
2434 /* Convenience function for constructing clean helper calls. */
2435 extern 
2436 IRExpr* mkIRExprCCall ( IRType retty,
2437                         Int regparms, const HChar* name, void* addr, 
2438                         IRExpr** args );
2439 
2440 
2441 /* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
2442  * Iex_Const). */
2443 static inline Bool isIRAtom ( const IRExpr* e ) {
2444    return e->tag == Iex_RdTmp || e->tag == Iex_Const;
2445 }
2446 
2447 /* Are these two IR atoms identical?  Causes an assertion
2448    failure if they are passed non-atoms. */
2449 extern Bool eqIRAtom ( const IRExpr*, const IRExpr* );
2450 
2451 
2452 /* ------------------ Jump kinds ------------------ */
2453 
2454 /* This describes hints which can be passed to the dispatcher at guest
2455    control-flow transfer points.
2456 
2457    Re Ijk_InvalICache and Ijk_FlushDCache: the guest state _must_ have
2458    two pseudo-registers, guest_CMSTART and guest_CMLEN, which specify
2459    the start and length of the region to be invalidated.  CM stands
2460    for "Cache Management".  These are both the size of a guest word.
2461    It is the responsibility of the relevant toIR.c to ensure that
2462    these are filled in with suitable values before issuing a jump of
2463    kind Ijk_InvalICache or Ijk_FlushDCache.
2464 
2465    Ijk_InvalICache requests invalidation of translations taken from
2466    the requested range.  Ijk_FlushDCache requests flushing of the D
2467    cache for the specified range.
2468 
2469    Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
2470    pseudo-register guest_EMNOTE, which is 32-bits regardless of the
2471    host or guest word size.  That register should be made to hold a
2472    VexEmNote value to indicate the reason for the exit.
2473 
2474    In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
2475    cannot continue) and so the jump destination can be anything.
2476 
2477    Re Ijk_Sys_ (syscall jumps): the guest state must have a
2478    pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
2479    word.  Front ends should set this to be the IP at the most recently
2480    executed kernel-entering (system call) instruction.  This makes it
2481    very much easier (viz, actually possible at all) to back up the
2482    guest to restart a syscall that has been interrupted by a signal.
2483 */
2484 typedef
2485    enum {
2486       Ijk_INVALID=0x1A00, 
2487       Ijk_Boring,         /* not interesting; just goto next */
2488       Ijk_Call,           /* guest is doing a call */
2489       Ijk_Ret,            /* guest is doing a return */
2490       Ijk_ClientReq,      /* do guest client req before continuing */
2491       Ijk_Yield,          /* client is yielding to thread scheduler */
2492       Ijk_EmWarn,         /* report emulation warning before continuing */
2493       Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
2494       Ijk_NoDecode,       /* current instruction cannot be decoded */
2495       Ijk_MapFail,        /* Vex-provided address translation failed */
2496       Ijk_InvalICache,    /* Inval icache for range [CMSTART, +CMLEN) */
2497       Ijk_FlushDCache,    /* Flush dcache for range [CMSTART, +CMLEN) */
2498       Ijk_NoRedir,        /* Jump to un-redirected guest addr */
2499       Ijk_SigILL,         /* current instruction synths SIGILL */
2500       Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
2501       Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
2502       Ijk_SigBUS,         /* current instruction synths SIGBUS */
2503       Ijk_SigFPE,         /* current instruction synths generic SIGFPE */
2504       Ijk_SigFPE_IntDiv,  /* current instruction synths SIGFPE - IntDiv */
2505       Ijk_SigFPE_IntOvf,  /* current instruction synths SIGFPE - IntOvf */
2506       /* Unfortunately, various guest-dependent syscall kinds.  They
2507      all mean: do a syscall before continuing. */
2508       Ijk_Sys_syscall,    /* amd64/x86 'syscall', ppc 'sc', arm 'svc #0' */
2509       Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
2510       Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
2511       Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
2512       Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
2513       Ijk_Sys_int145,     /* amd64/x86 'int $0x91' */
2514       Ijk_Sys_int210,     /* amd64/x86 'int $0xD2' */
2515       Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes 
2516                              invalid at the point this happens. */
2517    }
2518    IRJumpKind;
2519 
2520 extern void ppIRJumpKind ( IRJumpKind );
2521 
2522 
2523 /* ------------------ Dirty helper calls ------------------ */
2524 
2525 /* A dirty call is a flexible mechanism for calling (possibly
2526    conditionally) a helper function or procedure.  The helper function
2527    may read, write or modify client memory, and may read, write or
2528    modify client state.  It can take arguments and optionally return a
2529    value.  It may return different results and/or do different things
2530    when called repeatedly with the same arguments, by means of storing
2531    private state.
2532 
2533    If a value is returned, it is assigned to the nominated return
2534    temporary.
2535 
2536    Dirty calls are statements rather than expressions for obvious
2537    reasons.  If a dirty call is marked as writing guest state, any
2538    pre-existing values derived from the written parts of the guest
2539    state are invalid.  Similarly, if the dirty call is stated as
2540    writing memory, any pre-existing loaded values are invalidated by
2541    it.
2542 
2543    In order that instrumentation is possible, the call must state, and
2544    state correctly:
2545 
2546    * Whether it reads, writes or modifies memory, and if so where.
2547 
2548    * Whether it reads, writes or modifies guest state, and if so which
2549      pieces.  Several pieces may be stated, and their extents must be
2550      known at translation-time.  Each piece is allowed to repeat some
2551      number of times at a fixed interval, if required.
2552 
2553    Normally, code is generated to pass just the args to the helper.
2554    However, if IRExpr_GSPTR() is present in the argument list (at most
2555    one instance is allowed), then the guest state pointer is passed for
2556    that arg, so that the callee can access the guest state.  It is
2557    invalid for .nFxState to be zero but IRExpr_GSPTR() to be present,
2558    since .nFxState==0 is a claim that the call does not access guest
2559    state.
2560 
2561    IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
2562    arguments and 'mFx' are evaluated REGARDLESS of the guard value.
2563    The order of argument evaluation is unspecified.  The guard
2564    expression is evaluated AFTER the arguments and 'mFx' have been
2565    evaluated.  'mFx' is expected (by Memcheck) to be a defined value
2566    even if the guard evaluates to false.
2567 */
2568 
2569 #define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
2570 
2571 /* Effects on resources (eg. registers, memory locations) */
2572 typedef
2573    enum {
2574       Ifx_None=0x1B00,      /* no effect */
2575       Ifx_Read,             /* reads the resource */
2576       Ifx_Write,            /* writes the resource */
2577       Ifx_Modify,           /* modifies the resource */
2578    }
2579    IREffect;
2580 
2581 /* Pretty-print an IREffect */
2582 extern void ppIREffect ( IREffect );
2583 
2584 typedef
2585    struct _IRDirty {
2586       /* What to call, and details of args/results.  .guard must be
2587          non-NULL.  If .tmp is not IRTemp_INVALID, then the call
2588          returns a result which is placed in .tmp.  If at runtime the
2589          guard evaluates to false, .tmp has an 0x555..555 bit pattern
2590          written to it.  Hence conditional calls that assign .tmp are
2591          allowed. */
2592       IRCallee* cee;    /* where to call */
2593       IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
2594       /* The args vector may contain IRExpr_GSPTR() and/or
2595          IRExpr_VECRET(), in both cases, at most once. */
2596       IRExpr**  args;   /* arg vector, ends in NULL. */
2597       IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
2598 
2599       /* Mem effects; we allow only one R/W/M region to be stated */
2600       IREffect  mFx;    /* indicates memory effects, if any */
2601       IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
2602       Int       mSize;  /* of access, or zero if mFx==Ifx_None */
2603 
2604       /* Guest state effects; up to N allowed */
2605       Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
2606       struct {
2607          IREffect fx:16;   /* read, write or modify?  Ifx_None is invalid. */
2608          UShort   offset;
2609          UShort   size;
2610          UChar    nRepeats;
2611          UChar    repeatLen;
2612       } fxState[VEX_N_FXSTATE];
2613       /* The access can be repeated, as specified by nRepeats and
2614          repeatLen.  To describe only a single access, nRepeats and
2615          repeatLen should be zero.  Otherwise, repeatLen must be a
2616          multiple of size and greater than size. */
2617       /* Overall, the parts of the guest state denoted by (offset,
2618          size, nRepeats, repeatLen) is
2619                [offset, +size)
2620             and, if nRepeats > 0,
2621                for (i = 1; i <= nRepeats; i++)
2622                   [offset + i * repeatLen, +size)
2623          A convenient way to enumerate all segments is therefore
2624             for (i = 0; i < 1 + nRepeats; i++)
2625                [offset + i * repeatLen, +size)
2626       */
2627    }
2628    IRDirty;
2629 
2630 /* Pretty-print a dirty call */
2631 extern void     ppIRDirty ( const IRDirty* );
2632 
2633 /* Allocate an uninitialised dirty call */
2634 extern IRDirty* emptyIRDirty ( void );
2635 
2636 /* Deep-copy a dirty call */
2637 extern IRDirty* deepCopyIRDirty ( const IRDirty* );
2638 
2639 /* A handy function which takes some of the tedium out of constructing
2640    dirty helper calls.  The called function impliedly does not return
2641    any value and has a constant-True guard.  The call is marked as
2642    accessing neither guest state nor memory (hence the "unsafe"
2643    designation) -- you can change this marking later if need be.  A
2644    suitable IRCallee is constructed from the supplied bits. */
2645 extern 
2646 IRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr, 
2647                              IRExpr** args );
2648 
2649 /* Similarly, make a zero-annotation dirty call which returns a value,
2650    and assign that to the given temp. */
2651 extern 
2652 IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 
2653                              Int regparms, const HChar* name, void* addr, 
2654                              IRExpr** args );
2655 
2656 
2657 /* --------------- Memory Bus Events --------------- */
2658 
2659 typedef
2660    enum { 
2661       Imbe_Fence=0x1C00, 
2662       /* Needed only on ARM.  It cancels a reservation made by a
2663          preceding Linked-Load, and needs to be handed through to the
2664          back end, just as LL and SC themselves are. */
2665       Imbe_CancelReservation
2666    }
2667    IRMBusEvent;
2668 
2669 extern void ppIRMBusEvent ( IRMBusEvent );
2670 
2671 
2672 /* --------------- Compare and Swap --------------- */
2673 
2674 /* This denotes an atomic compare and swap operation, either
2675    a single-element one or a double-element one.
2676 
2677    In the single-element case:
2678 
2679      .addr is the memory address.
2680      .end  is the endianness with which memory is accessed
2681 
2682      If .addr contains the same value as .expdLo, then .dataLo is
2683      written there, else there is no write.  In both cases, the
2684      original value at .addr is copied into .oldLo.
2685 
2686      Types: .expdLo, .dataLo and .oldLo must all have the same type.
2687      It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2688      guests, I64.
2689 
2690      .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2691      be NULL.
2692 
2693    In the double-element case:
2694 
2695      .addr is the memory address.
2696      .end  is the endianness with which memory is accessed
2697 
2698      The operation is the same:
2699 
2700      If .addr contains the same value as .expdHi:.expdLo, then
2701      .dataHi:.dataLo is written there, else there is no write.  In
2702      both cases the original value at .addr is copied into
2703      .oldHi:.oldLo.
2704 
2705      Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2706      all have the same type, which may be any integral type, viz: I8,
2707      I16, I32 or, for 64-bit guests, I64.
2708 
2709      The double-element case is complicated by the issue of
2710      endianness.  In all cases, the two elements are understood to be
2711      located adjacently in memory, starting at the address .addr.
2712 
2713        If .end is Iend_LE, then the .xxxLo component is at the lower
2714        address and the .xxxHi component is at the higher address, and
2715        each component is itself stored little-endianly.
2716 
2717        If .end is Iend_BE, then the .xxxHi component is at the lower
2718        address and the .xxxLo component is at the higher address, and
2719        each component is itself stored big-endianly.
2720 
2721    This allows representing more cases than most architectures can
2722    handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
2723 
2724    How to know if the CAS succeeded?
2725 
2726    * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2727      then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2728      stored at .addr, and the original value there was .oldLo (resp
2729      .oldHi:.oldLo).
2730 
2731    * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2732      then the CAS failed, and the original value at .addr was .oldLo
2733      (resp. .oldHi:.oldLo).
2734 
2735    Hence it is easy to know whether or not the CAS succeeded.
2736 */
2737 typedef
2738    struct {
2739       IRTemp    oldHi;  /* old value of *addr is written here */
2740       IRTemp    oldLo;
2741       IREndness end;    /* endianness of the data in memory */
2742       IRExpr*   addr;   /* store address */
2743       IRExpr*   expdHi; /* expected old value at *addr */
2744       IRExpr*   expdLo;
2745       IRExpr*   dataHi; /* new value for *addr */
2746       IRExpr*   dataLo;
2747    }
2748    IRCAS;
2749 
2750 extern void ppIRCAS ( const IRCAS* cas );
2751 
2752 extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2753                         IREndness end, IRExpr* addr, 
2754                         IRExpr* expdHi, IRExpr* expdLo,
2755                         IRExpr* dataHi, IRExpr* dataLo );
2756 
2757 extern IRCAS* deepCopyIRCAS ( const IRCAS* );
2758 
2759 
2760 /* ------------------ Circular Array Put ------------------ */
2761 
2762 typedef
2763    struct {
2764       IRRegArray* descr; /* Part of guest state treated as circular */
2765       IRExpr*     ix;    /* Variable part of index into array */
2766       Int         bias;  /* Constant offset part of index into array */
2767       IRExpr*     data;  /* The value to write */
2768    } IRPutI;
2769 
2770 extern void ppIRPutI ( const IRPutI* puti );
2771 
2772 extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2773                           Int bias, IRExpr* data );
2774 
2775 extern IRPutI* deepCopyIRPutI ( const IRPutI* );
2776 
2777 
2778 /* --------------- Guarded loads and stores --------------- */
2779 
2780 /* Conditional stores are straightforward.  They are the same as
2781    normal stores, with an extra 'guard' field :: Ity_I1 that
2782    determines whether or not the store actually happens.  If not,
2783    memory is unmodified.
2784 
2785    The semantics of this is that 'addr' and 'data' are fully evaluated
2786    even in the case where 'guard' evaluates to zero (false).
2787 */
2788 typedef
2789    struct {
2790       IREndness end;    /* Endianness of the store */
2791       IRExpr*   addr;   /* store address */
2792       IRExpr*   data;   /* value to write */
2793       IRExpr*   guard;  /* Guarding value */
2794    }
2795    IRStoreG;
2796 
2797 /* Conditional loads are a little more complex.  'addr' is the
2798    address, 'guard' is the guarding condition.  If the load takes
2799    place, the loaded value is placed in 'dst'.  If it does not take
2800    place, 'alt' is copied to 'dst'.  However, the loaded value is not
2801    placed directly in 'dst' -- it is first subjected to the conversion
2802    specified by 'cvt'.
2803 
2804    For example, imagine doing a conditional 8-bit load, in which the
2805    loaded value is zero extended to 32 bits.  Hence:
2806    * 'dst' and 'alt' must have type I32
2807    * 'cvt' must be a unary op which converts I8 to I32.  In this 
2808      example, it would be ILGop_8Uto32.
2809 
2810    There is no explicit indication of the type at which the load is
2811    done, since that is inferrable from the arg type of 'cvt'.  Note
2812    that the types of 'alt' and 'dst' and the result type of 'cvt' must
2813    all be the same.
2814 
2815    Semantically, 'addr' is evaluated even in the case where 'guard'
2816    evaluates to zero (false), and 'alt' is evaluated even when 'guard'
2817    evaluates to one (true).  That is, 'addr' and 'alt' are always
2818    evaluated.
2819 */
2820 typedef
2821    enum {
2822       ILGop_INVALID=0x1D00,
2823       ILGop_IdentV128, /* 128 bit vector, no conversion */
2824       ILGop_Ident64,   /* 64 bit, no conversion */
2825       ILGop_Ident32,   /* 32 bit, no conversion */
2826       ILGop_16Uto32,   /* 16 bit load, Z-widen to 32 */
2827       ILGop_16Sto32,   /* 16 bit load, S-widen to 32 */
2828       ILGop_8Uto32,    /* 8 bit load, Z-widen to 32 */
2829       ILGop_8Sto32     /* 8 bit load, S-widen to 32 */
2830    }
2831    IRLoadGOp;
2832 
2833 typedef
2834    struct {
2835       IREndness end;    /* Endianness of the load */
2836       IRLoadGOp cvt;    /* Conversion to apply to the loaded value */
2837       IRTemp    dst;    /* Destination (LHS) of assignment */
2838       IRExpr*   addr;   /* Address being loaded from */
2839       IRExpr*   alt;    /* Value if load is not done. */
2840       IRExpr*   guard;  /* Guarding value */
2841    }
2842    IRLoadG;
2843 
2844 extern void ppIRStoreG ( const IRStoreG* sg );
2845 
2846 extern void ppIRLoadGOp ( IRLoadGOp cvt );
2847 
2848 extern void ppIRLoadG ( const IRLoadG* lg );
2849 
2850 extern IRStoreG* mkIRStoreG ( IREndness end,
2851                               IRExpr* addr, IRExpr* data,
2852                               IRExpr* guard );
2853 
2854 extern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
2855                             IRTemp dst, IRExpr* addr, IRExpr* alt, 
2856                             IRExpr* guard );
2857 
2858 
2859 /* ------------------ Statements ------------------ */
2860 
2861 /* The different kinds of statements.  Their meaning is explained
2862    below in the comments for IRStmt.
2863 
2864    Those marked META do not represent code, but rather extra
2865    information about the code.  These statements can be removed
2866    without affecting the functional behaviour of the code, however
2867    they are required by some IR consumers such as tools that
2868    instrument the code.
2869 */
2870 
2871 typedef 
2872    enum {
2873       Ist_NoOp=0x1E00,
2874       Ist_IMark,     /* META */
2875       Ist_AbiHint,   /* META */
2876       Ist_Put,
2877       Ist_PutI,
2878       Ist_WrTmp,
2879       Ist_Store,
2880       Ist_LoadG,
2881       Ist_StoreG,
2882       Ist_CAS,
2883       Ist_LLSC,
2884       Ist_Dirty,
2885       Ist_MBE,
2886       Ist_Exit
2887    } 
2888    IRStmtTag;
2889 
2890 /* A statement.  Stored as a tagged union.  'tag' indicates what kind
2891    of expression this is.  'Ist' is the union that holds the fields.
2892    If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2893    statement, and the fields can be accessed with
2894    'st.Ist.Store.<fieldname>'.
2895 
2896    For each kind of statement, we show what it looks like when
2897    pretty-printed with ppIRStmt().
2898 */
2899 typedef
2900    struct _IRStmt {
2901       IRStmtTag tag;
2902       union {
2903          /* A no-op (usually resulting from IR optimisation).  Can be
2904             omitted without any effect.
2905 
2906             ppIRStmt output: IR-NoOp
2907          */
2908          struct {
2909      } NoOp;
2910 
2911          /* META: instruction mark.  Marks the start of the statements
2912             that represent a single machine instruction (the end of
2913             those statements is marked by the next IMark or the end of
2914             the IRSB).  Contains the address and length of the
2915             instruction.
2916 
2917             It also contains a delta value.  The delta must be
2918             subtracted from a guest program counter value before
2919             attempting to establish, by comparison with the address
2920             and length values, whether or not that program counter
2921             value refers to this instruction.  For x86, amd64, ppc32,
2922             ppc64 and arm, the delta value is zero.  For Thumb
2923             instructions, the delta value is one.  This is because, on
2924             Thumb, guest PC values (guest_R15T) are encoded using the
2925             top 31 bits of the instruction address and a 1 in the lsb;
2926             hence they appear to be (numerically) 1 past the start of
2927             the instruction they refer to.  IOW, guest_R15T on ARM
2928             holds a standard ARM interworking address.
2929 
2930             ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2931                          eg. ------ IMark(0x4000792, 5, 0) ------,
2932          */
2933          struct {
2934             Addr   addr;   /* instruction address */
2935             UInt   len;    /* instruction length */
2936             UChar  delta;  /* addr = program counter as encoded in guest state
2937                                      - delta */
2938          } IMark;
2939 
2940          /* META: An ABI hint, which says something about this
2941             platform's ABI.
2942 
2943             At the moment, the only AbiHint is one which indicates
2944             that a given chunk of address space, [base .. base+len-1],
2945             has become undefined.  This is used on amd64-linux and
2946             some ppc variants to pass stack-redzoning hints to whoever
2947             wants to see them.  It also indicates the address of the
2948             next (dynamic) instruction that will be executed.  This is
2949             to help Memcheck to origin tracking.
2950 
2951             ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
2952                          eg. ====== AbiHint(t1, 16, t2) ======
2953          */
2954          struct {
2955             IRExpr* base;     /* Start  of undefined chunk */
2956             Int     len;      /* Length of undefined chunk */
2957             IRExpr* nia;      /* Address of next (guest) insn */
2958          } AbiHint;
2959 
2960          /* Write a guest register, at a fixed offset in the guest state.
2961             ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
2962          */
2963          struct {
2964             Int     offset;   /* Offset into the guest state */
2965             IRExpr* data;     /* The value to write */
2966          } Put;
2967 
2968          /* Write a guest register, at a non-fixed offset in the guest
2969             state.  See the comment for GetI expressions for more
2970             information.
2971 
2972             ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
2973                          eg. PUTI(64:8xF64)[t5,0] = t1
2974          */
2975          struct {
2976             IRPutI* details;
2977          } PutI;
2978 
2979          /* Assign a value to a temporary.  Note that SSA rules require
2980             each tmp is only assigned to once.  IR sanity checking will
2981             reject any block containing a temporary which is not assigned
2982             to exactly once.
2983 
2984             ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
2985          */
2986          struct {
2987             IRTemp  tmp;   /* Temporary  (LHS of assignment) */
2988             IRExpr* data;  /* Expression (RHS of assignment) */
2989          } WrTmp;
2990 
2991          /* Write a value to memory.  This is a normal store, not a
2992             Store-Conditional.  To represent a Store-Conditional,
2993             instead use IRStmt.LLSC.
2994             ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
2995          */
2996          struct {
2997             IREndness end;    /* Endianness of the store */
2998             IRExpr*   addr;   /* store address */
2999             IRExpr*   data;   /* value to write */
3000          } Store;
3001 
3002          /* Guarded store.  Note that this is defined to evaluate all
3003             expression fields (addr, data) even if the guard evaluates
3004             to false.
3005             ppIRStmt output:
3006               if (<guard>) ST<end>(<addr>) = <data> */
3007          struct {
3008             IRStoreG* details;
3009          } StoreG;
3010 
3011          /* Guarded load.  Note that this is defined to evaluate all
3012             expression fields (addr, alt) even if the guard evaluates
3013             to false.
3014             ppIRStmt output:
3015               t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */
3016          struct {
3017             IRLoadG* details;
3018          } LoadG;
3019 
3020          /* Do an atomic compare-and-swap operation.  Semantics are
3021             described above on a comment at the definition of IRCAS.
3022 
3023             ppIRStmt output:
3024                t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
3025             eg
3026                t1 = CASle(t2 :: t3->Add32(t3,1))
3027                which denotes a 32-bit atomic increment 
3028                of a value at address t2
3029 
3030             A double-element CAS may also be denoted, in which case <tmp>,
3031             <expected> and <new> are all pairs of items, separated by
3032             commas.
3033          */
3034          struct {
3035             IRCAS* details;
3036          } CAS;
3037 
3038          /* Either Load-Linked or Store-Conditional, depending on
3039             STOREDATA.
3040 
3041             If STOREDATA is NULL then this is a Load-Linked, meaning
3042             that data is loaded from memory as normal, but a
3043             'reservation' for the address is also lodged in the
3044             hardware.
3045 
3046                result = Load-Linked(addr, end)
3047 
3048             The data transfer type is the type of RESULT (I32, I64,
3049             etc).  ppIRStmt output:
3050 
3051                result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
3052 
3053             If STOREDATA is not NULL then this is a Store-Conditional,
3054             hence:
3055 
3056                result = Store-Conditional(addr, storedata, end)
3057 
3058             The data transfer type is the type of STOREDATA and RESULT
3059             has type Ity_I1. The store may fail or succeed depending
3060             on the state of a previously lodged reservation on this
3061             address.  RESULT is written 1 if the store succeeds and 0
3062             if it fails.  eg ppIRStmt output:
3063 
3064                result = ( ST<end>-Cond(<addr>) = <storedata> )
3065                eg t3 = ( STbe-Cond(t1, t2) )
3066 
3067             In all cases, the address must be naturally aligned for
3068             the transfer type -- any misaligned addresses should be
3069             caught by a dominating IR check and side exit.  This
3070             alignment restriction exists because on at least some
3071             LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
3072             misaligned addresses, and we have to actually generate
3073             stwcx. on the host, and we don't want it trapping on the
3074             host.
3075 
3076             Summary of rules for transfer type:
3077               STOREDATA == NULL (LL):
3078                 transfer type = type of RESULT
3079               STOREDATA != NULL (SC):
3080                 transfer type = type of STOREDATA, and RESULT :: Ity_I1
3081          */
3082          struct {
3083             IREndness end;
3084             IRTemp    result;
3085             IRExpr*   addr;
3086             IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
3087          } LLSC;
3088 
3089          /* Call (possibly conditionally) a C function that has side
3090             effects (ie. is "dirty").  See the comments above the
3091             IRDirty type declaration for more information.
3092 
3093             ppIRStmt output:
3094                t<tmp> = DIRTY <guard> <effects> 
3095                   ::: <callee>(<args>)
3096             eg.
3097                t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
3098                      ::: foo{0x380035f4}(t2)
3099          */       
3100          struct {
3101             IRDirty* details;
3102          } Dirty;
3103 
3104          /* A memory bus event - a fence, or acquisition/release of the
3105             hardware bus lock.  IR optimisation treats all these as fences
3106             across which no memory references may be moved.
3107             ppIRStmt output: MBusEvent-Fence,
3108                              MBusEvent-BusLock, MBusEvent-BusUnlock.
3109          */
3110          struct {
3111             IRMBusEvent event;
3112          } MBE;
3113 
3114          /* Conditional exit from the middle of an IRSB.
3115             ppIRStmt output: if (<guard>) goto {<jk>} <dst>
3116                          eg. if (t69) goto {Boring} 0x4000AAA:I32
3117             If <guard> is true, the guest state is also updated by
3118             PUT-ing <dst> at <offsIP>.  This is done because a
3119             taken exit must update the guest program counter.
3120          */
3121          struct {
3122             IRExpr*    guard;    /* Conditional expression */
3123             IRConst*   dst;      /* Jump target (constant only) */
3124             IRJumpKind jk;       /* Jump kind */
3125             Int        offsIP;   /* Guest state offset for IP */
3126          } Exit;
3127       } Ist;
3128    }
3129    IRStmt;
3130 
3131 /* Statement constructors. */
3132 extern IRStmt* IRStmt_NoOp    ( void );
3133 extern IRStmt* IRStmt_IMark   ( Addr addr, UInt len, UChar delta );
3134 extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
3135 extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
3136 extern IRStmt* IRStmt_PutI    ( IRPutI* details );
3137 extern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
3138 extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
3139 extern IRStmt* IRStmt_StoreG  ( IREndness end, IRExpr* addr, IRExpr* data,
3140                                 IRExpr* guard );
3141 extern IRStmt* IRStmt_LoadG   ( IREndness end, IRLoadGOp cvt, IRTemp dst,
3142                                 IRExpr* addr, IRExpr* alt, IRExpr* guard );
3143 extern IRStmt* IRStmt_CAS     ( IRCAS* details );
3144 extern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
3145                                 IRExpr* addr, IRExpr* storedata );
3146 extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
3147 extern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
3148 extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
3149                                 Int offsIP );
3150 
3151 /* Deep-copy an IRStmt. */
3152 extern IRStmt* deepCopyIRStmt ( const IRStmt* );
3153 
3154 /* Pretty-print an IRStmt. */
3155 extern void ppIRStmt ( const IRStmt* );
3156 
3157 
3158 /* ------------------ Basic Blocks ------------------ */
3159 
3160 /* Type environments: a bunch of statements, expressions, etc, are
3161    incomplete without an environment indicating the type of each
3162    IRTemp.  So this provides one.  IR temporaries are really just
3163    unsigned ints and so this provides an array, 0 .. n_types_used-1 of
3164    them.
3165 */
3166 typedef
3167    struct {
3168       IRType* types;
3169       Int     types_size;
3170       Int     types_used;
3171    }
3172    IRTypeEnv;
3173 
3174 /* Obtain a new IRTemp */
3175 extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
3176 
3177 /* Deep-copy a type environment */
3178 extern IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* );
3179 
3180 /* Pretty-print a type environment */
3181 extern void ppIRTypeEnv ( const IRTypeEnv* );
3182 
3183 
3184 /* Code blocks, which in proper compiler terminology are superblocks
3185    (single entry, multiple exit code sequences) contain:
3186 
3187    - A table giving a type for each temp (the "type environment")
3188    - An expandable array of statements
3189    - An expression of type 32 or 64 bits, depending on the
3190      guest's word size, indicating the next destination if the block 
3191      executes all the way to the end, without a side exit
3192    - An indication of any special actions (JumpKind) needed
3193      for this final jump.
3194    - Offset of the IP field in the guest state.  This will be
3195      updated before the final jump is done.
3196    
3197    "IRSB" stands for "IR Super Block".
3198 */
3199 typedef
3200    struct {
3201       IRTypeEnv* tyenv;
3202       IRStmt**   stmts;
3203       Int        stmts_size;
3204       Int        stmts_used;
3205       IRExpr*    next;
3206       IRJumpKind jumpkind;
3207       Int        offsIP;
3208    }
3209    IRSB;
3210 
3211 /* Allocate a new, uninitialised IRSB */
3212 extern IRSB* emptyIRSB ( void );
3213 
3214 /* Deep-copy an IRSB */
3215 extern IRSB* deepCopyIRSB ( const IRSB* );
3216 
3217 /* Deep-copy an IRSB, except for the statements list, which set to be
3218    a new, empty, list of statements. */
3219 extern IRSB* deepCopyIRSBExceptStmts ( const IRSB* );
3220 
3221 /* Pretty-print an IRSB */
3222 extern void ppIRSB ( const IRSB* );
3223 
3224 /* Append an IRStmt to an IRSB */
3225 extern void addStmtToIRSB ( IRSB*, IRStmt* );
3226 
3227 
3228 /*---------------------------------------------------------------*/
3229 /*--- Helper functions for the IR                             ---*/
3230 /*---------------------------------------------------------------*/
3231 
3232 /* For messing with IR type environments */
3233 extern IRTypeEnv* emptyIRTypeEnv  ( void );
3234 
3235 /* What is the type of this expression? */
3236 extern IRType typeOfIRConst ( const IRConst* );
3237 extern IRType typeOfIRTemp  ( const IRTypeEnv*, IRTemp );
3238 extern IRType typeOfIRExpr  ( const IRTypeEnv*, const IRExpr* );
3239 
3240 /* What are the arg and result type for this IRLoadGOp? */
3241 extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
3242                               /*OUT*/IRType* t_res,
3243                               /*OUT*/IRType* t_arg );
3244 
3245 /* Sanity check a BB of IR */
3246 extern void sanityCheckIRSB ( const  IRSB*  bb, 
3247                               const  HChar* caller,
3248                               Bool   require_flatness, 
3249                               IRType guest_word_size );
3250 extern Bool isFlatIRStmt ( const IRStmt* );
3251 extern Bool isFlatIRSB ( const IRSB* );
3252 
3253 /* Is this any value actually in the enumeration 'IRType' ? */
3254 extern Bool isPlausibleIRType ( IRType ty );
3255 
3256 
3257 /*---------------------------------------------------------------*/
3258 /*--- IR injection                                            ---*/
3259 /*---------------------------------------------------------------*/
3260 
3261 void vex_inject_ir(IRSB *, IREndness);
3262 
3263 
3264 #endif /* ndef __LIBVEX_IR_H */
3265 
3266 /*---------------------------------------------------------------*/
3267 /*---                                             libvex_ir.h ---*/
3268 /*---------------------------------------------------------------*/