libvex_ir.h revision 663860b1408516d02ebfcb3a9999a134e6cfb223
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin                                       libvex_ir.h ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2004-2012 OpenWorks LLP
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      info@open-works.net
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02110-1301, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Neither the names of the U.S. Department of Energy nor the
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   University of California nor the names of its contributors may be
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used to endorse or promote products derived from this software
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   without prior written permission.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __LIBVEX_IR_H
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __LIBVEX_IR_H
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- High-level IR description                               ---*/
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Vex IR is an architecture-neutral intermediate representation.
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Unlike some IRs in systems similar to Vex, it is not like assembly
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   language (ie. a list of instructions).  Rather, it is more like the
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IR that might be used in a compiler.
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Code blocks
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The code is broken into small code blocks ("superblocks", type:
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'IRSB').  Each code block typically represents from 1 to perhaps 50
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   instructions.  IRSBs are single-entry, multiple-exit code blocks.
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Each IRSB contains three things:
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - a type environment, which indicates the type of each temporary
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     value present in the IRSB
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - a list of statements, which represent code
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - a jump that exits from the end the IRSB
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Because the blocks are multiple-exit, there can be additional
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conditional exit statements that cause control to leave the IRSB
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   before the final exit.  Also because of this, IRSBs can cover
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   multiple non-consecutive sequences of code (up to 3).  These are
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   recorded in the type VexGuestExtents (see libvex.h).
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Statements and expressions
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~~~~~~~~~~~~~~~~
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Statements (type 'IRStmt') represent operations with side-effects,
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   eg.  guest register writes, stores, and assignments to temporaries.
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Expressions (type 'IRExpr') represent operations without
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   side-effects, eg. arithmetic operations, loads, constants.
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Expressions can contain sub-expressions, forming expression trees,
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   eg. (3 + (4 * load(addr1)).
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Storage of guest state
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~~~~~~~~~~~~
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The "guest state" contains the guest registers of the guest machine
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (ie.  the machine that we are simulating).  It is stored by default
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in a block of memory supplied by the user of the VEX library,
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   generally referred to as the guest state (area).  To operate on
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   these registers, one must first read ("Get") them from the guest
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   state into a temporary value.  Afterwards, one can write ("Put")
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   them back into the guest state.
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Get and Put are characterised by a byte offset into the guest
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   state, a small integer which effectively gives the identity of the
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   referenced guest register, and a type, which indicates the size of
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the value to be transferred.
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The basic "Get" and "Put" operations are sufficient to model normal
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fixed registers on the guest.  Selected areas of the guest state
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   can be treated as a circular array of registers (type:
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'IRRegArray'), which can be indexed at run-time.  This is done with
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the "GetI" and "PutI" primitives.  This is necessary to describe
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rotating register files, for example the x87 FPU stack, SPARC
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   register windows, and the Itanium register files.
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Examples, and flattened vs. unflattened code
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For example, consider this x86 instruction:
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     addl %eax, %ebx
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   One Vex IR translation for this code would be this:
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     ------ IMark(0x24F275, 7, 0) ------
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t3 = GET:I32(0)             # get %eax, a 32-bit integer
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t2 = GET:I32(12)            # get %ebx, a 32-bit integer
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t1 = Add32(t3,t2)           # addl
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PUT(0) = t1                 # put %eax
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (For simplicity, this ignores the effects on the condition codes, and
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the update of the instruction pointer.)
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The "IMark" is an IR statement that doesn't represent actual code.
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Instead it indicates the address and length of the original
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   instruction.  The numbers 0 and 12 are offsets into the guest state
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for %eax and %ebx.  The full list of offsets for an architecture
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <ARCH> can be found in the type VexGuest<ARCH>State in the file
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VEX/pub/libvex_guest_<ARCH>.h.
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The five statements in this example are:
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - the IMark
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - three assignments to temporaries
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - one register write (put)
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The six expressions in this example are:
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - two register reads (gets)
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - one arithmetic (add) operation
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - three temporaries (two nested within the Add32, one in the PUT)
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The above IR is "flattened", ie. all sub-expressions are "atoms",
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   either constants or temporaries.  An equivalent, unflattened version
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   would be:
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PUT(0) = Add32(GET:I32(0), GET:I32(12))
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IR is guaranteed to be flattened at instrumentation-time.  This makes
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   instrumentation easier.  Equivalent flattened and unflattened IR
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typically results in the same generated code.
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Another example, this one showing loads and stores:
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     addl %edx,4(%eax)
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This becomes (again ignoring condition code and instruction pointer
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   updates):
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     ------ IMark(0x4000ABA, 3, 0) ------
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t3 = Add32(GET:I32(0),0x4:I32)
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t2 = LDle:I32(t3)
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t1 = GET:I32(8)
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     t0 = Add32(t2,t1)
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     STle(t3) = t0
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The "le" in "LDle" and "STle" is short for "little-endian".
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   No need for deallocations
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~~~~~~~~~~~~~~~
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Although there are allocation functions for various data structures
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in this file, there are no deallocation functions.  This is because
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Vex uses a memory allocation scheme that automatically reclaims the
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   memory used by allocated structures once translation is completed.
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This makes things easier for tools that instruments/transforms code
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   blocks.
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SSAness and typing
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ~~~~~~~~~~~~~~~~~~
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The IR is fully typed.  For every IRSB (IR block) it is possible to
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   say unambiguously whether or not it is correctly typed.
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Incorrectly typed IR has no meaning and the VEX will refuse to
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   process it.  At various points during processing VEX typechecks the
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IR and aborts if any violations are found.  This seems overkill but
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   makes it a great deal easier to build a reliable JIT.
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IR also has the SSA property.  SSA stands for Static Single
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Assignment, and what it means is that each IR temporary may be
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assigned to only once.  This idea became widely used in compiler
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   construction in the mid to late 90s.  It makes many IR-level
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   transformations/code improvements easier, simpler and faster.
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Whenever it typechecks an IR block, VEX also checks the SSA
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   property holds, and will abort if not so.  So SSAness is
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mechanically and rigidly enforced.
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Type definitions for the IR                             ---*/
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* General comments about naming schemes:
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   All publically visible functions contain the name of the primary
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   type on which they operate (IRFoo, IRBar, etc).  Hence you should
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be able to identify these functions by grepping for "IR[A-Z]".
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For some type 'IRFoo':
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - ppIRFoo is the printing method for IRFoo, printing it to the
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     output channel specified in the LibVEX_Initialise call.
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - eqIRFoo is a structural equality predicate for IRFoos.
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - deepCopyIRFoo is a deep copy constructor for IRFoos.
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     It recursively traverses the entire argument tree and
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     produces a complete new tree.  All types have a deep copy
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     constructor.
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     It creates a new top-level copy of the supplied object,
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     but does not copy any sub-objects.  Only some types have a
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     shallow copy constructor.
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Types ------------------ */
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A type indicates the size of a value, and whether it's an integer, a
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   float, or a vector (SIMD) value. */
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_INVALID=0x11000,
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I1,
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I8,
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I16,
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I32,
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I64,
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_I128,  /* 128-bit scalar */
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_F32,   /* IEEE 754 float */
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ity_F64,   /* IEEE 754 double */
230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ity_D32,   /* 32-bit Decimal floating point */
231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ity_D64,   /* 64-bit Decimal floating point */
232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ity_D128,  /* 128-bit Decimal floating point */
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Ity_F128,  /* 128-bit floating point; implementation defined */
234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ity_V128,  /* 128-bit SIMD */
235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ity_V256   /* 256-bit SIMD */
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRType;
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRType */
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRType ( IRType );
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Get the size (in bytes) of an IRType */
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int sizeofIRType ( IRType );
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Endianness ------------------ */
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IREndness is used in load IRExprs and store IRStmts. */
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iend_LE=0x12000, /* little endian */
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iend_BE          /* big endian */
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IREndness;
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Constants ------------------ */
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRConsts are used within 'Const' and 'Exit' IRExprs. */
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The various kinds of constant. */
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_U1=0x13000,
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_U8,
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_U16,
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_U32,
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_U64,
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Ico_F32,   /* 32-bit IEEE754 floating */
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Ico_F32i,  /* 32-bit unsigned int to be interpreted literally
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    as a IEEE754 single value. */
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_F64,   /* 64-bit IEEE754 floating */
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    as a IEEE754 double value. */
275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ico_V128,  /* 128-bit restricted vector constant, with 1 bit
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (repeated 8 times) for each of the 16 x 1-byte lanes */
277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ico_V256   /* 256-bit restricted vector constant, with 1 bit
278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (repeated 8 times) for each of the 32 x 1-byte lanes */
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRConstTag;
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A constant.  Stored as a tagged union.  'tag' indicates what kind of
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   constant this is.  'Ico' is the union that holds the fields.  If an
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and its value can be accessed with 'c.Ico.U32'. */
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _IRConst {
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRConstTag tag;
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      union {
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool   U1;
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar  U8;
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UShort U16;
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt   U32;
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  U64;
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Float  F32;
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UInt   F32i;
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Double F64;
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  F64i;
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UShort V128;   /* 16-bit value; see Ico_V128 comment above */
300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt   V256;   /* 32-bit value; see Ico_V256 comment above */
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Ico;
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRConst;
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRConst constructors */
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U1   ( Bool );
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U8   ( UChar );
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U16  ( UShort );
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U32  ( UInt );
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U64  ( ULong );
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRConst* IRConst_F32  ( Float );
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRConst* IRConst_F32i ( UInt );
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_F64  ( Double );
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_F64i ( ULong );
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_V128 ( UShort );
316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRConst* IRConst_V256 ( UInt );
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRConst */
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* deepCopyIRConst ( IRConst* );
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRConst */
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRConst ( IRConst* );
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Compare two IRConsts for equality */
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRConst ( IRConst*, IRConst* );
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Call targets ------------------ */
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Describes a helper function to call.  The name part is purely for
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pretty printing and not actually used.  regparms=n tells the back
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   end that the callee has been declared
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "__attribute__((regparm(n)))", although indirectly using the
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VEX_REGPARM(n) macro.  On some targets (x86) the back end will need
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to construct a non-standard sequence to call a function declared
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   like this.
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mcx_mask is a sop to Memcheck.  It indicates which args should be
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   considered 'always defined' when lazily computing definedness of
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   args[1], etc.  If a bit is set, the corresponding arg is excluded
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (hence "x" in "mcx") from definedness checking.
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    regparms;
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HChar* name;
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void*  addr;
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   mcx_mask;
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRCallee;
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create an IRCallee. */
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRCallee. */
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCallee* deepCopyIRCallee ( IRCallee* );
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRCallee. */
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRCallee ( IRCallee* );
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Guest state arrays ------------------ */
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This describes a section of the guest state that we want to
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be able to index at run time, so as to be able to describe
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   indexed or rotating register files on the guest. */
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    base;   /* guest state offset of start of indexed area */
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRType elemTy; /* type of each element in the indexed area */
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    nElems; /* number of elements in the indexed area */
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRRegArray;
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRRegArray* mkIRRegArray ( Int, IRType, Int );
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRRegArray ( IRRegArray* );
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRRegArray ( IRRegArray*, IRRegArray* );
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Temporaries ------------------ */
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This represents a temporary, eg. t1.  The IR optimiser relies on the
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fact that IRTemps are 32-bit ints.  Do not change them to be ints of
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any other size. */
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef UInt IRTemp;
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRTemp. */
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRTemp ( IRTemp );
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Primops (arity 1,2,3 and 4) --------------- */
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Primitive operations that are used in Unop, Binop, Triop and Qop
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRExprs.  Once we take into account integer, floating point and SIMD
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   operations of all the different sizes, there are quite a lot of them.
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Most instructions supported by the architectures that Vex supports
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (x86, PPC, etc) are represented.  Some more obscure ones (eg. cpuid)
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   are not;  they are instead handled with dirty helpers that emulate
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   their functionality.  Such obscure ones are thus not directly visible
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in the IR, but their effects on guest state (memory and registers)
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   are made visible via the annotations in IRDirty structures.
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* -- Do not change this ordering.  The IR generators rely on
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            (eg) Iop_Add64 == IopAdd8 + 3. -- */
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_INVALID=0x14000,
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Signless mul.  MullS/MullU is elsewhere. */
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Integer comparisons. */
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Tags for unary ops */
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Exactly like CmpEQ8/16/32/64, but carrying the additional
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         hint that these compute the success/failure of a CAS
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         operation, and hence are almost certainly applied to two
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         copies of the same value, which in turn has implications for
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Memcheck's instrumentation. */
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* -- Ordering not important after here. -- */
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Widening multiplies */
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Wierdo integer stuff */
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         zero.  You must ensure they are never given a zero argument.
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Standard integer comparisons */
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpLT32S, Iop_CmpLT64S,
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpLE32S, Iop_CmpLE64S,
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpLT32U, Iop_CmpLT64U,
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpLE32U, Iop_CmpLE64U,
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* As a sop to Valgrind-Memcheck, the following are useful. */
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /*  \x -> x | -x */
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max32U, /* unsigned max */
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* PowerPC-style 3-way integer comparisons.  Without them it is
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         difficult to simulate PPC efficiently.
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         op(x,y) | x < y  = 0x8 else
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 | x > y  = 0x4 else
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 | x == y = 0x2
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpORD32U, Iop_CmpORD64U,
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpORD32S, Iop_CmpORD64S,
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Division */
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* TODO: clarify semantics wrt rounding, negative values, whatever */
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivS32,   // ditto, signed
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivU64,   // :: I64,I64 -> I64 (simple div, no mod)
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivS64,   // ditto, signed
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_DivU64E,  // :: I64,I64 -> I64 (dividend is 64-bit arg (hi) concat with 64 0's (low))
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_DivS64E,  // ditto, signed
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_DivU32E,  // :: I32,I32 -> I32 (dividend is 32-bit arg (hi) concat with 32 0's (low))
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_DivS32E,  // ditto, signed
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivModU64to32, // :: I64,I32 -> I64
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         // of which lo half is div and hi half is mod
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivModS64to32, // ditto, signed
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivModU128to64, // :: V128,I64 -> V128
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          // of which lo half is div and hi half is mod
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_DivModS128to64, // ditto, signed
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_DivModS64to64, // :: I64,I64 -> I128
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                         // of which lo half is div and hi half is mod
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Integer conversions.  Some of these are redundant (eg
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         having a complete set reduces the typical dynamic size of IR
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         and makes the instruction selectors easier to write. */
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Widening conversions */
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  Iop_16Uto32, Iop_16Uto64,
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               Iop_32Uto64,
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  Iop_16Sto32, Iop_16Sto64,
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               Iop_32Sto64,
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Narrowing conversions */
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64to8, Iop_32to8, Iop_64to16,
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 8 <-> 16 bit conversions */
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_16to8,      // :: I16 -> I8, low half
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_16HIto8,    // :: I16 -> I8, high half
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_8HLto16,    // :: (I8,I8) -> I16
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 16 <-> 32 bit conversions */
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_32to16,     // :: I32 -> I16, low half
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_32HIto16,   // :: I32 -> I16, high half
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_16HLto32,   // :: (I16,I16) -> I32
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 32 <-> 64 bit conversions */
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64to32,     // :: I64 -> I32, low half
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64HIto32,   // :: I64 -> I32, high half
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_32HLto64,   // :: (I32,I32) -> I64
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 64 <-> 128 bit conversions */
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_128to64,    // :: I128 -> I64, low half
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_128HIto64,  // :: I128 -> I64, high half
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64HLto128,  // :: (I64,I64) -> I128
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 1-bit stuff */
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------ Floating point.  We try to be IEEE754 compliant. ------ */
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- Simple stuff as mandated by 754. --- */
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Binary operations, with rounding. */
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Variants of the above which produce a 64-bit result but which
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         round their result to a IEEE float range first. */
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unary operations, without rounding. */
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F64 -> F64 */
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_NegF64, Iop_AbsF64,
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F32 -> F32 */
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_NegF32, Iop_AbsF32,
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unary operations, with rounding. */
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 -> F64 */
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SqrtF64, Iop_SqrtF64r32,
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F32 -> F32 */
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SqrtF32,
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            0x45 Unordered
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            0x01 LT
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            0x00 GT
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            0x40 EQ
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         This just happens to be the Intel encoding.  The values
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         are recorded in the type IRCmpF64Result.
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F64 x F64 -> IRCmpF64Result(I32) */
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpF64,
579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_CmpF32,
580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_CmpF128,
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- Int to/from FP conversions. --- */
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* For the most part, these take a first argument :: Ity_I32 (as
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRRoundingMode) which is an indication of the rounding mode
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to use, as per the following encoding ("the standard
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         encoding"):
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            00b  to nearest (the default)
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            01b  to -infinity
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            10b  to +infinity
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            11b  to zero
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         This just happens to be the Intel encoding.  For reference only,
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the PPC encoding is:
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            00b  to nearest (the default)
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            01b  to zero
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            10b  to +infinity
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            11b  to -infinity
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Any PPC -> IR front end will have to translate these PPC
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         encodings, as encoded in the guest state, to the standard
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         encodings, to pass to the primops.
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         For reference only, the ARM VFP encoding is:
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            00b  to nearest
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            01b  to +infinity
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            10b  to -infinity
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            11b  to zero
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Again, this will have to be converted to the standard encoding
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to pass to primops.
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         If one of these conversions gets an out-of-range condition,
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         or a NaN, as an argument, the result is host-defined.  On x86
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the "integer indefinite" value 0x80..00 is produced.  On PPC
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         it is either 0x80..00 or 0x7F..FF depending on the sign of
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the argument.
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         On ARMvfp, when converting to a signed integer result, the
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         overflow result is 0x80..00 for negative args and 0x7F..FF
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for positive args.  For unsigned integer results it is
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         0x00..00 and 0xFF..FF respectively.
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Rounding is required whenever the destination type cannot
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         represent exactly all values of the source type.
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I16StoF64, /*                       signed I16 -> F64 */
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I32StoF64, /*                       signed I32 -> F64 */
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I32UtoF64, /*                       unsigned I32 -> F64 */
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F32toI16S, /* IRRoundingMode(I32) x F32 -> signed I16 */
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I16StoF32, /*                       signed I16 -> F32 */
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Conversion between floating point formats */
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F32toF64,  /*                       F32 -> F64 */
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Reinterpretation.  Take an F64 and produce an I64 with
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the same bit pattern, or vice versa. */
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Support for 128-bit floating point */
656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128LOtoF64,/* F128 -> low  half of F128 into a F64 register */
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* :: F128 -> F128 */
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_NegF128, Iop_AbsF128,
665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* :: IRRoundingMode(I32) x F128 -> F128 */
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_SqrtF128,
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I32StoF128, /*                signed I32  -> F128 */
670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_I64StoF128, /*                signed I64  -> F128 */
671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F32toF128,  /*                       F32  -> F128 */
672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F64toF128,  /*                       F64  -> F128 */
673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32  */
675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64  */
676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128toF64,  /* IRRoundingMode(I32) x F128 -> F64         */
677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_F128toF32,  /* IRRoundingMode(I32) x F128 -> F32         */
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- guest x86/amd64 specifics, not mandated by 754. --- */
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Binary ops, with rounding. */
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note that on x86 guest, PRem1{C3210} has the same behaviour
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         as the IEEE mandated RemF64, except it is limited in the
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         range of its operand.  Hence the partialness. */
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unary ops, with rounding. */
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 -> F64 */
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SinF64,    /* FSIN */
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CosF64,    /* FCOS */
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_TanF64,    /* FTAN */
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_2xm1F64,   /* (2^arg - 1.0) */
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toInt, /* F64 value to nearest integral value (still
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            as F64) */
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF32toInt, /* F32 value to nearest integral value (still
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            as F32) */
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* --- guest s390 specifics, not mandated by 754. --- */
707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Fused multiply-add/sub */
709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            (computes op3 * op2 +/- op1 */
711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_MAddF32, Iop_MSubF32,
712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- guest ppc32/64 specifics, not mandated by 754. --- */
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Ternary operations, with rounding. */
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fused multiply-add/sub, with 112-bit intermediate
717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         precision for ppc.
718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Also used to implement fused multiply-add/sub for s390. */
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            (computes arg2 * arg3 +/- arg4) */
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MAddF64, Iop_MSubF64,
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Variants of the above which produce a 64-bit result but which
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         round their result to a IEEE float range first. */
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MAddF64r32, Iop_MSubF64r32,
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F64 -> F64 */
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Est5FRSqrt,    /* reciprocal square root estimate, 5 good bits */
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toF64_NEAREST, /* frin */
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toF64_NegINF,  /* frim */
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toF64_PosINF,  /* frip */
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toF64_ZERO,    /* friz */
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F64 -> F32 */
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: IRRoundingMode(I32) x F64 -> F64 */
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* NB: pretty much the same as Iop_F64toF32, except no change
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of type. */
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* :: F64 -> I32 */
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord)
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       from FP result */
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------------------ 32-bit SIMD Integer ------------------ */
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_QAdd32S,
751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_QSub32S,
752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 16x2 add/sub, also signed/unsigned saturating variants */
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add16x2, Iop_Sub16x2,
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd16Sx2, Iop_QAdd16Ux2,
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub16Sx2, Iop_QSub16Ux2,
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 16x2 signed/unsigned halving add/sub.  For each lane, these
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         compute bits 16:1 of (eg) sx(argL) + sx(argR),
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         or zx(argL) - zx(argR) etc. */
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_HAdd16Ux2, Iop_HAdd16Sx2,
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_HSub16Ux2, Iop_HSub16Sx2,
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 8x4 add/sub, also signed/unsigned saturating variants */
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add8x4, Iop_Sub8x4,
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd8Sx4, Iop_QAdd8Ux4,
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub8Sx4, Iop_QSub8Ux4,
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 8x4 signed/unsigned halving add/sub.  For each lane, these
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         compute bits 8:1 of (eg) sx(argL) + sx(argR),
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         or zx(argL) - zx(argR) etc. */
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_HAdd8Ux4, Iop_HAdd8Sx4,
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_HSub8Ux4, Iop_HSub8Sx4,
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 8x4 sum of absolute unsigned differences. */
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sad8Ux4,
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MISC (vector integer cmp != 0) */
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------------------ 64-bit SIMD FP ------------------------ */
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Convertion to/from int */
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I32UtoFx2,  Iop_I32StoFx2,    /* I32x4 -> F32x4 */
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_FtoI32Ux2_RZ,  Iop_FtoI32Sx2_RZ,    /* F32x4 -> I32x4 */
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fixed32 format is floating-point number with fixed number of fraction
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bits. The number of fraction bits is passed as a second argument of
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         type I8. */
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Binary operations */
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max32Fx2,      Iop_Min32Fx2,
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Pairwise Min and Max. See integer pairwise operations for more
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         details. */
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMax32Fx2,    Iop_PwMin32Fx2,
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: For the following compares, the arm front-end assumes a
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nan in a lane of either argument returns zero for that lane. */
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Estimate finds an approximate reciprocal of each
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      element in the operand vector, and places the results in the destination
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vector.  */
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip32Fx2,
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Note, that if one of the arguments is zero and another one is infinity
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of arbitrary sign the result of the operation is 2.0. */
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recps32Fx2,
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         square root of each element in the operand vector. */
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Rsqrte32Fx2,
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Note, that of one of the arguments is zero and another one is infiinty
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of arbitrary sign the result of the operation is 1.5. */
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Rsqrts32Fx2,
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unary */
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Neg32Fx2, Iop_Abs32Fx2,
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------------------ 64-bit SIMD Integer. ------------------ */
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MISC (vector integer cmp != 0) */
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ADDITION (normal / unsigned sat / signed sat) */
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* PAIRWISE operations */
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAdd8x8,  Iop_PwAdd16x4,  Iop_PwAdd32x2,
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Longening variant is unary. The resulting vector contains two times
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         less elements than operand, but they are two times wider.
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Example:
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               where a+b and c+d are unsigned 32-bit values. */
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* SUBTRACTION (normal / unsigned sat / signed sat) */
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ABSOLUTE VALUE */
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mul32Fx2,
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MulHi16Ux4,
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MulHi16Sx4,
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Plynomial multiplication treats it's arguments as coefficients of
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         polynoms over {0, 1}. */
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PolynomialMul8x8,
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Saturating Doubling Multiply Returning High Half and
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vector Saturating Rounding Doubling Multiply Returning High Half */
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These IROp's multiply corresponding elements in two vectors, double
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the results, and place the most significant half of the final results
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         in the destination vector. The results are truncated or rounded. If
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         any of the results overflow, they are saturated. */
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Avg8Ux8,
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Avg16Ux4,
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MIN/MAX */
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* COMPARISON */
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* COUNT ones / leading zeroes / leading sign bits (not including topmost
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bit) */
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Cnt8x8,
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2,
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2,
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x VECTOR SHIFT / ROTATE */
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x VECTOR SATURATING SHIFT */
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x INTEGER SATURATING SHIFT */
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1,
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1,
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1,
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* NARROWING (binary)
916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         -- narrow 2xI64 into 1xI64, hi half from left arg */
917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* For saturated narrowing, I believe there are 4 variants of
918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         the basic arithmetic operation, depending on the signedness
919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         of argument and result.  Here are examples that exemplify
920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         what I mean:
921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         QNarrow16Uto8U ( UShort x )  if (x >u 255) x = 255;
923b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      return x[7:0];
924b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
925b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         QNarrow16Sto8S ( Short x )   if (x <s -128) x = -128;
926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      if (x >s  127) x = 127;
927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      return x[7:0];
928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         QNarrow16Uto8S ( UShort x )  if (x >u 127) x = 127;
930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      return x[7:0];
931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         QNarrow16Sto8U ( Short x )   if (x <s 0)   x = 0;
933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      if (x >s 255) x = 255;
934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                      return x[7:0];
935b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      */
936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowBin16Sto8Ux8,
937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_NarrowBin16to8x8,    Iop_NarrowBin32to16x4,
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* INTERLEAVING */
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Interleave lanes from low or high halves of
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         operands.  Most-significant result lane is from the left
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         arg. */
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Interleave odd/even lanes of operands.  Most-significant result lane
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is from the left arg.  Note that Interleave{Odd,Even}Lanes32x2 are
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         identical to Interleave{HI,LO}32x2 and so are omitted.*/
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* CONCATENATION -- build a new value by concatenating either
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the even or odd lanes of both operands.  Note that
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         and so are omitted. */
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* GET / SET elements of VECTOR
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         GET is binop (I64, I8) -> I<elem_size>
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         SET is triop (I64, I8, I<elem_size>) -> I64 */
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: the arm back-end handles only constant second argument */
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* DUPLICATING -- copy value to all lanes */
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Dup8x8,   Iop_Dup16x4,   Iop_Dup32x2,
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         result.
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         It is a triop: (I64, I64, I8) -> I64 */
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: the arm back-end handles only constant third argumnet. */
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Extract64,
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* REVERSE the order of elements in each Half-words, Words,
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Double-words */
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Examples:
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse16_8x8,
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse32_8x8, Iop_Reverse32_16x4,
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2,
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* PERMUTING -- copy src bytes to dst,
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         as indexed by control vector bytes:
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            for i in 0 .. 7 . result[i] = argL[ argR[i] ]
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         argR[i] values may only be in the range 0 .. 7, else behaviour
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is undefined. */
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Perm8x8,
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         See floating-point equiwalents for details. */
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip32x2, Iop_Rsqrte32x2,
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ------------------ Decimal Floating Point ------------------ */
999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ARITHMETIC INSTRUCTIONS   64-bit
1001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 ----------------------------------
1002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 IRRoundingModeDFP(I32) X D64 X D64 -> D64
1003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      */
1004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ARITHMETIC INSTRUCTIONS  128-bit
1007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 ----------------------------------
1008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 IRRoundingModeDFP(I32) X D128 X D128 -> D128
1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      */
1010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* SHIFT SIGNIFICAND INSTRUCTIONS
1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    The DFP significand is shifted by the number of digits specified
1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    by the U8 operand.  Digits shifted out of the leftmost digit are
1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    lost. Zeros are supplied to the vacated positions on the right.
1016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    The sign of the result is the same as the sign of the original
1017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    operand.
1018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *
1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * D64 x U8  -> D64    left shift and right shift respectively */
1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ShlD64, Iop_ShrD64,
1021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* D128 x U8  -> D128  left shift and right shift respectively */
1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ShlD128, Iop_ShrD128,
1024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* FORMAT CONVERSION INSTRUCTIONS
1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *   D32 -> D64
1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D32toD64,
1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   D64 -> D128 */
1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D64toD128,
1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   I64S -> D128 */
1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_I64StoD128,
1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   IRRoundingModeDFP(I32) x D64 -> D32 */
1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D64toD32,
1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   IRRoundingModeDFP(I32) x D128 -> D64 */
1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D128toD64,
1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   IRRoundingModeDFP(I32) x I64 -> D64 */
1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_I64StoD64,
1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   IRRoundingModeDFP(I32) x D64 -> I64 */
1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D64toI64S,
1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*   IRRoundingModeDFP(I32) x D128 -> I64 */
1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D128toI64S,
1051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ROUNDING INSTRUCTIONS
1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * IRRoundingMode(I32) x D64 -> D64
1054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * The D64 operand, if a finite number, is rounded to an integer value.
1055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_RoundD64toInt,
1057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* IRRoundingMode(I32) x D128 -> D128 */
1059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_RoundD128toInt,
1060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* COMPARE INSTRUCTIONS
1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * D64 x D64 -> IRCmpD64Result(I32) */
1063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_CmpD64,
1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* D128 x D128 -> IRCmpD64Result(I32) */
1066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_CmpD128,
1067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* QUANTIZE AND ROUND INSTRUCTIONS
1069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * The source operand is converted and rounded to the form with the
1070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * immediate exponent specified by the rounding and exponent parameter.
1071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *
1072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * The second operand is converted and rounded to the form
1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * of the first operand's exponent and the rounded based on the specified
1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * rounding mode parameter.
1075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *
1076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * IRRoundingModeDFP(I32) x D64 x D64-> D64 */
1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_QuantizeD64,
1078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* IRRoundingModeDFP(I32) x D128 x D128 -> D128 */
1080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_QuantizeD128,
1081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* IRRoundingModeDFP(I32) x I8 x D64 -> D64
1083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    The Decimal Floating point operand is rounded to the requested
1084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    significance given by the I8 operand as specified by the rounding
1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    mode.
1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_SignificanceRoundD64,
1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* IRRoundingModeDFP(I32) x I8 x D128 -> D128 */
1090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_SignificanceRoundD128,
1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* EXTRACT AND INSERT INSTRUCTIONS
1093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       * D64 -> I64
1094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    The exponent of the D32 or D64 operand is extracted.  The
1095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    extracted exponent is converted to a 64-bit signed binary integer.
1096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ExtractExpD64,
1098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* D128 -> I64 */
1100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ExtractExpD128,
1101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* I64 x I64  -> D64
1103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    The exponent is specified by the first I64 operand the signed
1104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    significand is given by the second I64 value.  The result is a D64
1105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    value consisting of the specified significand and exponent whose
1106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *    sign is that of the specified significand.
1107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_InsertExpD64,
1109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* I64 x I128 -> D128 */
1111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_InsertExpD128,
1112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Support for 128-bit DFP type */
1114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /*  I64 -> I64
1117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *     Convert 50-bit densely packed BCD string to 60 bit BCD string
1118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_DPBtoBCD,
1120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* I64 -> I64
1122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       *     Convert 60 bit BCD string to 50-bit densely packed BCD string
1123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       */
1124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_BCDtoDPB,
1125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Conversion I64 -> D64 */
1127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ReinterpI64asD64,
1128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Conversion D64 -> I64 */
1130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_ReinterpD64asI64,
1131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------------------ 128-bit SIMD FP. ------------------ */
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- 32x4 vector FP --- */
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* binary */
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max32Fx4, Iop_Min32Fx4,
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add32Fx2, Iop_Sub32Fx2,
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: For the following compares, the ppc and arm front-ends assume a
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nan in a lane of either argument returns zero for that lane. */
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Absolute */
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Abs32Fx4,
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Pairwise Max and Min. See integer pairwise operations for details. */
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* unary */
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Neg32Fx4,
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      element in the operand vector, and places the results in the destination
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vector.  */
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip32Fx4,
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Note, that if one of the arguments is zero and another one is infinity
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of arbitrary sign the result of the operation is 2.0. */
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recps32Fx4,
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         square root of each element in the operand vector. */
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Rsqrte32Fx4,
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Note, that of one of the arguments is zero and another one is infiinty
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of arbitrary sign the result of the operation is 1.5. */
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Rsqrts32Fx4,
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- Int to/from FP conversion --- */
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unlike the standard fp conversions, these irops take no
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         indicate the mode: {-inf, +inf, nearest, zero} respectively. */
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_I32UtoFx4,  Iop_I32StoFx4,       /* I32x4 -> F32x4       */
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_FtoI32Ux4_RZ,  Iop_FtoI32Sx4_RZ,    /* F32x4 -> I32x4       */
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ,   /* F32x4 -> I32x4 (with saturation) */
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fixed32 format is floating-point number with fixed number of fraction
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bits. The number of fraction bits is passed as a second argument of
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         type I8. */
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- Single to/from half conversion --- */
1191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_F32toF16x4, Iop_F16toF32x4,         /* F32x4 <-> F16x4      */
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- 32x4 lowest-lane-only scalar FP --- */
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* In binary cases, upper 3/4 is copied from first operand.  In
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         unary cases, upper 3/4 is copied from the operand. */
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* binary */
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max32F0x4, Iop_Min32F0x4,
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* unary */
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- 64x2 vector FP --- */
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* binary */
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max64Fx2, Iop_Min64Fx2,
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* unary */
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- 64x2 lowest-lane-only scalar FP --- */
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* In binary cases, upper half is copied from first operand.  In
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         unary cases, upper half is copied from the operand. */
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* binary */
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max64F0x2, Iop_Min64F0x2,
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* unary */
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- pack / unpack --- */
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 64 <-> 128 bit vector */
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_V128to64,     // :: V128 -> I64, low half
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_V128HIto64,   // :: V128 -> I64, high half
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64HLtoV128,   // :: (I64,I64) -> V128
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_64UtoV128,
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SetV128lo64,
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 32 <-> 128 bit vector */
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_32UtoV128,
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_V128to32,     // :: V128 -> I32, lowest lane
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SetV128lo32,  // :: (V128,I32) -> V128
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ------------------ 128-bit SIMD Integer. ------------------ */
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* BITWISE OPS */
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_NotV128,
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_AndV128, Iop_OrV128, Iop_XorV128,
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR SHIFT (shift amt :: Ity_I8) */
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ShlV128, Iop_ShrV128,
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MISC (vector integer cmp != 0) */
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ADDITION (normal / unsigned sat / signed sat) */
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,   Iop_Add64x2,
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* SUBTRACTION (normal / unsigned sat / signed sat) */
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,   Iop_Sub64x2,
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MULTIPLICATION (normal / high half of signed/unsigned) */
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mul8x16,  Iop_Mul16x8,    Iop_Mul32x4,
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    Iop_MulHi16Sx8, Iop_MulHi32Sx4,
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MullEven8Ux16, Iop_MullEven16Ux8,
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_MullEven8Sx16, Iop_MullEven16Sx8,
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* FIXME: document these */
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mull8Ux8, Iop_Mull8Sx8,
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mull16Ux4, Iop_Mull16Sx4,
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Mull32Ux2, Iop_Mull32Sx2,
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Saturating Doubling Multiply Returning High Half and
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vector Saturating Rounding Doubling Multiply Returning High Half */
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These IROp's multiply corresponding elements in two vectors, double
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the results, and place the most significant half of the final results
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         in the destination vector. The results are truncated or rounded. If
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         any of the results overflow, they are saturated. */
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4,
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4,
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Doubling saturating multiplication (long) (I64, I64) -> V128 */
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2,
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Plynomial multiplication treats it's arguments as coefficients of
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         polynoms over {0, 1}. */
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PolynomialMull8x8, /*   (I64, I64) -> V128 */
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* PAIRWISE operations */
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAdd32Fx2,
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Longening variant is unary. The resulting vector contains two times
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         less elements than operand, but they are two times wider.
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Example:
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               where a+b and c+d are unsigned 32-bit values. */
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ABSOLUTE VALUE */
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4,
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* MIN/MAX */
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* COMPARISON */
1320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,  Iop_CmpEQ64x2,
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bit) */
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Cnt8x16,
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4,
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4,
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x VECTOR SHIFT / ROTATE */
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x VECTOR SATURATING SHIFT */
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* VECTOR x INTEGER SATURATING SHIFT */
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2,
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2,
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2,
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* NARROWING (binary)
1351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         -- narrow 2xV128 into 1xV128, hi half from left arg */
1352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* See comments above w.r.t. U vs S issues in saturated narrowing. */
1353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
1357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* NARROWING (unary) -- narrow V128 into I64 */
1359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Saturating narrowing from signed source to signed/unsigned destination */
1361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Saturating narrowing from unsigned source to unsigned destination */
1364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* WIDENING -- sign or zero extend each element of the argument
1367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vector to the twice original size.  The resulting vector consists of
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the same number of elements but each element and the vector itself
1369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         are twice as wide.
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         All operations are I64->V128.
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Example
1372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Iop_Widen32Sto64x2( [a, b] ) = [c, d]
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* INTERLEAVING */
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Interleave lanes from low or high halves of
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         operands.  Most-significant result lane is from the left
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         arg. */
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Interleave odd/even lanes of operands.  Most-significant result lane
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is from the left arg. */
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* CONCATENATION -- build a new value by concatenating either
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the even or odd lanes of both operands. */
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* GET elements of VECTOR
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         GET is binop (V128, I8) -> I<elem_size> */
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: the arm back-end handles only constant second argument. */
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* DUPLICATING -- copy value to all lanes */
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Dup8x16,   Iop_Dup16x8,   Iop_Dup32x4,
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         result.
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         It is a triop: (V128, V128, I8) -> V128 */
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note: the ARM back end handles only constant arg3 in this operation. */
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_ExtractV128,
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* REVERSE the order of elements in each Half-words, Words,
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Double-words */
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Examples:
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse16_8x16,
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse32_8x16, Iop_Reverse32_16x8,
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4,
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* PERMUTING -- copy src bytes to dst,
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         as indexed by control vector bytes:
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         argR[i] values may only be in the range 0 .. 15, else behaviour
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is undefined. */
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iop_Perm8x16,
1426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         See floating-point equiwalents for details. */
1430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Recip32x4, Iop_Rsqrte32x4,
1431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ------------------ 256-bit SIMD Integer. ------------------ */
1433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Pack/unpack */
1435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256to64_0,  // V256 -> I64, extract least significant lane
1436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256to64_1,
1437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256to64_2,
1438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256to64_3,  // V256 -> I64, extract most significant lane
1439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_64x4toV256,  // (I64,I64,I64,I64)->V256
1441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       // first arg is most significant lane
1442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256toV128_0, // V256 -> V128, less significant lane
1444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V256toV128_1, // V256 -> V128, more significant lane
1445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_AndV256,
1448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_OrV256,
1449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_XorV256,
1450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_NotV256,
1451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* MISC (vector integer cmp != 0) */
1453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* ------------------ 256-bit SIMD FP. ------------------ */
1456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Add64Fx4,
1457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Sub64Fx4,
1458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Mul64Fx4,
1459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Div64Fx4,
1460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Add32Fx8,
1461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Sub32Fx8,
1462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Mul32Fx8,
1463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Div32Fx8,
1464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Sqrt32Fx8,
1466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Sqrt64Fx4,
1467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_RSqrt32Fx8,
1468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Recip32Fx8,
1469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Max32Fx8, Iop_Min32Fx8,
1471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Iop_Max64Fx4, Iop_Min64Fx4
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IROp;
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an op. */
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIROp ( IROp );
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Encoding of IEEE754-specified rounding modes.  This is the same as
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the encoding used by Intel IA32 to indicate x87 rounding mode.
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Note, various front and back ends rely on the actual numerical
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   values of these, so do not change them. */
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Irrm_NEAREST = 0,
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Irrm_NegINF  = 1,
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Irrm_PosINF  = 2,
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Irrm_ZERO    = 3
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRRoundingMode;
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DFP encoding of IEEE754 2008 specified rounding modes extends the two bit
1493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * binary floating point rounding mode (IRRoundingMode) to three bits.  The
1494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * DFP rounding modes are a super set of the binary rounding modes.  The
1495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * encoding was chosen such that the mapping of the least significant two bits
1496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * of the IR to POWER encodings is same.  The upper IR encoding bit is just
1497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * a logical OR of the upper rounding mode bit from the POWER encoding.
1498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */
1499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef
1500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   enum {
1501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_NEAREST              = 0,  // Round to nearest, ties to even
1502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_NegINF               = 1,  // Round to negative infinity
1503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_PosINF               = 2,  // Round to posative infinity
1504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_ZERO                 = 3,  // Round toward zero
1505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_NEAREST_TIE_AWAY_0   = 4,  // Round to nearest, ties away from 0
1506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_PREPARE_SHORTER      = 5,  // Round to prepare for storter
1507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                          // precision
1508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_AWAY_FROM_ZERO       = 6,  // Round to away from 0
1509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Irrm_DFP_NEAREST_TIE_TOWARD_0 = 7   // Round to nearest, ties towards 0
1510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRRoundingModeDFP;
1512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Floating point comparison result values, as created by Iop_CmpF64.
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This is also derived from what IA32 does. */
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ircr_UN = 0x45,
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ircr_LT = 0x01,
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ircr_GT = 0x00,
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ircr_EQ = 0x40
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRCmpF64Result;
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef IRCmpF64Result IRCmpF32Result;
1525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef IRCmpF64Result IRCmpF128Result;
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Expressions ------------------ */
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct _IRQop   IRQop;   /* forward declaration */
1530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct _IRTriop IRTriop; /* forward declaration */
1531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The different kinds of expressions.  Their meaning is explained below
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in the comments for IRExpr. */
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Binder=0x15000,
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Get,
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_GetI,
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_RdTmp,
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Qop,
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Triop,
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Binop,
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Unop,
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Load,
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Const,
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_Mux0X,
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Iex_CCall
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRExprTag;
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* An expression.  Stored as a tagged union.  'tag' indicates what kind
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of expression this is.  'Iex' is the union that holds the fields.  If
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   expression, and the fields can be accessed with
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'e.Iex.Load.<fieldname>'.
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For each kind of expression, we show what it looks like when
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pretty-printed with ppIRExpr().
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _IRExpr
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRExpr;
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _IRExpr {
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRExprTag tag;
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   union {
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Used only in pattern matching within Vex.  Should not be seen
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         outside of Vex. */
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int binder;
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Binder;
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a guest register, at a fixed offset in the guest state.
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int    offset;    /* Offset into the guest state */
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRType ty;        /* Type of the value being read */
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Get;
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a guest register at a non-fixed offset in the guest
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         state.  This allows circular indexing into parts of the guest
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         state, which is essential for modelling situations where the
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         identity of guest registers is not known until run time.  One
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         example is the x87 FP register stack.
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         The part of the guest state to be treated as a circular array
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is described in the IRRegArray 'descr' field.  It holds the
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         offset of the first element in the array, the type of each
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         element, and the number of elements.
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         The array index is indicated rather indirectly, in a way
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         which makes optimisation easy: as the sum of variable part
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (the 'ix' field) and a constant offset (the 'bias' field).
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Since the indexing is circular, the actual array index to use
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is computed as (ix + bias) % num-of-elems-in-the-array.
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Here's an example.  The description
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            (96:8xF64)[t39,-7]
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         describes an array of 8 F64-typed values, the
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         guest-state-offset of the first being 96.  This array is
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         being indexed at (t39 - 7) % 8.
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         It is important to get the array size/type exactly correct
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         since IR optimisation looks closely at such info in order to
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         establish aliasing/non-aliasing between seperate GetI and
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PutI events, which is used to establish when they can be
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         reordered, etc.  Putting incorrect info in will lead to
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         obscure IR optimisation bugs.
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRExpr output: GETI<descr>[<ix>,<bias]
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         eg. GETI(128:8xI8)[t1,0]
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRRegArray* descr; /* Part of guest state treated as circular */
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr*     ix;    /* Variable part of index into array */
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int         bias;  /* Constant offset part of index into array */
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } GetI;
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The value held by a temporary.
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: t<tmp>, eg. t1
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRTemp tmp;       /* The temporary number */
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } RdTmp;
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A quaternary operation.
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      eg. MAddF64r32(t1, t2, t3, t4)
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        IRQop* details;
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Qop;
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A ternary operation.
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      eg. MulF64(1, 2.0, 3.0)
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        IRTriop* details;
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Triop;
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A binary operation.
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IROp op;          /* op-code   */
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* arg1;     /* operand 1 */
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* arg2;     /* operand 2 */
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Binop;
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A unary operation.
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IROp    op;       /* op-code */
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* arg;      /* operand */
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Unop;
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A load from memory -- a normal load, not a load-linked.
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Load-Linkeds (and Store-Conditionals) are instead represented
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         by IRStmt.LLSC since Load-Linkeds have side effects and so
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         are not semantically valid IRExpr's.
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IREndness end;    /* Endian-ness of the load */
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRType    ty;     /* Type of the loaded value */
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr*   addr;   /* Address being loaded from */
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Load;
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A constant-valued expression.
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <con>, eg. 0x4:I32
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRConst* con;     /* The constant itself */
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Const;
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A call to a pure (no side-effects) helper C function.
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         With the 'cee' field, 'name' is the function's name.  It is
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         only used for pretty-printing purposes.  The address to call
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (host address, of course) is stored in the 'addr' field
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         inside 'cee'.
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         The 'args' field is a NULL-terminated array of arguments.
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         The stated return IRType, and the implied argument types,
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         must match that of the function being called well enough so
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         that the back end can actually generate correct code for the
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         call.
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         The called function **must** satisfy the following:
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         * no side effects -- must be a pure function, the result of
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           which depends only on the passed parameters.
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         * it may not look at, nor modify, any of the guest state
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           since that would hide guest state transitions from
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           instrumenters
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         * it may not access guest memory, since that would hide
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           guest memory transactions from the instrumenters
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         * it must not assume that arguments are being evaluated in a
1709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng           particular order. The oder of evaluation is unspecified.
1710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         This is restrictive, but makes the semantics clean, and does
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         not interfere with IR optimisation.
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         If you want to call a helper which can mess with guest state
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         and/or memory, instead use Ist_Dirty.  This is a lot more
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         flexible, but you have to give a bunch of details about what
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the helper does (and you better be telling the truth,
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         otherwise any derived instrumentation will be wrong).  Also
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Ist_Dirty inhibits various IR optimisations and so can cause
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         quite poor code to be generated.  Try to avoid it.
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: <cee>(<args>):<retty>
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      eg. foo{0x80489304}(t1, t2):I32
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRCallee* cee;    /* Function to call. */
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRType    retty;  /* Type of return value. */
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr**  args;   /* Vector of argument expressions. */
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }  CCall;
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A ternary if-then-else operator.  It returns expr0 if cond is
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         zero, exprX otherwise.  Note that it is STRICT, ie. both
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         expr0 and exprX are evaluated in all cases.
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         eg. Mux0X(t6,t7,t8)
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* cond;     /* Condition */
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* expr0;    /* True expression */
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* exprX;    /* False expression */
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Mux0X;
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Iex;
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------ A ternary expression ---------------------- */
1747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _IRTriop {
1748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IROp op;          /* op-code   */
1749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg1;     /* operand 1 */
1750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg2;     /* operand 2 */
1751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg3;     /* operand 3 */
1752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
1753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------ A quarternary expression ------------------ */
1755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _IRQop {
1756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IROp op;          /* op-code   */
1757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg1;     /* operand 1 */
1758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg2;     /* operand 2 */
1759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg3;     /* operand 3 */
1760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IRExpr* arg4;     /* operand 4 */
1761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
1762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Expression constructors. */
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Binder ( Int binder );
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Get    ( Int off, IRType ty );
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2,
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        IRExpr* arg3, IRExpr* arg4 );
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1,
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        IRExpr* arg2, IRExpr* arg3 );
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Const  ( IRConst* con );
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRExpr. */
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* deepCopyIRExpr ( IRExpr* );
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRExpr. */
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRExpr ( IRExpr* );
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* NULL-terminated IRExpr vector constructors, suitable for
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   use as arg lists in clean/dirty helper calls. */
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_0 ( void );
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_1 ( IRExpr* );
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                IRExpr* );
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                IRExpr*, IRExpr* );
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                IRExpr*, IRExpr*, IRExpr* );
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                IRExpr*, IRExpr*, IRExpr*, IRExpr*);
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRExpr copiers:
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - shallowCopy: shallow-copy (ie. create a new vector that shares the
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     elements with the original).
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - deepCopy: deep-copy (ie. create a completely new vector). */
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** deepCopyIRExprVec ( IRExpr** );
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a constant expression from the given host word taking into
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   account (of course) the host word size. */
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* mkIRExpr_HWord ( HWord );
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convenience function for constructing clean helper calls. */
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRExpr* mkIRExprCCall ( IRType retty,
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Int regparms, HChar* name, void* addr,
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        IRExpr** args );
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Iex_Const). */
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool isIRAtom ( IRExpr* e ) {
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Are these two IR atoms identical?  Causes an assertion
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failure if they are passed non-atoms. */
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRAtom ( IRExpr*, IRExpr* );
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Jump kinds ------------------ */
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This describes hints which can be passed to the dispatcher at guest
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   control-flow transfer points.
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest_TISTART and guest_TILEN, which specify the start and length
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of the region to be invalidated.  These are both the size of a
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest word.  It is the responsibility of the relevant toIR.c to
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ensure that these are filled in with suitable values before issuing
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a jump of kind Ijk_TInval.
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pseudo-register guest_EMWARN, which is 32-bits regardless of the
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   host or guest word size.  That register should be made to hold an
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   EmWarn_* value to indicate the reason for the exit.
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cannot continue) and so the jump destination can be anything.
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Re Ijk_Sys_ (syscall jumps): the guest state must have a
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   word.  Front ends should set this to be the IP at the most recently
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   executed kernel-entering (system call) instruction.  This makes it
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   very much easier (viz, actually possible at all) to back up the
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest to restart a syscall that has been interrupted by a signal.
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   enum {
1859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ijk_INVALID=0x16000,
1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ijk_Boring,         /* not interesting; just goto next */
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Call,           /* guest is doing a call */
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Ret,            /* guest is doing a return */
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_ClientReq,      /* do guest client req before continuing */
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Yield,          /* client is yielding to thread scheduler */
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_EmWarn,         /* report emulation warning before continuing */
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_NoDecode,       /* next instruction cannot be decoded */
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_MapFail,        /* Vex-provided address translation failed */
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_TInval,         /* Invalidate translations before continuing. */
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_NoRedir,        /* Jump to un-redirected guest addr */
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_SigBUS,         /* current instruction synths SIGBUS */
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Unfortunately, various guest-dependent syscall kinds.  They
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 all mean: do a syscall before continuing. */
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Sys_syscall,    /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
1881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             invalid at the point this happens. */
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRJumpKind;
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRJumpKind ( IRJumpKind );
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Dirty helper calls ------------------ */
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A dirty call is a flexible mechanism for calling (possibly
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conditionally) a helper function or procedure.  The helper function
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   may read, write or modify client memory, and may read, write or
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify client state.  It can take arguments and optionally return a
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   value.  It may return different results and/or do different things
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   when called repeatedly with the same arguments, by means of storing
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   private state.
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If a value is returned, it is assigned to the nominated return
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   temporary.
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Dirty calls are statements rather than expressions for obvious
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   reasons.  If a dirty call is marked as writing guest state, any
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   values derived from the written parts of the guest state are
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   invalid.  Similarly, if the dirty call is stated as writing
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   memory, any loaded values are invalidated by it.
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In order that instrumentation is possible, the call must state, and
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   state correctly:
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   * whether it reads, writes or modifies memory, and if so where
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     (only one chunk can be stated)
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   * whether it reads, writes or modifies guest state, and if so which
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     pieces (several pieces may be stated, and currently their extents
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     must be known at translation-time).
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Normally, code is generated to pass just the args to the helper.
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   However, if .needsBBP is set, then an extra first argument is
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   passed, which is the baseblock pointer, so that the callee can
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   access the guest state.  It is invalid for .nFxState to be zero
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   but .needsBBP to be True, since .nFxState==0 is a claim that the
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   call does not access guest state.
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
1926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   arguments are evaluated REGARDLESS of the guard value.  The order of
1927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   argument evaluation is unspecified. The guard expression is evaluated
1928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   AFTER the arguments have been evaluated.
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Effects on resources (eg. registers, memory locations) */
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
1936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Ifx_None = 0x1700,    /* no effect */
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ifx_Read,             /* reads the resource */
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ifx_Write,            /* writes the resource */
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ifx_Modify,           /* modifies the resource */
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IREffect;
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IREffect */
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIREffect ( IREffect );
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   struct _IRDirty {
1949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* What to call, and details of args/results.  .guard must be
1950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         non-NULL.  If .tmp is not IRTemp_INVALID (that is, the call
1951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         returns a result) then .guard must be demonstrably (at
1952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         JIT-time) always true, that is, the call must be
1953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unconditional.  Conditional calls that assign .tmp are not
1954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         allowed. */
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRCallee* cee;    /* where to call */
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr**  args;   /* arg list, ends in NULL */
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Mem effects; we allow only one R/W/M region to be stated */
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IREffect  mFx;    /* indicates memory effects, if any */
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Guest state effects; up to N allowed */
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool needsBBP; /* True => also pass guest state ptr to callee */
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct {
1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         IREffect fx:16;   /* read, write or modify?  Ifx_None is invalid. */
1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UShort   offset;
1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UShort   size;
1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UChar    nRepeats;
1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UChar    repeatLen;
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } fxState[VEX_N_FXSTATE];
1975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* The access can be repeated, as specified by nRepeats and
1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         repeatLen.  To describe only a single access, nRepeats and
1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         repeatLen should be zero.  Otherwise, repeatLen must be a
1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         multiple of size and greater than size. */
1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Overall, the parts of the guest state denoted by (offset,
1980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         size, nRepeats, repeatLen) is
1981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               [offset, +size)
1982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            and, if nRepeats > 0,
1983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               for (i = 1; i <= nRepeats; i++)
1984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                  [offset + i * repeatLen, +size)
1985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         A convenient way to enumerate all segments is therefore
1986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            for (i = 0; i < 1 + nRepeats; i++)
1987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               [offset + i * repeatLen, +size)
1988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      */
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRDirty;
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print a dirty call */
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void     ppIRDirty ( IRDirty* );
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate an uninitialised dirty call */
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRDirty* emptyIRDirty ( void );
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy a dirty call */
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRDirty* deepCopyIRDirty ( IRDirty* );
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A handy function which takes some of the tedium out of constructing
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dirty helper calls.  The called function impliedly does not return
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any value and has a constant-True guard.  The call is marked as
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   accessing neither guest state nor memory (hence the "unsafe"
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   designation) -- you can change this marking later if need be.  A
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   suitable IRCallee is constructed from the supplied bits. */
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             IRExpr** args );
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Similarly, make a zero-annotation dirty call which returns a value,
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and assign that to the given temp. */
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRDirty* unsafeIRDirty_1_N ( IRTemp dst,
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Int regparms, HChar* name, void* addr,
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             IRExpr** args );
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Memory Bus Events --------------- */
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Imbe_Fence=0x18000,
2024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Needed only on ARM.  It cancels a reservation made by a
2025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         preceding Linked-Load, and needs to be handed through to the
2026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         back end, just as LL and SC themselves are. */
2027b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Imbe_CancelReservation
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRMBusEvent;
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRMBusEvent ( IRMBusEvent );
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Compare and Swap --------------- */
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This denotes an atomic compare and swap operation, either
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a single-element one or a double-element one.
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In the single-element case:
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .addr is the memory address.
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .end  is the endianness with which memory is accessed
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     If .addr contains the same value as .expdLo, then .dataLo is
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     written there, else there is no write.  In both cases, the
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     original value at .addr is copied into .oldLo.
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Types: .expdLo, .dataLo and .oldLo must all have the same type.
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     guests, I64.
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     be NULL.
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In the double-element case:
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .addr is the memory address.
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .end  is the endianness with which memory is accessed
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     The operation is the same:
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     If .addr contains the same value as .expdHi:.expdLo, then
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .dataHi:.dataLo is written there, else there is no write.  In
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     both cases the original value at .addr is copied into
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .oldHi:.oldLo.
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     all have the same type, which may be any integral type, viz: I8,
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     I16, I32 or, for 64-bit guests, I64.
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     The double-element case is complicated by the issue of
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     endianness.  In all cases, the two elements are understood to be
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     located adjacently in memory, starting at the address .addr.
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       If .end is Iend_LE, then the .xxxLo component is at the lower
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       address and the .xxxHi component is at the higher address, and
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       each component is itself stored little-endianly.
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       If .end is Iend_BE, then the .xxxHi component is at the lower
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       address and the .xxxLo component is at the higher address, and
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       each component is itself stored big-endianly.
2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This allows representing more cases than most architectures can
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   How to know if the CAS succeeded?
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     stored at .addr, and the original value there was .oldLo (resp
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     .oldHi:.oldLo).
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     then the CAS failed, and the original value at .addr was .oldLo
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     (resp. .oldHi:.oldLo).
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Hence it is easy to know whether or not the CAS succeeded.
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRTemp    oldHi;  /* old value of *addr is written here */
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRTemp    oldLo;
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IREndness end;    /* endianness of the data in memory */
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   addr;   /* store address */
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   expdHi; /* expected old value at *addr */
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   expdLo;
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   dataHi; /* new value for *addr */
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*   dataLo;
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRCAS;
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRCAS ( IRCAS* cas );
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        IREndness end, IRExpr* addr,
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        IRExpr* expdHi, IRExpr* expdLo,
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        IRExpr* dataHi, IRExpr* dataLo );
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCAS* deepCopyIRCAS ( IRCAS* );
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------ Circular Array Put ------------------ */
2123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef
2124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   struct {
2125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      IRRegArray* descr; /* Part of guest state treated as circular */
2126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      IRExpr*     ix;    /* Variable part of index into array */
2127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int         bias;  /* Constant offset part of index into array */
2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      IRExpr*     data;  /* The value to write */
2129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } IRPutI;
2130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern void ppIRPutI ( IRPutI* puti );
2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                          Int bias, IRExpr* data );
2135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRPutI* deepCopyIRPutI ( IRPutI* );
2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Statements ------------------ */
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The different kinds of statements.  Their meaning is explained
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   below in the comments for IRStmt.
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Those marked META do not represent code, but rather extra
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information about the code.  These statements can be removed
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   without affecting the functional behaviour of the code, however
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   they are required by some IR consumers such as tools that
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   instrument the code.
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_NoOp=0x19000,
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_IMark,     /* META */
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_AbiHint,   /* META */
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_Put,
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_PutI,
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_WrTmp,
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_Store,
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_CAS,
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_LLSC,
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_Dirty,
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_MBE,       /* META (maybe) */
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ist_Exit
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRStmtTag;
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A statement.  Stored as a tagged union.  'tag' indicates what kind
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of expression this is.  'Ist' is the union that holds the fields.
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   statement, and the fields can be accessed with
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'st.Ist.Store.<fieldname>'.
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For each kind of statement, we show what it looks like when
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pretty-printed with ppIRStmt().
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _IRStmt {
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRStmtTag tag;
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      union {
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* A no-op (usually resulting from IR optimisation).  Can be
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            omitted without any effect.
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: IR-NoOp
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 } NoOp;
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* META: instruction mark.  Marks the start of the statements
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            that represent a single machine instruction (the end of
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            those statements is marked by the next IMark or the end of
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the IRSB).  Contains the address and length of the
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            instruction.
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            It also contains a delta value.  The delta must be
2196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            subtracted from a guest program counter value before
2197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            attempting to establish, by comparison with the address
2198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            and length values, whether or not that program counter
2199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            value refers to this instruction.  For x86, amd64, ppc32,
2200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ppc64 and arm, the delta value is zero.  For Thumb
2201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            instructions, the delta value is one.  This is because, on
2202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Thumb, guest PC values (guest_R15T) are encoded using the
2203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            top 31 bits of the instruction address and a 1 in the lsb;
2204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            hence they appear to be (numerically) 1 past the start of
2205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            the instruction they refer to.  IOW, guest_R15T on ARM
2206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            holds a standard ARM interworking address.
2207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                         eg. ------ IMark(0x4000792, 5, 0) ------,
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr64 addr;   /* instruction address */
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int    len;    /* instruction length */
2214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            UChar  delta;  /* addr = program counter as encoded in guest state
2215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                     - delta */
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } IMark;
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* META: An ABI hint, which says something about this
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            platform's ABI.
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            At the moment, the only AbiHint is one which indicates
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            that a given chunk of address space, [base .. base+len-1],
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            has become undefined.  This is used on amd64-linux and
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            some ppc variants to pass stack-redzoning hints to whoever
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            wants to see them.  It also indicates the address of the
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            next (dynamic) instruction that will be executed.  This is
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            to help Memcheck to origin tracking.
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         eg. ====== AbiHint(t1, 16, t2) ======
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr* base;     /* Start  of undefined chunk */
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int     len;      /* Length of undefined chunk */
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr* nia;      /* Address of next (guest) insn */
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } AbiHint;
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Write a guest register, at a fixed offset in the guest state.
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int     offset;   /* Offset into the guest state */
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr* data;     /* The value to write */
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Put;
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Write a guest register, at a non-fixed offset in the guest
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            state.  See the comment for GetI expressions for more
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            information.
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         eg. PUTI(64:8xF64)[t5,0] = t1
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            IRPutI* details;
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } PutI;
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Assign a value to a temporary.  Note that SSA rules require
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            each tmp is only assigned to once.  IR sanity checking will
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            reject any block containing a temporary which is not assigned
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            to exactly once.
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRTemp  tmp;   /* Temporary  (LHS of assignment) */
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr* data;  /* Expression (RHS of assignment) */
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } WrTmp;
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Write a value to memory.  This is a normal store, not a
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Store-Conditional.  To represent a Store-Conditional,
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            instead use IRStmt.LLSC.
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IREndness end;    /* Endianness of the store */
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr*   addr;   /* store address */
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr*   data;   /* value to write */
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Store;
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Do an atomic compare-and-swap operation.  Semantics are
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            described above on a comment at the definition of IRCAS.
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output:
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            eg
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               t1 = CASle(t2 :: t3->Add32(t3,1))
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               which denotes a 32-bit atomic increment
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               of a value at address t2
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            A double-element CAS may also be denoted, in which case <tmp>,
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <expected> and <new> are all pairs of items, separated by
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            commas.
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRCAS* details;
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } CAS;
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Either Load-Linked or Store-Conditional, depending on
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            STOREDATA.
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            If STOREDATA is NULL then this is a Load-Linked, meaning
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            that data is loaded from memory as normal, but a
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            'reservation' for the address is also lodged in the
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            hardware.
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               result = Load-Linked(addr, end)
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            The data transfer type is the type of RESULT (I32, I64,
2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            etc).  ppIRStmt output:
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            If STOREDATA is not NULL then this is a Store-Conditional,
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            hence:
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               result = Store-Conditional(addr, storedata, end)
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            The data transfer type is the type of STOREDATA and RESULT
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            has type Ity_I1. The store may fail or succeed depending
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            on the state of a previously lodged reservation on this
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            address.  RESULT is written 1 if the store succeeds and 0
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if it fails.  eg ppIRStmt output:
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               result = ( ST<end>-Cond(<addr>) = <storedata> )
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               eg t3 = ( STbe-Cond(t1, t2) )
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            In all cases, the address must be naturally aligned for
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the transfer type -- any misaligned addresses should be
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            caught by a dominating IR check and side exit.  This
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            alignment restriction exists because on at least some
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            misaligned addresses, and we have to actually generate
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            stwcx. on the host, and we don't want it trapping on the
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            host.
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Summary of rules for transfer type:
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              STOREDATA == NULL (LL):
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                transfer type = type of RESULT
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              STOREDATA != NULL (SC):
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                transfer type = type of STOREDATA, and RESULT :: Ity_I1
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IREndness end;
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRTemp    result;
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr*   addr;
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } LLSC;
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Call (possibly conditionally) a C function that has side
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            effects (ie. is "dirty").  See the comments above the
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRDirty type declaration for more information.
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output:
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               t<tmp> = DIRTY <guard> <effects>
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::: <callee>(<args>)
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            eg.
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ::: foo{0x380035f4}(t2)
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRDirty* details;
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Dirty;
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* A memory bus event - a fence, or acquisition/release of the
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            hardware bus lock.  IR optimisation treats all these as fences
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            across which no memory references may be moved.
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: MBusEvent-Fence,
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             MBusEvent-BusLock, MBusEvent-BusUnlock.
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRMBusEvent event;
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } MBE;
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Conditional exit from the middle of an IRSB.
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt output: if (<guard>) goto {<jk>} <dst>
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         eg. if (t69) goto {Boring} 0x4000AAA:I32
2377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            If <guard> is true, the guest state is also updated by
2378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            PUT-ing <dst> at <offsIP>.  This is done because a
2379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            taken exit must update the guest program counter.
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRExpr*    guard;    /* Conditional expression */
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            IRConst*   dst;      /* Jump target (constant only) */
2384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            IRJumpKind jk;       /* Jump kind */
2385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            Int        offsIP;   /* Guest state offset for IP */
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Exit;
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } Ist;
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRStmt;
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Statement constructors. */
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_NoOp    ( void );
2393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len, UChar delta );
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
2396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRStmt* IRStmt_PutI    ( IRPutI* details );
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_CAS     ( IRCAS* details );
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                IRExpr* addr, IRExpr* storedata );
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Dirty   ( IRDirty* details );
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
2404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                Int offsIP );
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRStmt. */
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* deepCopyIRStmt ( IRStmt* );
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRStmt. */
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRStmt ( IRStmt* );
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Basic Blocks ------------------ */
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Type environments: a bunch of statements, expressions, etc, are
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   incomplete without an environment indicating the type of each
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRTemp.  So this provides one.  IR temporaries are really just
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   them.
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRType* types;
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     types_size;
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     types_used;
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRTypeEnv;
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Obtain a new IRTemp */
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy a type environment */
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print a type environment */
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRTypeEnv ( IRTypeEnv* );
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Code blocks, which in proper compiler terminology are superblocks
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (single entry, multiple exit code sequences) contain:
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - A table giving a type for each temp (the "type environment")
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - An expandable array of statements
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - An expression of type 32 or 64 bits, depending on the
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     guest's word size, indicating the next destination if the block
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     executes all the way to the end, without a side exit
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - An indication of any special actions (JumpKind) needed
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     for this final jump.
2450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   - Offset of the IP field in the guest state.  This will be
2451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng     updated before the final jump is done.
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "IRSB" stands for "IR Super Block".
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRTypeEnv* tyenv;
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRStmt**   stmts;
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int        stmts_size;
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int        stmts_used;
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRExpr*    next;
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRJumpKind jumpkind;
2463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int        offsIP;
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRSB;
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate a new, uninitialised IRSB */
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* emptyIRSB ( void );
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRSB */
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* deepCopyIRSB ( IRSB* );
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRSB, except for the statements list, which set to be
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a new, empty, list of statements. */
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRSB */
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRSB ( IRSB* );
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append an IRStmt to an IRSB */
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void addStmtToIRSB ( IRSB*, IRStmt* );
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for the IR                             ---*/
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* For messing with IR type environments */
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTypeEnv* emptyIRTypeEnv  ( void );
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* What is the type of this expression? */
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRConst ( IRConst* );
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Sanity check a BB of IR */
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void sanityCheckIRSB ( IRSB*  bb,
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              HChar* caller,
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              Bool   require_flatness,
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              IRType guest_word_size );
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool isFlatIRStmt ( IRStmt* );
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this any value actually in the enumeration 'IRType' ? */
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool isPlausibleIRType ( IRType ty );
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ndef __LIBVEX_IR_H */
2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                             libvex_ir.h ---*/
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
2512