1ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
2ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin                                       libvex_ir.h ---*/
4ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
5ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
6f8ed9d874a7b8651654591c68c6d431c758d787csewardj/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
9f8ed9d874a7b8651654591c68c6d431c758d787csewardj
10785952d4bf502fa756b2ac58595fd31fe0f88559sewardj   Copyright (C) 2004-2015 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
29f8ed9d874a7b8651654591c68c6d431c758d787csewardj
30f8ed9d874a7b8651654591c68c6d431c758d787csewardj   Neither the names of the U.S. Department of Energy nor the
31f8ed9d874a7b8651654591c68c6d431c758d787csewardj   University of California nor the names of its contributors may be
32f8ed9d874a7b8651654591c68c6d431c758d787csewardj   used to endorse or promote products derived from this software
33f8ed9d874a7b8651654591c68c6d431c758d787csewardj   without prior written permission.
34f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/
35f8ed9d874a7b8651654591c68c6d431c758d787csewardj
36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#ifndef __LIBVEX_IR_H
37887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#define __LIBVEX_IR_H
38ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj
39887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "libvex_basictypes.h"
40ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
4157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
42ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
4357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/*--- High-level IR description                               ---*/
4457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/*---------------------------------------------------------------*/
4557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
4657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Vex IR is an architecture-neutral intermediate representation.
4757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Unlike some IRs in systems similar to Vex, it is not like assembly
4857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   language (ie. a list of instructions).  Rather, it is more like the
4957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IR that might be used in a compiler.
5057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
5157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Code blocks
5257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~
53dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   The code is broken into small code blocks ("superblocks", type:
54dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   'IRSB').  Each code block typically represents from 1 to perhaps 50
55dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   instructions.  IRSBs are single-entry, multiple-exit code blocks.
56dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   Each IRSB contains three things:
5757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - a type environment, which indicates the type of each temporary
58dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj     value present in the IRSB
5957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - a list of statements, which represent code
60dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   - a jump that exits from the end the IRSB
6157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Because the blocks are multiple-exit, there can be additional
62dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   conditional exit statements that cause control to leave the IRSB
63dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   before the final exit.  Also because of this, IRSBs can cover
64dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   multiple non-consecutive sequences of code (up to 3).  These are
65dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   recorded in the type VexGuestExtents (see libvex.h).
6657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
6757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Statements and expressions
6857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~~~~~~~~~~~~~~~~
6957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Statements (type 'IRStmt') represent operations with side-effects,
7057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   eg.  guest register writes, stores, and assignments to temporaries.
7157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Expressions (type 'IRExpr') represent operations without
7257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   side-effects, eg. arithmetic operations, loads, constants.
7357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Expressions can contain sub-expressions, forming expression trees,
7457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   eg. (3 + (4 * load(addr1)).
7557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
7657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Storage of guest state
7757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~~~~~~~~~~~~
7857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The "guest state" contains the guest registers of the guest machine
7957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   (ie.  the machine that we are simulating).  It is stored by default
8057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   in a block of memory supplied by the user of the VEX library,
8157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   generally referred to as the guest state (area).  To operate on
8257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   these registers, one must first read ("Get") them from the guest
8357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   state into a temporary value.  Afterwards, one can write ("Put")
8457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   them back into the guest state.
8557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
8657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Get and Put are characterised by a byte offset into the guest
8757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   state, a small integer which effectively gives the identity of the
8857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   referenced guest register, and a type, which indicates the size of
8957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   the value to be transferred.
9057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
9157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The basic "Get" and "Put" operations are sufficient to model normal
9257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   fixed registers on the guest.  Selected areas of the guest state
93dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   can be treated as a circular array of registers (type:
94dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   'IRRegArray'), which can be indexed at run-time.  This is done with
95dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   the "GetI" and "PutI" primitives.  This is necessary to describe
96dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   rotating register files, for example the x87 FPU stack, SPARC
97dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   register windows, and the Itanium register files.
9857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
9957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Examples, and flattened vs. unflattened code
10057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   For example, consider this x86 instruction:
10257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
10357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     addl %eax, %ebx
10457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
10557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   One Vex IR translation for this code would be this:
10657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
1072f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj     ------ IMark(0x24F275, 7, 0) ------
10857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t3 = GET:I32(0)             # get %eax, a 32-bit integer
10957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t2 = GET:I32(12)            # get %ebx, a 32-bit integer
11057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t1 = Add32(t3,t2)           # addl
11157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     PUT(0) = t1                 # put %eax
11257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   (For simplicity, this ignores the effects on the condition codes, and
11457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   the update of the instruction pointer.)
11557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The "IMark" is an IR statement that doesn't represent actual code.
11757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Instead it indicates the address and length of the original
11857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   instruction.  The numbers 0 and 12 are offsets into the guest state
11957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   for %eax and %ebx.  The full list of offsets for an architecture
12057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   <ARCH> can be found in the type VexGuest<ARCH>State in the file
12157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   VEX/pub/libvex_guest_<ARCH>.h.
12257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The five statements in this example are:
12457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - the IMark
12557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - three assignments to temporaries
12657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - one register write (put)
12757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The six expressions in this example are:
12957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - two register reads (gets)
13057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - one arithmetic (add) operation
13157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - three temporaries (two nested within the Add32, one in the PUT)
13257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
13357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The above IR is "flattened", ie. all sub-expressions are "atoms",
13457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   either constants or temporaries.  An equivalent, unflattened version
13557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   would be:
13657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
13757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     PUT(0) = Add32(GET:I32(0), GET:I32(12))
13857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
13957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IR is guaranteed to be flattened at instrumentation-time.  This makes
14057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   instrumentation easier.  Equivalent flattened and unflattened IR
14157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   typically results in the same generated code.
14257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
14357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Another example, this one showing loads and stores:
14457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
14557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     addl %edx,4(%eax)
14657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
14757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   This becomes (again ignoring condition code and instruction pointer
14857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   updates):
14957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
1502f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj     ------ IMark(0x4000ABA, 3, 0) ------
15157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t3 = Add32(GET:I32(0),0x4:I32)
15257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t2 = LDle:I32(t3)
15357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t1 = GET:I32(8)
15457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     t0 = Add32(t2,t1)
15557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     STle(t3) = t0
15657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
15757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   The "le" in "LDle" and "STle" is short for "little-endian".
15857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
15957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   No need for deallocations
16057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~~~~~~~~~~~~~~~
16157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Although there are allocation functions for various data structures
16257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   in this file, there are no deallocation functions.  This is because
16357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Vex uses a memory allocation scheme that automatically reclaims the
16457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   memory used by allocated structures once translation is completed.
16557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   This makes things easier for tools that instruments/transforms code
16657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   blocks.
16757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
16857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   SSAness and typing
16957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   ~~~~~~~~~~~~~~~~~~
170dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   The IR is fully typed.  For every IRSB (IR block) it is possible to
17157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   say unambiguously whether or not it is correctly typed.
17257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Incorrectly typed IR has no meaning and the VEX will refuse to
17357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   process it.  At various points during processing VEX typechecks the
17457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IR and aborts if any violations are found.  This seems overkill but
17557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   makes it a great deal easier to build a reliable JIT.
17657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
17757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IR also has the SSA property.  SSA stands for Static Single
17857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Assignment, and what it means is that each IR temporary may be
17957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   assigned to only once.  This idea became widely used in compiler
18057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   construction in the mid to late 90s.  It makes many IR-level
18157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   transformations/code improvements easier, simpler and faster.
18257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Whenever it typechecks an IR block, VEX also checks the SSA
18357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   property holds, and will abort if not so.  So SSAness is
18457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   mechanically and rigidly enforced.
18557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
18657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
18757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/*---------------------------------------------------------------*/
188ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj/*--- Type definitions for the IR                             ---*/
189ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
190ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
191496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj/* General comments about naming schemes:
192496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
193496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   All publically visible functions contain the name of the primary
194496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   type on which they operate (IRFoo, IRBar, etc).  Hence you should
195496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   be able to identify these functions by grepping for "IR[A-Z]".
196496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
197496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   For some type 'IRFoo':
198496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
199496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   - ppIRFoo is the printing method for IRFoo, printing it to the
200496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj     output channel specified in the LibVEX_Initialise call.
201496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
202496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   - eqIRFoo is a structural equality predicate for IRFoos.
203496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
204dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   - deepCopyIRFoo is a deep copy constructor for IRFoos.
205496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj     It recursively traverses the entire argument tree and
206f6c8ebf1294fea43756683ba7089b746168abb8esewardj     produces a complete new tree.  All types have a deep copy
207f6c8ebf1294fea43756683ba7089b746168abb8esewardj     constructor.
208496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
209dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
210496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj     It creates a new top-level copy of the supplied object,
211f6c8ebf1294fea43756683ba7089b746168abb8esewardj     but does not copy any sub-objects.  Only some types have a
212f6c8ebf1294fea43756683ba7089b746168abb8esewardj     shallow copy constructor.
213496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj*/
214496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
215c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* ------------------ Types ------------------ */
216e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
21757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* A type indicates the size of a value, and whether it's an integer, a
21857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   float, or a vector (SIMD) value. */
219e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardjtypedef
220c9a43665879a03886b27a65b68af2a2c11b04f59sewardj   enum {
221cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ity_INVALID=0x1100,
222c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      Ity_I1,
223c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_I8,
224c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_I16,
225c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_I32,
226c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_I64,
2279b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Ity_I128,  /* 128-bit scalar */
2283738bfcea70600334c830de5421adc0204890c95sewardj      Ity_F16,   /* 16 bit float */
229c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_F32,   /* IEEE 754 float */
230c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ity_F64,   /* IEEE 754 double */
231c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Ity_D32,   /* 32-bit Decimal floating point */
232c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Ity_D64,   /* 64-bit Decimal floating point */
233c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Ity_D128,  /* 128-bit Decimal floating point */
2342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Ity_F128,  /* 128-bit floating point; implementation defined */
235c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      Ity_V128,  /* 128-bit SIMD */
236c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      Ity_V256   /* 256-bit SIMD */
237d1725d18b61bf7912a9099686179faef5815dba1sewardj   }
238e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj   IRType;
239e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
24057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRType */
24135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardjextern void ppIRType ( IRType );
24257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
24357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Get the size (in bytes) of an IRType */
24457c10c89904f7fdc4244fcbf704625e7169aafe6sewardjextern Int sizeofIRType ( IRType );
245c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
2467d00913f2ac5014a145a899b6ee4b8511539221fsewardj/* Translate 1/2/4/8 into Ity_I{8,16,32,64} respectively.  Asserts on
2477d00913f2ac5014a145a899b6ee4b8511539221fsewardj   any other input. */
2487d00913f2ac5014a145a899b6ee4b8511539221fsewardjextern IRType integerIRTypeOfSize ( Int szB );
2497d00913f2ac5014a145a899b6ee4b8511539221fsewardj
250e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
251af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj/* ------------------ Endianness ------------------ */
252af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
25357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* IREndness is used in load IRExprs and store IRStmts. */
254af1cecaf9c96f99381dda16f41d286fc3e4d220asewardjtypedef
255af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   enum {
256cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Iend_LE=0x1200, /* little endian */
257c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      Iend_BE          /* big endian */
258af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   }
259af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   IREndness;
260af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
261af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
262c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* ------------------ Constants ------------------ */
263ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
26457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* IRConsts are used within 'Const' and 'Exit' IRExprs. */
26557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
26657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* The various kinds of constant. */
267ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
268c9a43665879a03886b27a65b68af2a2c11b04f59sewardj   enum {
269cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ico_U1=0x1300,
270c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ico_U8,
271c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ico_U16,
272c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ico_U32,
273c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Ico_U64,
2742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Ico_F32,   /* 32-bit IEEE754 floating */
2752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Ico_F32i,  /* 32-bit unsigned int to be interpreted literally
2762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                    as a IEEE754 single value. */
2771e6ad745ebafd0524da1da27a4b85524fa84f777sewardj      Ico_F64,   /* 64-bit IEEE754 floating */
2781e6ad745ebafd0524da1da27a4b85524fa84f777sewardj      Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
2791e6ad745ebafd0524da1da27a4b85524fa84f777sewardj                    as a IEEE754 double value. */
28037a505b5a6814921fcfff1eac950a9ef7651e42bsewardj      Ico_V128,  /* 128-bit restricted vector constant, with 1 bit
28157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                    (repeated 8 times) for each of the 16 x 1-byte lanes */
28237a505b5a6814921fcfff1eac950a9ef7651e42bsewardj      Ico_V256   /* 256-bit restricted vector constant, with 1 bit
28337a505b5a6814921fcfff1eac950a9ef7651e42bsewardj                    (repeated 8 times) for each of the 32 x 1-byte lanes */
284207557ab2ea38239b670785c976b89d50bbb0eccsewardj   }
285ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   IRConstTag;
286ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
28757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* A constant.  Stored as a tagged union.  'tag' indicates what kind of
28857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   constant this is.  'Ico' is the union that holds the fields.  If an
28957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
29057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   and its value can be accessed with 'c.Ico.U32'. */
291ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
292e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj   struct _IRConst {
293ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      IRConstTag tag;
294ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      union {
295ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj         Bool   U1;
296c97096c44637ae5775ed305b19f16f0b505f17d8sewardj         UChar  U8;
297c97096c44637ae5775ed305b19f16f0b505f17d8sewardj         UShort U16;
298c97096c44637ae5775ed305b19f16f0b505f17d8sewardj         UInt   U32;
299c97096c44637ae5775ed305b19f16f0b505f17d8sewardj         ULong  U64;
3002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         Float  F32;
3012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         UInt   F32i;
302a58ea668d4725b87a146cf43cc48b8ea6ead84casewardj         Double F64;
30317442fe8094d0f82266e5a05509f62cac8f7539esewardj         ULong  F64i;
30457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         UShort V128;   /* 16-bit value; see Ico_V128 comment above */
30537a505b5a6814921fcfff1eac950a9ef7651e42bsewardj         UInt   V256;   /* 32-bit value; see Ico_V256 comment above */
306ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      } Ico;
307ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   }
308ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   IRConst;
309ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
31057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* IRConst constructors */
311ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardjextern IRConst* IRConst_U1   ( Bool );
31217442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_U8   ( UChar );
31317442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_U16  ( UShort );
31417442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_U32  ( UInt );
31517442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_U64  ( ULong );
3162019a976f07ff418dde2dfc7cc74667ef66d7764sewardjextern IRConst* IRConst_F32  ( Float );
3172019a976f07ff418dde2dfc7cc74667ef66d7764sewardjextern IRConst* IRConst_F32i ( UInt );
31817442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_F64  ( Double );
31917442fe8094d0f82266e5a05509f62cac8f7539esewardjextern IRConst* IRConst_F64i ( ULong );
3201e6ad745ebafd0524da1da27a4b85524fa84f777sewardjextern IRConst* IRConst_V128 ( UShort );
32137a505b5a6814921fcfff1eac950a9ef7651e42bsewardjextern IRConst* IRConst_V256 ( UInt );
322c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
32357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy an IRConst */
3240b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRConst* deepCopyIRConst ( const IRConst* );
325695cff9303ef5dc8079117acfd632b44edb1f010sewardj
32657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRConst */
3270b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRConst ( const IRConst* );
32857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
32957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Compare two IRConsts for equality */
3300b70efae27eafd60bc7ea9a3955605d55a681651florianextern Bool eqIRConst ( const IRConst*, const IRConst* );
331ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
332c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
3338ea867b06de73d909c29e243407713c291c8414esewardj/* ------------------ Call targets ------------------ */
3348ea867b06de73d909c29e243407713c291c8414esewardj
3358ea867b06de73d909c29e243407713c291c8414esewardj/* Describes a helper function to call.  The name part is purely for
33677352545d8416a36a4e6310aaea6b0205508aea2sewardj   pretty printing and not actually used.  regparms=n tells the back
3378ea867b06de73d909c29e243407713c291c8414esewardj   end that the callee has been declared
33803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj   "__attribute__((regparm(n)))", although indirectly using the
33903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj   VEX_REGPARM(n) macro.  On some targets (x86) the back end will need
34003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj   to construct a non-standard sequence to call a function declared
34103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj   like this.
34243c56461a667ca81fe29f1db01450d6ff1d62949sewardj
34343c56461a667ca81fe29f1db01450d6ff1d62949sewardj   mcx_mask is a sop to Memcheck.  It indicates which args should be
34443c56461a667ca81fe29f1db01450d6ff1d62949sewardj   considered 'always defined' when lazily computing definedness of
34543c56461a667ca81fe29f1db01450d6ff1d62949sewardj   the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
34643c56461a667ca81fe29f1db01450d6ff1d62949sewardj   args[1], etc.  If a bit is set, the corresponding arg is excluded
34743c56461a667ca81fe29f1db01450d6ff1d62949sewardj   (hence "x" in "mcx") from definedness checking.
34843c56461a667ca81fe29f1db01450d6ff1d62949sewardj*/
3498ea867b06de73d909c29e243407713c291c8414esewardj
3508ea867b06de73d909c29e243407713c291c8414esewardjtypedef
3518ea867b06de73d909c29e243407713c291c8414esewardj   struct {
3521ff4756e1731485e6bf3cd96717cd8398daec1f2florian      Int          regparms;
3531ff4756e1731485e6bf3cd96717cd8398daec1f2florian      const HChar* name;
3541ff4756e1731485e6bf3cd96717cd8398daec1f2florian      void*        addr;
3551ff4756e1731485e6bf3cd96717cd8398daec1f2florian      UInt         mcx_mask;
3568ea867b06de73d909c29e243407713c291c8414esewardj   }
3578ea867b06de73d909c29e243407713c291c8414esewardj   IRCallee;
3588ea867b06de73d909c29e243407713c291c8414esewardj
35957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Create an IRCallee. */
3601ff4756e1731485e6bf3cd96717cd8398daec1f2florianextern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr );
3618ea867b06de73d909c29e243407713c291c8414esewardj
36257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy an IRCallee. */
3630b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRCallee* deepCopyIRCallee ( const IRCallee* );
3648ea867b06de73d909c29e243407713c291c8414esewardj
36557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRCallee. */
3660b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRCallee ( const IRCallee* );
3678ea867b06de73d909c29e243407713c291c8414esewardj
3688ea867b06de73d909c29e243407713c291c8414esewardj
3692d3f77c12d2911173fd182d0b6e954196dee9135sewardj/* ------------------ Guest state arrays ------------------ */
3702d3f77c12d2911173fd182d0b6e954196dee9135sewardj
37157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* This describes a section of the guest state that we want to
37257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   be able to index at run time, so as to be able to describe
37357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   indexed or rotating register files on the guest. */
3742d3f77c12d2911173fd182d0b6e954196dee9135sewardjtypedef
3752d3f77c12d2911173fd182d0b6e954196dee9135sewardj   struct {
37657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Int    base;   /* guest state offset of start of indexed area */
37757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      IRType elemTy; /* type of each element in the indexed area */
37857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Int    nElems; /* number of elements in the indexed area */
3792d3f77c12d2911173fd182d0b6e954196dee9135sewardj   }
380dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   IRRegArray;
3812d3f77c12d2911173fd182d0b6e954196dee9135sewardj
382dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRRegArray* mkIRRegArray ( Int, IRType, Int );
3832d3f77c12d2911173fd182d0b6e954196dee9135sewardj
3840b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRRegArray* deepCopyIRRegArray ( const IRRegArray* );
385695cff9303ef5dc8079117acfd632b44edb1f010sewardj
3860b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRRegArray ( const IRRegArray* );
3870b70efae27eafd60bc7ea9a3955605d55a681651florianextern Bool eqIRRegArray ( const IRRegArray*, const IRRegArray* );
3882d3f77c12d2911173fd182d0b6e954196dee9135sewardj
3892d3f77c12d2911173fd182d0b6e954196dee9135sewardj
390c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* ------------------ Temporaries ------------------ */
391ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
39257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* This represents a temporary, eg. t1.  The IR optimiser relies on the
39357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   fact that IRTemps are 32-bit ints.  Do not change them to be ints of
39457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   any other size. */
395fbcaf3312f39fb73d54821636c6168db76245f61sewardjtypedef UInt IRTemp;
396ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
39757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRTemp. */
39835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardjextern void ppIRTemp ( IRTemp );
399c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
40092d168d0f2a985ed9f7ae4e6bba9565a13921b31sewardj#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
401fbcaf3312f39fb73d54821636c6168db76245f61sewardj
402ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
40340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj/* --------------- Primops (arity 1,2,3 and 4) --------------- */
404ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj
40557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Primitive operations that are used in Unop, Binop, Triop and Qop
40657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRExprs.  Once we take into account integer, floating point and SIMD
40757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   operations of all the different sizes, there are quite a lot of them.
40857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Most instructions supported by the architectures that Vex supports
40957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   (x86, PPC, etc) are represented.  Some more obscure ones (eg. cpuid)
41057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   are not;  they are instead handled with dirty helpers that emulate
41157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   their functionality.  Such obscure ones are thus not directly visible
41257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   in the IR, but their effects on guest state (memory and registers)
41357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   are made visible via the annotations in IRDirty structures.
41457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
415ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
41641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj   enum {
41771a35e7351fc1202ef2960d3f0315d9181624fe2sewardj      /* -- Do not change this ordering.  The IR generators rely on
41871a35e7351fc1202ef2960d3f0315d9181624fe2sewardj            (eg) Iop_Add64 == IopAdd8 + 3. -- */
41971a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
420cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Iop_INVALID=0x1400,
42166de22767fc526eff52133c18d4a42a9b25d5f18sewardj      Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
42241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
42341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      /* Signless mul.  MullS/MullU is elsewhere. */
42441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
42541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
42641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
42741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
42841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
42941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
43041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
431e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj      /* Integer comparisons. */
432e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
433e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
43441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      /* Tags for unary ops */
43541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
43671a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
4371fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj      /* Exactly like CmpEQ8/16/32/64, but carrying the additional
4381fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj         hint that these compute the success/failure of a CAS
4391fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj         operation, and hence are almost certainly applied to two
4401fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj         copies of the same value, which in turn has implications for
4411fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj         Memcheck's instrumentation. */
4421fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj      Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
4431fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj      Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
4441fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj
445e13074c2c1321d069fb95806bdce64f9a3512341sewardj      /* Exactly like CmpNE8/16/32/64, but carrying the additional
446e13074c2c1321d069fb95806bdce64f9a3512341sewardj         hint that these needs expensive definedness tracking. */
447e13074c2c1321d069fb95806bdce64f9a3512341sewardj      Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
448e13074c2c1321d069fb95806bdce64f9a3512341sewardj
44971a35e7351fc1202ef2960d3f0315d9181624fe2sewardj      /* -- Ordering not important after here. -- */
45071a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
4519690d927540d730525a5f7f14663f3ceaa7818dasewardj      /* Widening multiplies */
4529b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
4539b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
4548f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
455ce646f23d71ac432c340667387aa4a5ce7d18099sewardj      /* Wierdo integer stuff */
456f53b7359a342e7d79090615169c6583a1a75fbcesewardj      Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
457f53b7359a342e7d79090615169c6583a1a75fbcesewardj      Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
458f53b7359a342e7d79090615169c6583a1a75fbcesewardj      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
459f53b7359a342e7d79090615169c6583a1a75fbcesewardj         zero.  You must ensure they are never given a zero argument.
4608f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      */
4618f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
462b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* Standard integer comparisons */
4639854007808ab24cad3f971eab63face1cb1e6089sewardj      Iop_CmpLT32S, Iop_CmpLT64S,
4649854007808ab24cad3f971eab63face1cb1e6089sewardj      Iop_CmpLE32S, Iop_CmpLE64S,
4659854007808ab24cad3f971eab63face1cb1e6089sewardj      Iop_CmpLT32U, Iop_CmpLT64U,
4669854007808ab24cad3f971eab63face1cb1e6089sewardj      Iop_CmpLE32U, Iop_CmpLE64U,
467343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj
4680033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      /* As a sop to Valgrind-Memcheck, the following are useful. */
4690033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
470eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
471eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /*  \x -> x | -x */
472478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      Iop_Max32U, /* unsigned max */
4730033ddccac6f90789fe2e78e86b8a649931d77b4sewardj
47457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* PowerPC-style 3-way integer comparisons.  Without them it is
47557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         difficult to simulate PPC efficiently.
476b51f0f4f33256638ed953156a2635aa739b232f1sewardj         op(x,y) | x < y  = 0x8 else
477b51f0f4f33256638ed953156a2635aa739b232f1sewardj                 | x > y  = 0x4 else
478b51f0f4f33256638ed953156a2635aa739b232f1sewardj                 | x == y = 0x2
479b51f0f4f33256638ed953156a2635aa739b232f1sewardj      */
4802831b00c4950d6c2b061def05fd67528fe132ececerion      Iop_CmpORD32U, Iop_CmpORD64U,
4812831b00c4950d6c2b061def05fd67528fe132ececerion      Iop_CmpORD32S, Iop_CmpORD64S,
482b51f0f4f33256638ed953156a2635aa739b232f1sewardj
4839690d927540d730525a5f7f14663f3ceaa7818dasewardj      /* Division */
4848f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      /* TODO: clarify semantics wrt rounding, negative values, whatever */
4855c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion      Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
4865c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion      Iop_DivS32,   // ditto, signed
487f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      Iop_DivU64,   // :: I64,I64 -> I64 (simple div, no mod)
488f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      Iop_DivS64,   // ditto, signed
4898b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj      Iop_DivU64E,  // :: I64,I64 -> I64 (dividend is 64-bit arg (hi)
4908b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj                    //                    concat with 64 0's (low))
491e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj      Iop_DivS64E,  // ditto, signed
4928b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj      Iop_DivU32E,  // :: I32,I32 -> I32 (dividend is 32-bit arg (hi)
4938b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj                    // concat with 32 0's (low))
494e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj      Iop_DivS32E,  // ditto, signed
4955c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion
4969690d927540d730525a5f7f14663f3ceaa7818dasewardj      Iop_DivModU64to32, // :: I64,I32 -> I64
4979690d927540d730525a5f7f14663f3ceaa7818dasewardj                         // of which lo half is div and hi half is mod
4989690d927540d730525a5f7f14663f3ceaa7818dasewardj      Iop_DivModS64to32, // ditto, signed
49989d4e9828ce36532c957566ebb46947109a7b53dsewardj
500343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj      Iop_DivModU128to64, // :: V128,I64 -> V128
501343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj                          // of which lo half is div and hi half is mod
502343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj      Iop_DivModS128to64, // ditto, signed
503343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj
5042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_DivModS64to64, // :: I64,I64 -> I128
5052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                         // of which lo half is div and hi half is mod
5062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
5070033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      /* Integer conversions.  Some of these are redundant (eg
5080033ddccac6f90789fe2e78e86b8a649931d77b4sewardj         Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
5090033ddccac6f90789fe2e78e86b8a649931d77b4sewardj         having a complete set reduces the typical dynamic size of IR
5100033ddccac6f90789fe2e78e86b8a649931d77b4sewardj         and makes the instruction selectors easier to write. */
5110033ddccac6f90789fe2e78e86b8a649931d77b4sewardj
5129690d927540d730525a5f7f14663f3ceaa7818dasewardj      /* Widening conversions */
5130033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
5140033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                  Iop_16Uto32, Iop_16Uto64,
5150033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                               Iop_32Uto64,
5160033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
5170033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                  Iop_16Sto32, Iop_16Sto64,
5180033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                               Iop_32Sto64,
5190033ddccac6f90789fe2e78e86b8a649931d77b4sewardj
520a238471814bd386aeb58a76718b41e68b1a794b2sewardj      /* Narrowing conversions */
5210033ddccac6f90789fe2e78e86b8a649931d77b4sewardj      Iop_64to8, Iop_32to8, Iop_64to16,
522b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj      /* 8 <-> 16 bit conversions */
523b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj      Iop_16to8,      // :: I16 -> I8, low half
524b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj      Iop_16HIto8,    // :: I16 -> I8, high half
525b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj      Iop_8HLto16,    // :: (I8,I8) -> I16
5268c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      /* 16 <-> 32 bit conversions */
5278c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      Iop_32to16,     // :: I32 -> I16, low half
5288c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      Iop_32HIto16,   // :: I32 -> I16, high half
5298c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      Iop_16HLto32,   // :: (I16,I16) -> I32
5309690d927540d730525a5f7f14663f3ceaa7818dasewardj      /* 32 <-> 64 bit conversions */
5318c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      Iop_64to32,     // :: I64 -> I32, low half
5329690d927540d730525a5f7f14663f3ceaa7818dasewardj      Iop_64HIto32,   // :: I64 -> I32, high half
5339690d927540d730525a5f7f14663f3ceaa7818dasewardj      Iop_32HLto64,   // :: (I32,I32) -> I64
5349b96767debeeb1f78378f0e7e295fe6762c64002sewardj      /* 64 <-> 128 bit conversions */
5359b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Iop_128to64,    // :: I128 -> I64, low half
5369b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Iop_128HIto64,  // :: I128 -> I64, high half
5379b96767debeeb1f78378f0e7e295fe6762c64002sewardj      Iop_64HLto128,  // :: (I64,I64) -> I128
538cf780b4c356a274cc48a6829963f8bc79a1b34e8sewardj      /* 1-bit stuff */
5396e797c5fbd90ecc6531f9d8c4929848664a13714sewardj      Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
54084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
541291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj      Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
542291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj      Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
54384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
544291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj      Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
545fd33277c458b31596eb4fb15959467ac047c75dasewardj      Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
5468eda6304ecfaa1d0aa70773a2c07f996717f8f54sewardj      Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
547cf7879021370aabcccb1a9347244fcc7d5680141sewardj      Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
548b5874aa03bb38bf754aa8c1cb1e400f3d7e86b9fsewardj      Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
5498f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
550baf971ad7f6e005109f3301ec9d19c98066b3840sewardj      /* ------ Floating point.  We try to be IEEE754 compliant. ------ */
5518f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
552b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* --- Simple stuff as mandated by 754. --- */
553cfded9ab7c059881ecdbe967ddfcc1ce207986casewardj
554b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Binary operations, with rounding. */
555b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
556b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
55752ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj
5586c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
5596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
5606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
561b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Variants of the above which produce a 64-bit result but which
562b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         round their result to a IEEE float range first. */
563b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
564b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
56552ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj
566b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Unary operations, without rounding. */
567b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: F64 -> F64 */
568b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_NegF64, Iop_AbsF64,
5698f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
5706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* :: F32 -> F32 */
5716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_NegF32, Iop_AbsF32,
5726c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
573b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Unary operations, with rounding. */
574b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 -> F64 */
5756d52228c83cccffb6cadf7f0cdfe34df057b6fefflorian      Iop_SqrtF64,
576baf971ad7f6e005109f3301ec9d19c98066b3840sewardj
5776c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* :: IRRoundingMode(I32) x F32 -> F32 */
5786c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_SqrtF32,
5796c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5808f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
581883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj            0x45 Unordered
5828f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            0x01 LT
5838f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            0x00 GT
584883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj            0x40 EQ
5858f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         This just happens to be the Intel encoding.  The values
5868f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         are recorded in the type IRCmpF64Result.
5878f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      */
5886c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* :: F64 x F64 -> IRCmpF64Result(I32) */
5898f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      Iop_CmpF64,
5902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_CmpF32,
5912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_CmpF128,
5928f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
5933bca906f6e715c544eb49c278bedef093c14c0d7sewardj      /* --- Int to/from FP conversions. --- */
594b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
5956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* For the most part, these take a first argument :: Ity_I32 (as
5966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         IRRoundingMode) which is an indication of the rounding mode
5976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         to use, as per the following encoding ("the standard
5986c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         encoding"):
5998f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            00b  to nearest (the default)
6008f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            01b  to -infinity
6018f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            10b  to +infinity
6028f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            11b  to zero
6038f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         This just happens to be the Intel encoding.  For reference only,
6048f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         the PPC encoding is:
6058f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            00b  to nearest (the default)
6068f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            01b  to zero
6078f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            10b  to +infinity
6088f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            11b  to -infinity
6098f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         Any PPC -> IR front end will have to translate these PPC
6106c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         encodings, as encoded in the guest state, to the standard
6116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         encodings, to pass to the primops.
6126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         For reference only, the ARM VFP encoding is:
6136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            00b  to nearest
6146c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            01b  to +infinity
6156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            10b  to -infinity
6166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            11b  to zero
6176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         Again, this will have to be converted to the standard encoding
6186c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         to pass to primops.
6198f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
6208f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         If one of these conversions gets an out-of-range condition,
6218f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj         or a NaN, as an argument, the result is host-defined.  On x86
6226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         the "integer indefinite" value 0x80..00 is produced.  On PPC
6236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         it is either 0x80..00 or 0x7F..FF depending on the sign of
6246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         the argument.
6256c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6266c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         On ARMvfp, when converting to a signed integer result, the
6276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         overflow result is 0x80..00 for negative args and 0x7F..FF
6286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         for positive args.  For unsigned integer results it is
6296c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         0x00..00 and 0xFF..FF respectively.
6303bca906f6e715c544eb49c278bedef093c14c0d7sewardj
6313bca906f6e715c544eb49c278bedef093c14c0d7sewardj         Rounding is required whenever the destination type cannot
6323bca906f6e715c544eb49c278bedef093c14c0d7sewardj         represent exactly all values of the source type.
6338f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj      */
6346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
6356c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
6366c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
6374aa412af1d8166cc11f39a6e721df49431d23618sewardj      Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
6386c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6396c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
6406c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6416c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_I32StoF64, /*                       signed I32 -> F64 */
6426c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
64366d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
64466d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
64552ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj
6461c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */
6476c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      Iop_I32UtoF64, /*                       unsigned I32 -> F64 */
6483bca906f6e715c544eb49c278bedef093c14c0d7sewardj
6492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
6502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
6511c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */
6521c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */
6532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
6552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
6562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6576c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* Conversion between floating point formats */
6583bca906f6e715c544eb49c278bedef093c14c0d7sewardj      Iop_F32toF64,  /*                       F32 -> F64 */
6593bca906f6e715c544eb49c278bedef093c14c0d7sewardj      Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
6604cb918d355cef4e7640d374346852db4556f3524sewardj
66117442fe8094d0f82266e5a05509f62cac8f7539esewardj      /* Reinterpretation.  Take an F64 and produce an I64 with
66217442fe8094d0f82266e5a05509f62cac8f7539esewardj         the same bit pattern, or vice versa. */
663c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
664fc1b541264539587f12721ca0b73ef04580ed2bdsewardj      Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
665b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
6662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* Support for 128-bit floating point */
6672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
6682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
6692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128LOtoF64,/* F128 -> low  half of F128 into a F64 register */
6702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
6722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
6732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* :: F128 -> F128 */
6752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_NegF128, Iop_AbsF128,
6762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* :: IRRoundingMode(I32) x F128 -> F128 */
6782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_SqrtF128,
6792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_I32StoF128, /*                signed I32  -> F128 */
6812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_I64StoF128, /*                signed I64  -> F128 */
6821c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_I32UtoF128, /*              unsigned I32  -> F128 */
6831c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_I64UtoF128, /*              unsigned I64  -> F128 */
6842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F32toF128,  /*                       F32  -> F128 */
6852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F64toF128,  /*                       F64  -> F128 */
6862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32  */
6882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64  */
6891c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32  */
6901c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian      Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64  */
6912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128toF64,  /* IRRoundingMode(I32) x F128 -> F64         */
6922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_F128toF32,  /* IRRoundingMode(I32) x F128 -> F32         */
6932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
694b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* --- guest x86/amd64 specifics, not mandated by 754. --- */
695b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
696b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Binary ops, with rounding. */
697b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
698b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
699b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
700b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
701b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
702b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
703b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
704b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
705b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
706b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Note that on x86 guest, PRem1{C3210} has the same behaviour
707b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         as the IEEE mandated RemF64, except it is limited in the
708b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         range of its operand.  Hence the partialness. */
709b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
710b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* Unary ops, with rounding. */
711b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 -> F64 */
712b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_SinF64,    /* FSIN */
713b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_CosF64,    /* FCOS */
714b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_TanF64,    /* FTAN */
715b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_2xm1F64,   /* (2^arg - 1.0) */
716b53f948e1940bc43dcab52b3f99318da2240a0c9florian      Iop_RoundF128toInt, /* F128 value to nearest integral value (still
717b53f948e1940bc43dcab52b3f99318da2240a0c9florian                             as F128) */
718b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_RoundF64toInt, /* F64 value to nearest integral value (still
719b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                            as F64) */
720d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj      Iop_RoundF32toInt, /* F32 value to nearest integral value (still
721d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj                            as F32) */
722b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
7232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* --- guest s390 specifics, not mandated by 754. --- */
7242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
7252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* Fused multiply-add/sub */
7262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
7275906a6b242b06c27fdc583d4547eab10b86a9800florian            (computes arg2 * arg3 +/- arg4) */
7282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      Iop_MAddF32, Iop_MSubF32,
7292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
730b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* --- guest ppc32/64 specifics, not mandated by 754. --- */
731b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
73240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      /* Ternary operations, with rounding. */
73340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      /* Fused multiply-add/sub, with 112-bit intermediate
7342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         precision for ppc.
7352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         Also used to implement fused multiply-add/sub for s390. */
73640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
73740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            (computes arg2 * arg3 +/- arg4) */
73840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      Iop_MAddF64, Iop_MSubF64,
73940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj
74040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      /* Variants of the above which produce a 64-bit result but which
74140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         round their result to a IEEE float range first. */
74240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
74340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      Iop_MAddF64r32, Iop_MSubF64r32,
74440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj
745b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: F64 -> F64 */
7461ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtEst5GoodF64, /* reciprocal square root estimate, 5 good bits */
7470f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj      Iop_RoundF64toF64_NEAREST, /* frin */
7480f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj      Iop_RoundF64toF64_NegINF,  /* frim */
7490f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj      Iop_RoundF64toF64_PosINF,  /* frip */
7500f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj      Iop_RoundF64toF64_ZERO,    /* friz */
751b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
752b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: F64 -> F32 */
753b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
754b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
755b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* :: IRRoundingMode(I32) x F64 -> F64 */
756b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
757b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* NB: pretty much the same as Iop_F64toF32, except no change
758b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         of type. */
759b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
76089cefe4bb6a35343636d47f9888409a4e877fd5esewardj      /* --- guest arm64 specifics, not mandated by 754. --- */
76189cefe4bb6a35343636d47f9888409a4e877fd5esewardj
76289cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RecpExpF64,  /* FRECPX d  :: IRRoundingMode(I32) x F64 -> F64 */
76389cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RecpExpF32,  /* FRECPX s  :: IRRoundingMode(I32) x F32 -> F32 */
76489cefe4bb6a35343636d47f9888409a4e877fd5esewardj
7653738bfcea70600334c830de5421adc0204890c95sewardj      /* ------------------ 16-bit scalar FP ------------------ */
7663738bfcea70600334c830de5421adc0204890c95sewardj
7673738bfcea70600334c830de5421adc0204890c95sewardj      Iop_F16toF64,  /*                       F16 -> F64 */
7683738bfcea70600334c830de5421adc0204890c95sewardj      Iop_F64toF16,  /* IRRoundingMode(I32) x F64 -> F16 */
7693738bfcea70600334c830de5421adc0204890c95sewardj
7703738bfcea70600334c830de5421adc0204890c95sewardj      Iop_F16toF32,  /*                       F16 -> F32 */
7713738bfcea70600334c830de5421adc0204890c95sewardj      Iop_F32toF16,  /* IRRoundingMode(I32) x F32 -> F16 */
7723738bfcea70600334c830de5421adc0204890c95sewardj
773e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* ------------------ 32-bit SIMD Integer ------------------ */
774e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
77544ce46d5945ed83d96695d280510cc2a858894dcsewardj      /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
77644ce46d5945ed83d96695d280510cc2a858894dcsewardj      Iop_QAdd32S,
77744ce46d5945ed83d96695d280510cc2a858894dcsewardj      Iop_QSub32S,
77844ce46d5945ed83d96695d280510cc2a858894dcsewardj
779e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* 16x2 add/sub, also signed/unsigned saturating variants */
780e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_Add16x2, Iop_Sub16x2,
781e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_QAdd16Sx2, Iop_QAdd16Ux2,
782e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_QSub16Sx2, Iop_QSub16Ux2,
783e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
784e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* 16x2 signed/unsigned halving add/sub.  For each lane, these
785e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj         compute bits 16:1 of (eg) sx(argL) + sx(argR),
786e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj         or zx(argL) - zx(argR) etc. */
787e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_HAdd16Ux2, Iop_HAdd16Sx2,
788e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_HSub16Ux2, Iop_HSub16Sx2,
789e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
790e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* 8x4 add/sub, also signed/unsigned saturating variants */
791e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_Add8x4, Iop_Sub8x4,
792e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_QAdd8Sx4, Iop_QAdd8Ux4,
793e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_QSub8Sx4, Iop_QSub8Ux4,
794e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
795e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* 8x4 signed/unsigned halving add/sub.  For each lane, these
796e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj         compute bits 8:1 of (eg) sx(argL) + sx(argR),
797e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj         or zx(argL) - zx(argR) etc. */
798e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_HAdd8Ux4, Iop_HAdd8Sx4,
799e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_HSub8Ux4, Iop_HSub8Sx4,
800e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
801310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj      /* 8x4 sum of absolute unsigned differences. */
802310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj      Iop_Sad8Ux4,
803310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj
804e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      /* MISC (vector integer cmp != 0) */
805e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj      Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
806e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
8072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* ------------------ 64-bit SIMD FP ------------------------ */
8082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Convertion to/from int */
8102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_I32UtoFx2,  Iop_I32StoFx2,    /* I32x4 -> F32x4 */
8112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_FtoI32Ux2_RZ,  Iop_FtoI32Sx2_RZ,    /* F32x4 -> I32x4 */
8122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Fixed32 format is floating-point number with fixed number of fraction
8132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         bits. The number of fraction bits is passed as a second argument of
8142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         type I8. */
8152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
8162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
8172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Binary operations */
8192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Max32Fx2,      Iop_Min32Fx2,
8202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Pairwise Min and Max. See integer pairwise operations for more
8212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         details. */
8222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMax32Fx2,    Iop_PwMin32Fx2,
8232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Note: For the following compares, the arm front-end assumes a
8242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         nan in a lane of either argument returns zero for that lane. */
8252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
8262fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8272fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Estimate finds an approximate reciprocal of each
8282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      element in the operand vector, and places the results in the destination
8292fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      vector.  */
8301ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32Fx2,
8312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8322fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
8332fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Note, that if one of the arguments is zero and another one is infinity
8342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         of arbitrary sign the result of the operation is 2.0. */
8351ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipStep32Fx2,
8362fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8372fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
8382fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         square root of each element in the operand vector. */
8391ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtEst32Fx2,
8402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8412fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
8422fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Note, that of one of the arguments is zero and another one is infiinty
8432fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         of arbitrary sign the result of the operation is 1.5. */
8441ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtStep32Fx2,
8452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Unary */
8472fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Neg32Fx2, Iop_Abs32Fx2,
8482fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
84938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* ------------------ 64-bit SIMD Integer. ------------------ */
85038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
85138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* MISC (vector integer cmp != 0) */
8521806918ae2783af5808f00876581e01c7b650a0dsewardj      Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
85338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
85438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* ADDITION (normal / unsigned sat / signed sat) */
85538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
8562fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
8572fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
8582fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8592fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* PAIRWISE operations */
8602fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
8612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
8622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAdd8x8,  Iop_PwAdd16x4,  Iop_PwAdd32x2,
8632fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
8642fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
8652fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
8662fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
8672fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Longening variant is unary. The resulting vector contains two times
8682fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         less elements than operand, but they are two times wider.
8692fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Example:
8702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
8712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj               where a+b and c+d are unsigned 32-bit values. */
8722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
8732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
87438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
87538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* SUBTRACTION (normal / unsigned sat / signed sat) */
87638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
8772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
8782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
87938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
8802fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* ABSOLUTE VALUE */
8812fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
8822fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8832fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
8842fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
8852fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mul32Fx2,
88638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_MulHi16Ux4,
88738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_MulHi16Sx4,
8882fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Plynomial multiplication treats it's arguments as coefficients of
8892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         polynoms over {0, 1}. */
8902fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PolynomialMul8x8,
8912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8922fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Saturating Doubling Multiply Returning High Half and
8932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Vector Saturating Rounding Doubling Multiply Returning High Half */
8942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* These IROp's multiply corresponding elements in two vectors, double
8952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         the results, and place the most significant half of the final results
8962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         in the destination vector. The results are truncated or rounded. If
8972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         any of the results overflow, they are saturated. */
8982fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
8992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
90038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
9015ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
90238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_Avg8Ux8,
90338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_Avg16Ux4,
90438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
90538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* MIN/MAX */
9062fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
9072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
9082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
9092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
91038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
91138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* COMPARISON */
91238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
9132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
91438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
91538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
9162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* COUNT ones / leading zeroes / leading sign bits (not including topmost
9172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         bit) */
9182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Cnt8x8,
919a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      Iop_Clz8x8, Iop_Clz16x4, Iop_Clz32x2,
920a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      Iop_Cls8x8, Iop_Cls16x4, Iop_Cls32x2,
9217deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_Clz64x2,
9222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* VECTOR x VECTOR SHIFT / ROTATE */
9242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
9252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
9262fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
9272fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
9282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
92938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
930d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj      Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
9312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
932d71ba837242cc470f622335b1c650bce8886a533sewardj      Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
93338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
9342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* VECTOR x VECTOR SATURATING SHIFT */
9352fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
9362fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
9372fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* VECTOR x INTEGER SATURATING SHIFT */
9381dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSU8x8,  Iop_QShlNsatSU16x4,
9391dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSU32x2, Iop_QShlNsatSU64x1,
9401dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatUU8x8,  Iop_QShlNsatUU16x4,
9411dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatUU32x2, Iop_QShlNsatUU64x1,
9421dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSS8x8,  Iop_QShlNsatSS16x4,
9431dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSS32x2, Iop_QShlNsatSS64x1,
9442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9455f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* NARROWING (binary)
9465f438dd73072211989c6d496845bdc9b777ecbecsewardj         -- narrow 2xI64 into 1xI64, hi half from left arg */
947c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      /* For saturated narrowing, I believe there are 4 variants of
948c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         the basic arithmetic operation, depending on the signedness
949c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         of argument and result.  Here are examples that exemplify
950c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         what I mean:
951c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
952c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         QNarrow16Uto8U ( UShort x )  if (x >u 255) x = 255;
953c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      return x[7:0];
954c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
955c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         QNarrow16Sto8S ( Short x )   if (x <s -128) x = -128;
956c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      if (x >s  127) x = 127;
957c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      return x[7:0];
958c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
959c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         QNarrow16Uto8S ( UShort x )  if (x >u 127) x = 127;
960c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      return x[7:0];
961c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
962c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj         QNarrow16Sto8U ( Short x )   if (x <s 0)   x = 0;
963c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      if (x >s 255) x = 255;
964c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                      return x[7:0];
965c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      */
9665f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowBin16Sto8Ux8,
9675f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
968ad2c9ea0c360fced134b2dd0d4b28c0be3639cfbsewardj      Iop_NarrowBin16to8x8,    Iop_NarrowBin32to16x4,
96938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
9702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* INTERLEAVING */
9712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Interleave lanes from low or high halves of
97238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj         operands.  Most-significant result lane is from the left
97338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj         arg. */
97438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
97538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj      Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
9762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Interleave odd/even lanes of operands.  Most-significant result lane
9772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         is from the left arg.  Note that Interleave{Odd,Even}Lanes32x2 are
9782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         identical to Interleave{HI,LO}32x2 and so are omitted.*/
9792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
9802fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
9812fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
982d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj      /* CONCATENATION -- build a new value by concatenating either
983d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         the even or odd lanes of both operands.  Note that
984d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
985d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         and so are omitted. */
9862fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
9872fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
9882fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* GET / SET elements of VECTOR
9902fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         GET is binop (I64, I8) -> I<elem_size>
9912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         SET is triop (I64, I8, I<elem_size>) -> I64 */
9922fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Note: the arm back-end handles only constant second argument */
9932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
9942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
9952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* DUPLICATING -- copy value to all lanes */
9972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Dup8x8,   Iop_Dup16x4,   Iop_Dup32x2,
9982fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
999e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj      /* SLICE -- produces the lowest 64 bits of (arg1:arg2) >> (8 * arg3).
1000e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         arg3 is a shift amount in bytes and may be between 0 and 8
1001e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         inclusive.  When 0, the result is arg2; when 8, the result is arg1.
1002e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         Not all back ends handle all values.  The arm32 and arm64 back
1003e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         ends handle only immediate arg3 values. */
1004e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj      Iop_Slice64,  // (I64, I64, I8) -> I64
10052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1006336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      /* REVERSE the order of chunks in vector lanes.  Chunks must be
1007336803528188cd4fe8b4fcfa7c48ca1056811046sewardj         smaller than the vector lanes (obviously) and so may be 8-,
1008336803528188cd4fe8b4fcfa7c48ca1056811046sewardj         16- and 32-bit in size. */
10092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Examples:
1010336803528188cd4fe8b4fcfa7c48ca1056811046sewardj            Reverse8sIn16_x4([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1011336803528188cd4fe8b4fcfa7c48ca1056811046sewardj            Reverse8sIn32_x2([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
1012336803528188cd4fe8b4fcfa7c48ca1056811046sewardj            Reverse8sIn64_x1([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
1013336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn16_x4,
1014336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn32_x2, Iop_Reverse16sIn32_x2,
1015336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn64_x1, Iop_Reverse16sIn64_x1, Iop_Reverse32sIn64_x1,
1016d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj
1017d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj      /* PERMUTING -- copy src bytes to dst,
1018d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         as indexed by control vector bytes:
1019d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj            for i in 0 .. 7 . result[i] = argL[ argR[i] ]
1020d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         argR[i] values may only be in the range 0 .. 7, else behaviour
1021d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj         is undefined. */
1022d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj      Iop_Perm8x8,
1023d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj
1024e13074c2c1321d069fb95806bdce64f9a3512341sewardj      /* MISC CONVERSION -- get high bits of each byte lane, a la
1025e13074c2c1321d069fb95806bdce64f9a3512341sewardj         x86/amd64 pmovmskb */
1026e13074c2c1321d069fb95806bdce64f9a3512341sewardj      Iop_GetMSBs8x8, /* I64 -> I8 */
1027e13074c2c1321d069fb95806bdce64f9a3512341sewardj
10282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
10291ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj         See floating-point equivalents for details. */
10301ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32Ux2, Iop_RSqrtEst32Ux2,
10312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1032c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      /* ------------------ Decimal Floating Point ------------------ */
1033c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1034c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      /* ARITHMETIC INSTRUCTIONS   64-bit
1035c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj	 ----------------------------------
103679e5a4845df6d09250b142c4e160a95cf7688fc8florian	 IRRoundingMode(I32) X D64 X D64 -> D64
1037c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      */
1038c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1039c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1040c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      /* ARITHMETIC INSTRUCTIONS  128-bit
1041c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj	 ----------------------------------
104279e5a4845df6d09250b142c4e160a95cf7688fc8florian	 IRRoundingMode(I32) X D128 X D128 -> D128
1043c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      */
1044c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1045c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
104626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      /* SHIFT SIGNIFICAND INSTRUCTIONS
104726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *    The DFP significand is shifted by the number of digits specified
104826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *    by the U8 operand.  Digits shifted out of the leftmost digit are
104926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *    lost. Zeros are supplied to the vacated positions on the right.
105026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *    The sign of the result is the same as the sign of the original
105126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *    operand.
1052cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *
1053cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * D64 x U8  -> D64    left shift and right shift respectively */
105426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_ShlD64, Iop_ShrD64,
105526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
105626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      /* D128 x U8  -> D128  left shift and right shift respectively */
105726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_ShlD128, Iop_ShrD128,
105826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
105926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
106026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      /* FORMAT CONVERSION INSTRUCTIONS
106126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       *   D32 -> D64
106226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj       */
106326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D32toD64,
106426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
106526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      /*   D64 -> D128 */
106626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D64toD128,
106726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
1068b17e16fb3709b8282646009caffa2ead7bcf363fflorian      /*   I32S -> D128 */
1069b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I32StoD128,
1070b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1071b17e16fb3709b8282646009caffa2ead7bcf363fflorian      /*   I32U -> D128 */
1072b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I32UtoD128,
1073b17e16fb3709b8282646009caffa2ead7bcf363fflorian
107426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      /*   I64S -> D128 */
107526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_I64StoD128,
107626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
1077b17e16fb3709b8282646009caffa2ead7bcf363fflorian      /*   I64U -> D128 */
1078b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I64UtoD128,
1079b17e16fb3709b8282646009caffa2ead7bcf363fflorian
108079e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D64 -> D32 */
108126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D64toD32,
108226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
108379e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> D64 */
108426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D128toD64,
108526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
1086b17e16fb3709b8282646009caffa2ead7bcf363fflorian      /*   I32S -> D64 */
1087b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I32StoD64,
1088b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1089b17e16fb3709b8282646009caffa2ead7bcf363fflorian      /*   I32U -> D64 */
1090b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I32UtoD64,
1091b17e16fb3709b8282646009caffa2ead7bcf363fflorian
109279e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x I64 -> D64 */
109326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_I64StoD64,
109426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
109579e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x I64 -> D64 */
1096b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_I64UtoD64,
1097b17e16fb3709b8282646009caffa2ead7bcf363fflorian
109879e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D64 -> I32 */
1099b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D64toI32S,
1100b17e16fb3709b8282646009caffa2ead7bcf363fflorian
110179e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D64 -> I32 */
1102b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D64toI32U,
1103b17e16fb3709b8282646009caffa2ead7bcf363fflorian
110479e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D64 -> I64 */
110526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D64toI64S,
110626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
110779e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D64 -> I64 */
1108b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D64toI64U,
1109b17e16fb3709b8282646009caffa2ead7bcf363fflorian
111079e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> I32 */
1111b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D128toI32S,
1112b17e16fb3709b8282646009caffa2ead7bcf363fflorian
111379e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> I32 */
1114b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D128toI32U,
1115b17e16fb3709b8282646009caffa2ead7bcf363fflorian
111679e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> I64 */
111726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      Iop_D128toI64S,
111826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
111979e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> I64 */
1120b17e16fb3709b8282646009caffa2ead7bcf363fflorian      Iop_D128toI64U,
1121b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1122b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F32 -> D32 */
1123b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F32toD32,
1124b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1125b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F32 -> D64 */
1126b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F32toD64,
1127b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1128b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F32 -> D128 */
1129b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F32toD128,
1130b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1131b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F64 -> D32 */
1132b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F64toD32,
1133b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
113479e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x F64 -> D64 */
113537c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian      Iop_F64toD64,
113637c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian
113779e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x F64 -> D128 */
113837c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian      Iop_F64toD128,
113937c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian
1140b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F128 -> D32 */
1141b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F128toD32,
1142b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1143b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x F128 -> D64 */
1144b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_F128toD64,
114537c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian
114679e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x F128 -> D128 */
114737c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian      Iop_F128toD128,
114837c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian
1149b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D32 -> F32 */
1150b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D32toF32,
1151b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1152b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D32 -> F64 */
1153b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D32toF64,
1154b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1155b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D32 -> F128 */
1156b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D32toF128,
1157b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1158b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D64 -> F32 */
1159b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D64toF32,
1160b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1161b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D64 -> F64 */
1162b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D64toF64,
1163b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1164b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D64 -> F128 */
1165b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D64toF128,
1166b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1167b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D128 -> F32 */
1168b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D128toF32,
1169b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
1170b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      /*   IRRoundingMode(I32) x D128 -> F64 */
1171b22838d88488f42a46a6d01f5df441c391fb3bbaflorian      Iop_D128toF64,
1172b22838d88488f42a46a6d01f5df441c391fb3bbaflorian
117379e5a4845df6d09250b142c4e160a95cf7688fc8florian      /*   IRRoundingMode(I32) x D128 -> F128 */
117437c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian      Iop_D128toF128,
117537c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian
1176cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* ROUNDING INSTRUCTIONS
1177cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * IRRoundingMode(I32) x D64 -> D64
1178cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll       * The D64 operand, if a finite number, it is rounded to a
1179cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll       * floating point integer value, i.e. no fractional part.
1180cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       */
1181cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_RoundD64toInt,
1182cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1183cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* IRRoundingMode(I32) x D128 -> D128 */
1184cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_RoundD128toInt,
1185cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1186cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* COMPARE INSTRUCTIONS
1187cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * D64 x D64 -> IRCmpD64Result(I32) */
1188cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_CmpD64,
1189cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1190daa4084cffd771efef294a484e64868f3eeeb0e4florian      /* D128 x D128 -> IRCmpD128Result(I32) */
1191cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_CmpD128,
1192cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
119320c6bca02d9b3c985607b4639ffc70eb504cc237florian      /* COMPARE BIASED EXPONENET INSTRUCTIONS
119420c6bca02d9b3c985607b4639ffc70eb504cc237florian       * D64 x D64 -> IRCmpD64Result(I32) */
119520c6bca02d9b3c985607b4639ffc70eb504cc237florian      Iop_CmpExpD64,
119620c6bca02d9b3c985607b4639ffc70eb504cc237florian
119720c6bca02d9b3c985607b4639ffc70eb504cc237florian      /* D128 x D128 -> IRCmpD128Result(I32) */
119820c6bca02d9b3c985607b4639ffc70eb504cc237florian      Iop_CmpExpD128,
119920c6bca02d9b3c985607b4639ffc70eb504cc237florian
1200cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* QUANTIZE AND ROUND INSTRUCTIONS
1201cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * The source operand is converted and rounded to the form with the
1202cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * immediate exponent specified by the rounding and exponent parameter.
1203cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *
1204cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * The second operand is converted and rounded to the form
1205cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * of the first operand's exponent and the rounded based on the specified
1206cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * rounding mode parameter.
1207cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *
120879e5a4845df6d09250b142c4e160a95cf7688fc8florian       * IRRoundingMode(I32) x D64 x D64-> D64 */
1209cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_QuantizeD64,
1210cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
121179e5a4845df6d09250b142c4e160a95cf7688fc8florian      /* IRRoundingMode(I32) x D128 x D128 -> D128 */
1212cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_QuantizeD128,
1213cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
121479e5a4845df6d09250b142c4e160a95cf7688fc8florian      /* IRRoundingMode(I32) x I8 x D64 -> D64
1215cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    The Decimal Floating point operand is rounded to the requested
1216cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    significance given by the I8 operand as specified by the rounding
1217cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    mode.
1218cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       */
1219cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_SignificanceRoundD64,
1220cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
122179e5a4845df6d09250b142c4e160a95cf7688fc8florian      /* IRRoundingMode(I32) x I8 x D128 -> D128 */
1222cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_SignificanceRoundD128,
1223cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1224cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* EXTRACT AND INSERT INSTRUCTIONS
1225cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       * D64 -> I64
1226cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    The exponent of the D32 or D64 operand is extracted.  The
1227cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    extracted exponent is converted to a 64-bit signed binary integer.
1228cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       */
1229cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_ExtractExpD64,
1230cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1231cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* D128 -> I64 */
1232cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_ExtractExpD128,
1233cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
12344bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian      /* D64 -> I64
12354bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian       * The number of significand digits of the D64 operand is extracted.
12364bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian       * The number is stored as a 64-bit signed binary integer.
12374bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian       */
12384bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian      Iop_ExtractSigD64,
12394bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian
12404bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian      /* D128 -> I64 */
12414bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian      Iop_ExtractSigD128,
12424bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian
1243cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      /* I64 x D64  -> D64
1244cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    The exponent is specified by the first I64 operand the signed
1245cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    significand is given by the second I64 value.  The result is a D64
1246cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    value consisting of the specified significand and exponent whose
1247cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       *    sign is that of the specified significand.
1248cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       */
1249cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_InsertExpD64,
1250cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1251cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      /* I64 x D128 -> D128 */
1252cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_InsertExpD128,
1253cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1254c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      /* Support for 128-bit DFP type */
1255c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1256c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
12574c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      /*  I64 -> I64
12584c96e61dd85c172b999d6afc88ce6640aeba9962sewardj       *     Convert 50-bit densely packed BCD string to 60 bit BCD string
12594c96e61dd85c172b999d6afc88ce6640aeba9962sewardj       */
12604c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      Iop_DPBtoBCD,
12614c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
12624c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      /* I64 -> I64
12634c96e61dd85c172b999d6afc88ce6640aeba9962sewardj       *     Convert 60 bit BCD string to 50-bit densely packed BCD string
12644c96e61dd85c172b999d6afc88ce6640aeba9962sewardj       */
12654c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      Iop_BCDtoDPB,
12664c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
12677deaf9552b546b847528cf39b38898fb7742b5f5carll      /* BCD arithmetic instructions, (V128, V128) -> V128
12687deaf9552b546b847528cf39b38898fb7742b5f5carll       * The BCD format is the same as that used in the BCD<->DPB conversion
12699571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj       * routines, except using 124 digits (vs 60) plus the trailing 4-bit
12709571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj       * signed code. */
12717deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_BCDAdd, Iop_BCDSub,
12727deaf9552b546b847528cf39b38898fb7742b5f5carll
1273cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      /* Conversion I64 -> D64 */
1274cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      Iop_ReinterpI64asD64,
1275cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
12765eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      /* Conversion D64 -> I64 */
12775eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      Iop_ReinterpD64asI64,
12785eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
1279164f9275c465cd09ecd09276b8542282f5def250sewardj      /* ------------------ 128-bit SIMD FP. ------------------ */
1280c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1281c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* --- 32x4 vector FP --- */
1282c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
12839571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1284c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
12859571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj
12869571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      /* binary */
1287c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Iop_Max32Fx4, Iop_Min32Fx4,
12882fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Add32Fx2, Iop_Sub32Fx2,
12892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Note: For the following compares, the ppc and arm front-ends assume a
1290f294eb389e8e703e2d4476aea7ca579a160a0a89cerion         nan in a lane of either argument returns zero for that lane. */
12912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
1292206c36410bd92f385b972e36a3a40e38675294e2cerion      Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
1293c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
12942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Pairwise Max and Min. See integer pairwise operations for details. */
12952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwMax32Fx4, Iop_PwMin32Fx4,
12962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1297c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* unary */
1298fab09143fb77b43e626ee73eeb375820e275d7bcsewardj      Iop_Abs32Fx4,
12992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Neg32Fx4,
13002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13014b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj      /* binary :: IRRoundingMode(I32) x V128 -> V128 */
13024b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj      Iop_Sqrt32Fx4,
13034b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj
13042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Estimate finds an approximate reciprocal of each
130589cefe4bb6a35343636d47f9888409a4e877fd5esewardj         element in the operand vector, and places the results in the
130689cefe4bb6a35343636d47f9888409a4e877fd5esewardj         destination vector.  */
13071ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32Fx4,
13082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
13102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Note, that if one of the arguments is zero and another one is infinity
13112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         of arbitrary sign the result of the operation is 2.0. */
13121ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipStep32Fx4,
13132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
13152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         square root of each element in the operand vector. */
13161ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtEst32Fx4,
13172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
13192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Note, that of one of the arguments is zero and another one is infiinty
13202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         of arbitrary sign the result of the operation is 1.5. */
13211ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtStep32Fx4,
13222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1323f294eb389e8e703e2d4476aea7ca579a160a0a89cerion      /* --- Int to/from FP conversion --- */
1324f294eb389e8e703e2d4476aea7ca579a160a0a89cerion      /* Unlike the standard fp conversions, these irops take no
1325f294eb389e8e703e2d4476aea7ca579a160a0a89cerion         rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1326f294eb389e8e703e2d4476aea7ca579a160a0a89cerion         indicate the mode: {-inf, +inf, nearest, zero} respectively. */
13278b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj      Iop_I32UtoFx4,     Iop_I32StoFx4,       /* I32x4 -> F32x4       */
13282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_FtoI32Ux4_RZ,  Iop_FtoI32Sx4_RZ,    /* F32x4 -> I32x4       */
13298b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj      Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ,   /* F32x4 -> I32x4 (saturating) */
1330f294eb389e8e703e2d4476aea7ca579a160a0a89cerion      Iop_RoundF32x4_RM, Iop_RoundF32x4_RP,   /* round to fp integer  */
1331f294eb389e8e703e2d4476aea7ca579a160a0a89cerion      Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ,   /* round to fp integer  */
13322fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Fixed32 format is floating-point number with fixed number of fraction
13332fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         bits. The number of fraction bits is passed as a second argument of
13342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         type I8. */
13352fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
13362fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
13372fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13382fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* --- Single to/from half conversion --- */
13395f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
13402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_F32toF16x4, Iop_F16toF32x4,         /* F32x4 <-> F16x4      */
1341f294eb389e8e703e2d4476aea7ca579a160a0a89cerion
1342c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* --- 32x4 lowest-lane-only scalar FP --- */
1343c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1344c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* In binary cases, upper 3/4 is copied from first operand.  In
1345b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion         unary cases, upper 3/4 is copied from the operand. */
1346c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1347c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* binary */
1348c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1349c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      Iop_Max32F0x4, Iop_Min32F0x4,
1350636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
1351c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1352c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* unary */
13531ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32F0x4, Iop_Sqrt32F0x4, Iop_RSqrtEst32F0x4,
1354636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1355636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* --- 64x2 vector FP --- */
1356636ad762e49597ef608323f27c7b8eb66962cd90sewardj
13579571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1358636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
13599571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj
13609571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      /* binary */
1361636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_Max64Fx2, Iop_Min64Fx2,
1362636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1363636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1364636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* unary */
1365fab09143fb77b43e626ee73eeb375820e275d7bcsewardj      Iop_Abs64Fx2,
1366fab09143fb77b43e626ee73eeb375820e275d7bcsewardj      Iop_Neg64Fx2,
1367fab09143fb77b43e626ee73eeb375820e275d7bcsewardj
13684b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj      /* binary :: IRRoundingMode(I32) x V128 -> V128 */
13694b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj      Iop_Sqrt64Fx2,
13704b21c3de6dabbe17c7f4cc1c4748c5491267c158sewardj
137189cefe4bb6a35343636d47f9888409a4e877fd5esewardj      /* see 32Fx4 variants for description */
137289cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RecipEst64Fx2,    // unary
137389cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RecipStep64Fx2,   // binary
137489cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RSqrtEst64Fx2,    // unary
137589cefe4bb6a35343636d47f9888409a4e877fd5esewardj      Iop_RSqrtStep64Fx2,   // binary
137689cefe4bb6a35343636d47f9888409a4e877fd5esewardj
1377636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* --- 64x2 lowest-lane-only scalar FP --- */
1378636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1379636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* In binary cases, upper half is copied from first operand.  In
1380b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion         unary cases, upper half is copied from the operand. */
1381636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1382636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* binary */
1383636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1384636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_Max64F0x2, Iop_Min64F0x2,
1385636ad762e49597ef608323f27c7b8eb66962cd90sewardj      Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1386636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1387636ad762e49597ef608323f27c7b8eb66962cd90sewardj      /* unary */
13881ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_Sqrt64F0x2,
1389c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1390c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      /* --- pack / unpack --- */
1391c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1392f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      /* 64 <-> 128 bit vector */
1393f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_V128to64,     // :: V128 -> I64, low half
1394f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_V128HIto64,   // :: V128 -> I64, high half
1395f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_64HLtoV128,   // :: (I64,I64) -> V128
1396c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1397f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_64UtoV128,
1398f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_SetV128lo64,
1399164f9275c465cd09ecd09276b8542282f5def250sewardj
1400ecde697ac84d29709ec34f8eb12753f9da32d451sewardj      /* Copies lower 64/32/16/8 bits, zeroes out the rest. */
1401ecde697ac84d29709ec34f8eb12753f9da32d451sewardj      Iop_ZeroHI64ofV128,    // :: V128 -> V128
1402ecde697ac84d29709ec34f8eb12753f9da32d451sewardj      Iop_ZeroHI96ofV128,    // :: V128 -> V128
1403ecde697ac84d29709ec34f8eb12753f9da32d451sewardj      Iop_ZeroHI112ofV128,   // :: V128 -> V128
1404ecde697ac84d29709ec34f8eb12753f9da32d451sewardj      Iop_ZeroHI120ofV128,   // :: V128 -> V128
1405606c4badcde61d6fc39f2f2be091e768b95909f8sewardj
1406f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      /* 32 <-> 128 bit vector */
1407f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_32UtoV128,
1408f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_V128to32,     // :: V128 -> I32, lowest lane
1409f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_SetV128lo32,  // :: (V128,I32) -> V128
141070f676d62218657de2d230d495ccd775909e107dsewardj
1411164f9275c465cd09ecd09276b8542282f5def250sewardj      /* ------------------ 128-bit SIMD Integer. ------------------ */
1412164f9275c465cd09ecd09276b8542282f5def250sewardj
1413164f9275c465cd09ecd09276b8542282f5def250sewardj      /* BITWISE OPS */
1414f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_NotV128,
1415f0c1c58d6e47608ce166058997f795f1d7d45127sewardj      Iop_AndV128, Iop_OrV128, Iop_XorV128,
1416164f9275c465cd09ecd09276b8542282f5def250sewardj
1417f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      /* VECTOR SHIFT (shift amt :: Ity_I8) */
1418f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      Iop_ShlV128, Iop_ShrV128,
1419f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion
14202e38386d2f5902feed6ec276c2c2292a137717b9sewardj      /* MISC (vector integer cmp != 0) */
14212e38386d2f5902feed6ec276c2c2292a137717b9sewardj      Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
142270f676d62218657de2d230d495ccd775909e107dsewardj
1423f7003bc89eb8b671eae3a9d730e024936b950583sewardj      /* ADDITION (normal / U->U sat / S->S sat) */
1424f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_Add8x16,    Iop_Add16x8,    Iop_Add32x4,    Iop_Add64x2,
1425f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAdd8Ux16,  Iop_QAdd16Ux8,  Iop_QAdd32Ux4,  Iop_QAdd64Ux2,
1426f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAdd8Sx16,  Iop_QAdd16Sx8,  Iop_QAdd32Sx4,  Iop_QAdd64Sx2,
1427f7003bc89eb8b671eae3a9d730e024936b950583sewardj
1428f7003bc89eb8b671eae3a9d730e024936b950583sewardj      /* ADDITION, ARM64 specific saturating variants. */
1429f7003bc89eb8b671eae3a9d730e024936b950583sewardj      /* Unsigned widen left arg, signed widen right arg, add, saturate S->S.
1430f7003bc89eb8b671eae3a9d730e024936b950583sewardj         This corresponds to SUQADD. */
1431f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAddExtUSsatSS8x16, Iop_QAddExtUSsatSS16x8,
1432f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAddExtUSsatSS32x4, Iop_QAddExtUSsatSS64x2,
1433f7003bc89eb8b671eae3a9d730e024936b950583sewardj      /* Signed widen left arg, unsigned widen right arg, add, saturate U->U.
1434f7003bc89eb8b671eae3a9d730e024936b950583sewardj         This corresponds to USQADD. */
1435f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAddExtSUsatUU8x16, Iop_QAddExtSUsatUU16x8,
1436f7003bc89eb8b671eae3a9d730e024936b950583sewardj      Iop_QAddExtSUsatUU32x4, Iop_QAddExtSUsatUU64x2,
1437164f9275c465cd09ecd09276b8542282f5def250sewardj
1438164f9275c465cd09ecd09276b8542282f5def250sewardj      /* SUBTRACTION (normal / unsigned sat / signed sat) */
14392fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,   Iop_Sub64x2,
14402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
14412fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
1442164f9275c465cd09ecd09276b8542282f5def250sewardj
1443164f9275c465cd09ecd09276b8542282f5def250sewardj      /* MULTIPLICATION (normal / high half of signed/unsigned) */
14442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mul8x16,  Iop_Mul16x8,    Iop_Mul32x4,
14452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                    Iop_MulHi16Ux8, Iop_MulHi32Ux4,
14462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                    Iop_MulHi16Sx8, Iop_MulHi32Sx4,
144724d06f124e3325e8edcc1c495d15736d5adcda96cerion      /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
144848ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4,
144948ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4,
145051d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj
145151d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj      /* Widening multiplies, all of the form (I64, I64) -> V128 */
14522fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mull8Ux8, Iop_Mull8Sx8,
14532fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mull16Ux4, Iop_Mull16Sx4,
14542fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Mull32Ux2, Iop_Mull32Sx2,
145551d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj
145651d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj      /* Signed doubling saturating widening multiplies, (I64, I64) -> V128 */
145751d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj      Iop_QDMull16Sx4, Iop_QDMull32Sx2,
145851d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj
14592fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Saturating Doubling Multiply Returning High Half and
1460f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj         Vector Saturating Rounding Doubling Multiply Returning High Half.
1461f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj         These IROps multiply corresponding elements in two vectors, double
14622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         the results, and place the most significant half of the final results
1463f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj         in the destination vector.  The results are truncated or rounded.  If
1464f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj         any of the results overflow, they are saturated.  To be more precise,
1465f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj         for each lane, the computed result is:
1466f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj           QDMulHi:
1467f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj             hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2 )
1468f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj           QRDMulHi:
1469f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj             hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2
1470f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj                      +q (1 << (lane-width-in-bits - 1)) )
1471f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj      */
1472f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj      Iop_QDMulHi16Sx8,  Iop_QDMulHi32Sx4,  /* (V128, V128) -> V128 */
1473f3eaabd8f0325dc4a7a51e56c9ab6d569616072fsewardj      Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, /* (V128, V128) -> V128 */
147451d012a3533e6c8c0a378dbca05a6ee3e4bd81absewardj
1475f5b0891759c4822ffee6cd6a13e4d043201d2297sewardj      /* Polynomial multiplication treats its arguments as
1476f5b0891759c4822ffee6cd6a13e4d043201d2297sewardj         coefficients of polynomials over {0, 1}. */
14772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
14782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PolynomialMull8x8, /*   (I64, I64) -> V128 */
14792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
14807deaf9552b546b847528cf39b38898fb7742b5f5carll      /* Vector Polynomial multiplication add.   (V128, V128) -> V128
14817deaf9552b546b847528cf39b38898fb7742b5f5carll
14827deaf9552b546b847528cf39b38898fb7742b5f5carll       *** Below is the algorithm for the instructions. These Iops could
14837deaf9552b546b847528cf39b38898fb7742b5f5carll           be emulated to get this functionality, but the emulation would
14847deaf9552b546b847528cf39b38898fb7742b5f5carll           be long and messy.
14857deaf9552b546b847528cf39b38898fb7742b5f5carll
14867deaf9552b546b847528cf39b38898fb7742b5f5carll        Example for polynomial multiply add for vector of bytes
14877deaf9552b546b847528cf39b38898fb7742b5f5carll        do i = 0 to 15
14887deaf9552b546b847528cf39b38898fb7742b5f5carll            prod[i].bit[0:14] <- 0
14897deaf9552b546b847528cf39b38898fb7742b5f5carll            srcA <- VR[argL].byte[i]
14907deaf9552b546b847528cf39b38898fb7742b5f5carll            srcB <- VR[argR].byte[i]
14917deaf9552b546b847528cf39b38898fb7742b5f5carll            do j = 0 to 7
14927deaf9552b546b847528cf39b38898fb7742b5f5carll                do k = 0 to j
14937deaf9552b546b847528cf39b38898fb7742b5f5carll                    gbit <- srcA.bit[k] & srcB.bit[j-k]
14947deaf9552b546b847528cf39b38898fb7742b5f5carll                    prod[i].bit[j] <- prod[i].bit[j] ^ gbit
14957deaf9552b546b847528cf39b38898fb7742b5f5carll                end
14967deaf9552b546b847528cf39b38898fb7742b5f5carll            end
14977deaf9552b546b847528cf39b38898fb7742b5f5carll
14987deaf9552b546b847528cf39b38898fb7742b5f5carll            do j = 8 to 14
14997deaf9552b546b847528cf39b38898fb7742b5f5carll                do k = j-7 to 7
15007deaf9552b546b847528cf39b38898fb7742b5f5carll                     gbit <- (srcA.bit[k] & srcB.bit[j-k])
15017deaf9552b546b847528cf39b38898fb7742b5f5carll                     prod[i].bit[j] <- prod[i].bit[j] ^ gbit
15027deaf9552b546b847528cf39b38898fb7742b5f5carll                end
15037deaf9552b546b847528cf39b38898fb7742b5f5carll            end
15047deaf9552b546b847528cf39b38898fb7742b5f5carll        end
15057deaf9552b546b847528cf39b38898fb7742b5f5carll
15067deaf9552b546b847528cf39b38898fb7742b5f5carll        do i = 0 to 7
15077deaf9552b546b847528cf39b38898fb7742b5f5carll            VR[dst].hword[i] <- 0b0 || (prod[2×i] ^ prod[2×i+1])
15087deaf9552b546b847528cf39b38898fb7742b5f5carll        end
15097deaf9552b546b847528cf39b38898fb7742b5f5carll      */
15107deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_PolynomialMulAdd8x16, Iop_PolynomialMulAdd16x8,
15117deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_PolynomialMulAdd32x4, Iop_PolynomialMulAdd64x2,
15127deaf9552b546b847528cf39b38898fb7742b5f5carll
15132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* PAIRWISE operations */
15142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
15152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
15162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
15172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAdd32Fx2,
15182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Longening variant is unary. The resulting vector contains two times
15192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         less elements than operand, but they are two times wider.
15202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Example:
15212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
15222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj               where a+b and c+d are unsigned 32-bit values. */
15232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
15242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
15252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
152660c6bac19ffe055cabab554e7877d73096a8bf17carll      /* Other unary pairwise ops */
152760c6bac19ffe055cabab554e7877d73096a8bf17carll
152860c6bac19ffe055cabab554e7877d73096a8bf17carll      /* Vector bit matrix transpose.  (V128) -> V128 */
152960c6bac19ffe055cabab554e7877d73096a8bf17carll      /* For each doubleword element of the source vector, an 8-bit x 8-bit
153060c6bac19ffe055cabab554e7877d73096a8bf17carll       * matrix transpose is performed. */
153160c6bac19ffe055cabab554e7877d73096a8bf17carll      Iop_PwBitMtxXpose64x2,
153260c6bac19ffe055cabab554e7877d73096a8bf17carll
15332fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* ABSOLUTE VALUE */
153425523c41e75eeb10894d60452d8e69ef8bf30244sewardj      Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2,
15351ac656a3b8eead55eeb0fb9090efec1c6719f989cerion
15365ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
1537f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1538f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
1539164f9275c465cd09ecd09276b8542282f5def250sewardj
1540164f9275c465cd09ecd09276b8542282f5def250sewardj      /* MIN/MAX */
154148ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2,
154248ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2,
154348ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2,
154448ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2,
1545164f9275c465cd09ecd09276b8542282f5def250sewardj
1546164f9275c465cd09ecd09276b8542282f5def250sewardj      /* COMPARISON */
1547d881562f1d18ab33038dab4a1b24823dba3422c0sewardj      Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,  Iop_CmpEQ64x2,
154869d98e3853a63e578e039894e2ef00ca6f9878c8sewardj      Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
154948ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, Iop_CmpGT64Ux2,
1550164f9275c465cd09ecd09276b8542282f5def250sewardj
15512fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* COUNT ones / leading zeroes / leading sign bits (not including topmost
15522fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         bit) */
15532fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Cnt8x16,
1554a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4,
1555a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      Iop_Cls8x16, Iop_Cls16x8, Iop_Cls32x4,
15562fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1557164f9275c465cd09ecd09276b8542282f5def250sewardj      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
15582a4b8459fa6ccd298263990296b955a36e313398cerion      Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
15592a4b8459fa6ccd298263990296b955a36e313398cerion      Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
15602fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
1561164f9275c465cd09ecd09276b8542282f5def250sewardj
1562f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      /* VECTOR x VECTOR SHIFT / ROTATE */
156315ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj      /* FIXME: I'm pretty sure the ARM32 front/back ends interpret these
156415ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         differently from all other targets.  The intention is that
156515ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         the shift amount (2nd arg) is interpreted as unsigned and
156615ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         only the lowest log2(lane-bits) bits are relevant.  But the
156715ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         ARM32 versions treat the shift amount as an 8 bit signed
156815ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         number.  The ARM32 uses should be replaced by the relevant
156915ceaef2c46a21b4598a304ad7d1eb14a901d3absewardj         vector x vector bidirectional shifts instead. */
15702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
15712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
15722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
15732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
157448ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2,
1575f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion
15762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* VECTOR x VECTOR SATURATING SHIFT */
15772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
15782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
15792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* VECTOR x INTEGER SATURATING SHIFT */
15801dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSU8x16, Iop_QShlNsatSU16x8,
15811dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSU32x4, Iop_QShlNsatSU64x2,
15821dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatUU8x16, Iop_QShlNsatUU16x8,
15831dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatUU32x4, Iop_QShlNsatUU64x2,
15841dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSS8x16, Iop_QShlNsatSS16x8,
15851dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj      Iop_QShlNsatSS32x4, Iop_QShlNsatSS64x2,
15862fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
15871297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      /* VECTOR x VECTOR BIDIRECTIONAL SATURATING (& MAYBE ROUNDING) SHIFT */
1588a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      /* All of type (V128, V128) -> V256. */
15891297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      /* The least significant 8 bits of each lane of the second
15901297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         operand are used as the shift amount, and interpreted signedly.
15911297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         Positive values mean a shift left, negative a shift right.  The
15921297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         result is signedly or unsignedly saturated.  There are also
15931297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         rounding variants, which add 2^(shift_amount-1) to the value before
15941297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         shifting, but only in the shift-right case.  Vacated positions
15951297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         are filled with zeroes.  IOW, it's either SHR or SHL, but not SAR.
15961297218cbc3c4b2da8537cca6e815afa57f255c3sewardj
15971297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         These operations return 129 bits: one bit ("Q") indicating whether
15981297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         saturation occurred, and the shift result.  The result type is V256,
15991297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         of which the lower V128 is the shift result, and Q occupies the
16001297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         least significant bit of the upper V128.  All other bits of the
16011297218cbc3c4b2da8537cca6e815afa57f255c3sewardj         upper V128 are zero. */
16021297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      // Unsigned saturation, no rounding
16031297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandUQsh8x16, Iop_QandUQsh16x8,
16041297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandUQsh32x4, Iop_QandUQsh64x2,
16051297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      // Signed saturation, no rounding
16061297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandSQsh8x16, Iop_QandSQsh16x8,
16071297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandSQsh32x4, Iop_QandSQsh64x2,
16081297218cbc3c4b2da8537cca6e815afa57f255c3sewardj
16091297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      // Unsigned saturation, rounding
16101297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandUQRsh8x16, Iop_QandUQRsh16x8,
16111297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandUQRsh32x4, Iop_QandUQRsh64x2,
16121297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      // Signed saturation, rounding
16131297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandSQRsh8x16, Iop_QandSQRsh16x8,
16141297218cbc3c4b2da8537cca6e815afa57f255c3sewardj      Iop_QandSQRsh32x4, Iop_QandSQRsh64x2,
16151297218cbc3c4b2da8537cca6e815afa57f255c3sewardj
1616a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      /* VECTOR x VECTOR BIDIRECTIONAL (& MAYBE ROUNDING) SHIFT */
1617a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      /* All of type (V128, V128) -> V128 */
1618a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      /* The least significant 8 bits of each lane of the second
1619a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         operand are used as the shift amount, and interpreted signedly.
1620a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         Positive values mean a shift left, negative a shift right.
1621a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         There are also rounding variants, which add 2^(shift_amount-1)
1622a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         to the value before shifting, but only in the shift-right case.
1623a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj
1624a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         For left shifts, the vacated places are filled with zeroes.
1625a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         For right shifts, the vacated places are filled with zeroes
1626a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         for the U variants and sign bits for the S variants. */
1627a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      // Signed and unsigned, non-rounding
1628a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      Iop_Sh8Sx16, Iop_Sh16Sx8, Iop_Sh32Sx4, Iop_Sh64Sx2,
1629a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      Iop_Sh8Ux16, Iop_Sh16Ux8, Iop_Sh32Ux4, Iop_Sh64Ux2,
1630a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj
1631a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      // Signed and unsigned, rounding
1632a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      Iop_Rsh8Sx16, Iop_Rsh16Sx8, Iop_Rsh32Sx4, Iop_Rsh64Sx2,
1633a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      Iop_Rsh8Ux16, Iop_Rsh16Ux8, Iop_Rsh32Ux4, Iop_Rsh64Ux2,
1634a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj
1635a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      /* The least significant 8 bits of each lane of the second
1636a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         operand are used as the shift amount, and interpreted signedly.
1637a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         Positive values mean a shift left, negative a shift right.  The
1638a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         result is signedly or unsignedly saturated.  There are also
1639a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         rounding variants, which add 2^(shift_amount-1) to the value before
1640a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         shifting, but only in the shift-right case.  Vacated positions
1641a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj         are filled with zeroes.  IOW, it's either SHR or SHL, but not SAR.
1642a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj      */
1643a6b61f00e85d3f9a51a216487941a55c700af0c6sewardj
1644ecedd989304126b77b8ff91044b8dde0e987c67asewardj      /* VECTOR x SCALAR SATURATING (& MAYBE ROUNDING) NARROWING SHIFT RIGHT */
1645ecedd989304126b77b8ff91044b8dde0e987c67asewardj      /* All of type (V128, I8) -> V128 */
1646ecedd989304126b77b8ff91044b8dde0e987c67asewardj      /* The first argument is shifted right, then narrowed to half the width
1647ecedd989304126b77b8ff91044b8dde0e987c67asewardj         by saturating it.  The second argument is a scalar shift amount that
1648ecedd989304126b77b8ff91044b8dde0e987c67asewardj         applies to all lanes, and must be a value in the range 1 to lane_width.
1649ecedd989304126b77b8ff91044b8dde0e987c67asewardj         The shift may be done signedly (Sar variants) or unsignedly (Shr
1650ecedd989304126b77b8ff91044b8dde0e987c67asewardj         variants).  The saturation is done according to the two signedness
1651ecedd989304126b77b8ff91044b8dde0e987c67asewardj         indicators at the end of the name.  For example 64Sto32U means a
1652ecedd989304126b77b8ff91044b8dde0e987c67asewardj         signed 64 bit value is saturated into an unsigned 32 bit value.
1653ecedd989304126b77b8ff91044b8dde0e987c67asewardj         Additionally, the QRS variants do rounding, that is, they add the
1654ecedd989304126b77b8ff91044b8dde0e987c67asewardj         value (1 << (shift_amount-1)) to each source lane before shifting.
1655ecedd989304126b77b8ff91044b8dde0e987c67asewardj
1656ecedd989304126b77b8ff91044b8dde0e987c67asewardj         These operations return 65 bits: one bit ("Q") indicating whether
1657ecedd989304126b77b8ff91044b8dde0e987c67asewardj         saturation occurred, and the shift result.  The result type is V128,
1658ecedd989304126b77b8ff91044b8dde0e987c67asewardj         of which the lower half is the shift result, and Q occupies the
1659ecedd989304126b77b8ff91044b8dde0e987c67asewardj         least significant bit of the upper half.  All other bits of the
1660ecedd989304126b77b8ff91044b8dde0e987c67asewardj         upper half are zero. */
1661ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // No rounding, sat U->U
1662ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQShrNnarrow16Uto8Ux8,
1663ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQShrNnarrow32Uto16Ux4, Iop_QandQShrNnarrow64Uto32Ux2,
1664ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // No rounding, sat S->S
1665ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQSarNnarrow16Sto8Sx8,
1666ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQSarNnarrow32Sto16Sx4, Iop_QandQSarNnarrow64Sto32Sx2,
1667ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // No rounding, sat S->U
1668ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQSarNnarrow16Sto8Ux8,
1669ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQSarNnarrow32Sto16Ux4, Iop_QandQSarNnarrow64Sto32Ux2,
1670ecedd989304126b77b8ff91044b8dde0e987c67asewardj
1671ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // Rounding, sat U->U
1672ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRShrNnarrow16Uto8Ux8,
1673ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRShrNnarrow32Uto16Ux4, Iop_QandQRShrNnarrow64Uto32Ux2,
1674ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // Rounding, sat S->S
1675ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRSarNnarrow16Sto8Sx8,
1676ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRSarNnarrow32Sto16Sx4, Iop_QandQRSarNnarrow64Sto32Sx2,
1677ecedd989304126b77b8ff91044b8dde0e987c67asewardj      // Rounding, sat S->U
1678ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRSarNnarrow16Sto8Ux8,
1679ecedd989304126b77b8ff91044b8dde0e987c67asewardj      Iop_QandQRSarNnarrow32Sto16Ux4, Iop_QandQRSarNnarrow64Sto32Ux2,
1680ecedd989304126b77b8ff91044b8dde0e987c67asewardj
16815f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* NARROWING (binary)
16825f438dd73072211989c6d496845bdc9b777ecbecsewardj         -- narrow 2xV128 into 1xV128, hi half from left arg */
1683c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      /* See comments above w.r.t. U vs S issues in saturated narrowing. */
16845f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
16855f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
16865f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
16875f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
168848ae46b56cef87c90638b25d6b2462c475033da8carll      Iop_QNarrowBin64Sto32Sx4, Iop_QNarrowBin64Uto32Ux4,
16890c74bb5aa3240f693df0568d578baabf0c376dc4carll      Iop_NarrowBin64to32x4,
16905f438dd73072211989c6d496845bdc9b777ecbecsewardj
16915f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* NARROWING (unary) -- narrow V128 into I64 */
16925f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
16938b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj      /* Saturating narrowing from signed source to signed/unsigned
16948b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj         destination */
16955f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
16965f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
16975f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* Saturating narrowing from unsigned source to unsigned destination */
16985f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
16995f438dd73072211989c6d496845bdc9b777ecbecsewardj
17005f438dd73072211989c6d496845bdc9b777ecbecsewardj      /* WIDENING -- sign or zero extend each element of the argument
17015f438dd73072211989c6d496845bdc9b777ecbecsewardj         vector to the twice original size.  The resulting vector consists of
17022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         the same number of elements but each element and the vector itself
17035f438dd73072211989c6d496845bdc9b777ecbecsewardj         are twice as wide.
17042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         All operations are I64->V128.
17052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         Example
17065f438dd73072211989c6d496845bdc9b777ecbecsewardj            Iop_Widen32Sto64x2( [a, b] ) = [c, d]
17072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj               where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
17085f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
17095f438dd73072211989c6d496845bdc9b777ecbecsewardj      Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
17102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
17112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* INTERLEAVING */
17122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Interleave lanes from low or high halves of
1713164f9275c465cd09ecd09276b8542282f5def250sewardj         operands.  Most-significant result lane is from the left
1714164f9275c465cd09ecd09276b8542282f5def250sewardj         arg. */
1715164f9275c465cd09ecd09276b8542282f5def250sewardj      Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1716164f9275c465cd09ecd09276b8542282f5def250sewardj      Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
17172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
1718f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
17192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Interleave odd/even lanes of operands.  Most-significant result lane
17202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         is from the left arg. */
17212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
17222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
17232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
17242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
17252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* CONCATENATION -- build a new value by concatenating either
1726487559e1a0215d7703d4286d396db9ec651803afsewardj         the even or odd lanes of both operands.  Note that
1727487559e1a0215d7703d4286d396db9ec651803afsewardj         Cat{Odd,Even}Lanes64x2 are identical to Interleave{HI,LO}64x2
1728487559e1a0215d7703d4286d396db9ec651803afsewardj         and so are omitted. */
17292fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
17302fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
17312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
17322fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* GET elements of VECTOR
17332fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj         GET is binop (V128, I8) -> I<elem_size> */
17342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Note: the arm back-end handles only constant second argument. */
17352fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
1736f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion
1737f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      /* DUPLICATING -- copy value to all lanes */
17382fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Dup8x16,   Iop_Dup16x8,   Iop_Dup32x4,
17392fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1740e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj      /* SLICE -- produces the lowest 128 bits of (arg1:arg2) >> (8 * arg3).
1741e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         arg3 is a shift amount in bytes and may be between 0 and 16
1742e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         inclusive.  When 0, the result is arg2; when 16, the result is arg1.
1743e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         Not all back ends handle all values.  The arm64 back
1744e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj         end handles only immediate arg3 values. */
1745e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj      Iop_SliceV128,  // (V128, V128, I8) -> V128
17462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1747336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      /* REVERSE the order of chunks in vector lanes.  Chunks must be
1748336803528188cd4fe8b4fcfa7c48ca1056811046sewardj         smaller than the vector lanes (obviously) and so may be 8-,
1749336803528188cd4fe8b4fcfa7c48ca1056811046sewardj         16- and 32-bit in size.  See definitions of 64-bit SIMD
1750336803528188cd4fe8b4fcfa7c48ca1056811046sewardj         versions above for examples. */
1751336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn16_x8,
1752336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
1753336803528188cd4fe8b4fcfa7c48ca1056811046sewardj      Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
1754715d162596c384614565879bf8d1b44bb9901d5bsewardj      Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
1755f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion
1756f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion      /* PERMUTING -- copy src bytes to dst,
1757dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         as indexed by control vector bytes:
1758dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj            for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1759dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         argR[i] values may only be in the range 0 .. 15, else behaviour
1760dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         is undefined. */
17612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      Iop_Perm8x16,
1762d8bca7e48c8b3ad028878ab501197ba701df43e5sewardj      Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
17632fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
176478a20592024c096430f630006412fec063568bfdsewardj      /* MISC CONVERSION -- get high bits of each byte lane, a la
176578a20592024c096430f630006412fec063568bfdsewardj         x86/amd64 pmovmskb */
17660e7d2803a32270fc2dcb4737c29b7a4a3d550f85sewardj      Iop_GetMSBs8x16, /* V128 -> I16 */
176778a20592024c096430f630006412fec063568bfdsewardj
17682fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj      /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
17691ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj         See floating-point equivalents for details. */
17701ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32Ux4, Iop_RSqrtEst32Ux4,
1771c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj
1772c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      /* ------------------ 256-bit SIMD Integer. ------------------ */
1773c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj
1774c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      /* Pack/unpack */
17754b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_V256to64_0,  // V256 -> I64, extract least significant lane
1776c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      Iop_V256to64_1,
1777c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj      Iop_V256to64_2,
17784b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_V256to64_3,  // V256 -> I64, extract most significant lane
1779c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj
178056c30311864565c853457b4398d96588cdf141fdsewardj      Iop_64x4toV256,  // (I64,I64,I64,I64)->V256
1781c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj                       // first arg is most significant lane
178256c30311864565c853457b4398d96588cdf141fdsewardj
17834b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_V256toV128_0, // V256 -> V128, less significant lane
17844b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_V256toV128_1, // V256 -> V128, more significant lane
17854b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
17864b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj
17874b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_AndV256,
17882a2bda92787a9daef62737e54f3a1752920a0ecfsewardj      Iop_OrV256,
17894b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj      Iop_XorV256,
17902a2bda92787a9daef62737e54f3a1752920a0ecfsewardj      Iop_NotV256,
17914b1cc83949a6a6aa05ad24420f6b64a82f7a7857sewardj
179223db8a0f3aadf513afc9e7bb8bbde5634fc84137sewardj      /* MISC (vector integer cmp != 0) */
1793cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1794cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1795cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Add8x32,    Iop_Add16x16,    Iop_Add32x8,    Iop_Add64x4,
1796cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Sub8x32,    Iop_Sub16x16,    Iop_Sub32x8,    Iop_Sub64x4,
1797cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1798cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_CmpEQ8x32,  Iop_CmpEQ16x16,  Iop_CmpEQ32x8,  Iop_CmpEQ64x4,
1799cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4,
1800cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1801cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4,
1802cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4,
1803cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_SarN16x16, Iop_SarN32x8,
1804cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1805cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8,
1806cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8,
1807cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8,
1808cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8,
1809cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1810cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Mul16x16, Iop_Mul32x8,
1811cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_MulHi16Ux16, Iop_MulHi16Sx16,
1812cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1813cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_QAdd8Ux32, Iop_QAdd16Ux16,
1814cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_QAdd8Sx32, Iop_QAdd16Sx16,
1815cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_QSub8Ux32, Iop_QSub16Ux16,
1816cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_QSub8Sx32, Iop_QSub16Sx16,
1817cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1818cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Avg8Ux32, Iop_Avg16Ux16,
1819cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj
1820cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      Iop_Perm32x8,
182123db8a0f3aadf513afc9e7bb8bbde5634fc84137sewardj
18227deaf9552b546b847528cf39b38898fb7742b5f5carll      /* (V128, V128) -> V128 */
18237deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_CipherV128, Iop_CipherLV128, Iop_CipherSV128,
18247deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_NCipherV128, Iop_NCipherLV128,
18257deaf9552b546b847528cf39b38898fb7742b5f5carll
18267deaf9552b546b847528cf39b38898fb7742b5f5carll      /* Hash instructions, Federal Information Processing Standards
18277deaf9552b546b847528cf39b38898fb7742b5f5carll       * Publication 180-3 Secure Hash Standard. */
18287deaf9552b546b847528cf39b38898fb7742b5f5carll      /* (V128, I8) -> V128; The I8 input arg is (ST | SIX), where ST and
18297deaf9552b546b847528cf39b38898fb7742b5f5carll       * SIX are fields from the insn. See ISA 2.07 description of
18307deaf9552b546b847528cf39b38898fb7742b5f5carll       * vshasigmad and vshasigmaw insns.*/
18317deaf9552b546b847528cf39b38898fb7742b5f5carll      Iop_SHA512, Iop_SHA256,
18327deaf9552b546b847528cf39b38898fb7742b5f5carll
183356c30311864565c853457b4398d96588cdf141fdsewardj      /* ------------------ 256-bit SIMD FP. ------------------ */
18349571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj
18359571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      /* ternary :: IRRoundingMode(I32) x V256 x V256 -> V256 */
18369571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      Iop_Add64Fx4, Iop_Sub64Fx4, Iop_Mul64Fx4, Iop_Div64Fx4,
18379571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj      Iop_Add32Fx8, Iop_Sub32Fx8, Iop_Mul32Fx8, Iop_Div32Fx8,
1838f0ad4f8bb1aebe9724b7170e1478613984521b76sewardj
1839f0ad4f8bb1aebe9724b7170e1478613984521b76sewardj      Iop_Sqrt32Fx8,
1840f0ad4f8bb1aebe9724b7170e1478613984521b76sewardj      Iop_Sqrt64Fx4,
18411ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RSqrtEst32Fx8,
18421ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      Iop_RecipEst32Fx8,
18438eb7ae8df9e152f0f99d1abbc68f2fee77ac2d04sewardj
18448eb7ae8df9e152f0f99d1abbc68f2fee77ac2d04sewardj      Iop_Max32Fx8, Iop_Min32Fx8,
18452245ce9e834193d49261b8a433b4a0bd128c878eflorian      Iop_Max64Fx4, Iop_Min64Fx4,
18462245ce9e834193d49261b8a433b4a0bd128c878eflorian      Iop_LAST      /* must be the last enumerator */
1847ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   }
1848ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   IROp;
1849ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
185057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an op. */
185135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardjextern void ppIROp ( IROp );
1852ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
18532074a4426f436cce67b2622f972bd6e2fd87a55fflorian/* For a given operand return the types of its arguments and its result. */
18542074a4426f436cce67b2622f972bd6e2fd87a55fflorianextern void typeOfPrimop ( IROp op,
18552074a4426f436cce67b2622f972bd6e2fd87a55fflorian                           /*OUTs*/ IRType* t_dst, IRType* t_arg1,
18562074a4426f436cce67b2622f972bd6e2fd87a55fflorian                           IRType* t_arg2, IRType* t_arg3, IRType* t_arg4 );
1857e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
185879e5a4845df6d09250b142c4e160a95cf7688fc8florian/* Encoding of IEEE754-specified rounding modes.
1859f1b5b1a3c39f248c6634c78619971ac41d0a9726sewardj   Note, various front and back ends rely on the actual numerical
1860f1b5b1a3c39f248c6634c78619971ac41d0a9726sewardj   values of these, so do not change them. */
1861c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardjtypedef
1862f1b5b1a3c39f248c6634c78619971ac41d0a9726sewardj   enum {
186379e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_NEAREST              = 0,  // Round to nearest, ties to even
186479e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_NegINF               = 1,  // Round to negative infinity
186579e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_PosINF               = 2,  // Round to positive infinity
186679e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_ZERO                 = 3,  // Round toward zero
186779e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_NEAREST_TIE_AWAY_0   = 4,  // Round to nearest, ties away from 0
1868bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      Irrm_PREPARE_SHORTER      = 5,  // Round to prepare for shorter
186979e5a4845df6d09250b142c4e160a95cf7688fc8florian                                      // precision
187079e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_AWAY_FROM_ZERO       = 6,  // Round to away from 0
187179e5a4845df6d09250b142c4e160a95cf7688fc8florian      Irrm_NEAREST_TIE_TOWARD_0 = 7   // Round to nearest, ties towards 0
1872f1b5b1a3c39f248c6634c78619971ac41d0a9726sewardj   }
1873c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj   IRRoundingMode;
1874c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj
1875daa4084cffd771efef294a484e64868f3eeeb0e4florian/* Binary floating point comparison result values.
1876c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj   This is also derived from what IA32 does. */
1877c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardjtypedef
1878c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj   enum {
1879c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj      Ircr_UN = 0x45,
1880c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj      Ircr_LT = 0x01,
1881c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj      Ircr_GT = 0x00,
1882c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj      Ircr_EQ = 0x40
1883c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj   }
1884daa4084cffd771efef294a484e64868f3eeeb0e4florian   IRCmpFResult;
1885c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj
1886daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpFResult IRCmpF32Result;
1887daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpFResult IRCmpF64Result;
1888daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpFResult IRCmpF128Result;
1889daa4084cffd771efef294a484e64868f3eeeb0e4florian
1890daa4084cffd771efef294a484e64868f3eeeb0e4florian/* Decimal floating point result values. */
1891daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpFResult IRCmpDResult;
1892daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpDResult IRCmpD64Result;
1893daa4084cffd771efef294a484e64868f3eeeb0e4floriantypedef IRCmpDResult IRCmpD128Result;
1894c9868d7a6cdf51c3c23365d3b3bd4af5e80d30e1sewardj
1895c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* ------------------ Expressions ------------------ */
1896b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
1897eadea2e722b843fe0c5d15834fb59a5c723fc21ffloriantypedef struct _IRQop   IRQop;   /* forward declaration */
1898eadea2e722b843fe0c5d15834fb59a5c723fc21ffloriantypedef struct _IRTriop IRTriop; /* forward declaration */
189996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian
190096d7cc3e7d54ad5af2af2821223b21f9a8516a59florian
190157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* The different kinds of expressions.  Their meaning is explained below
190257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   in the comments for IRExpr. */
190357c10c89904f7fdc4244fcbf704625e7169aafe6sewardjtypedef
190457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   enum {
1905cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Iex_Binder=0x1900,
190657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Get,
190757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_GetI,
1908dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      Iex_RdTmp,
190957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Qop,
191057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Triop,
191157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Binop,
191257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Unop,
191357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Load,
191457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Iex_Const,
191599dd03e04a6914d90d5fee727d61d76905334becflorian      Iex_ITE,
19169041956f39c57e265122ed0a71061dea1e554edcflorian      Iex_CCall,
19179041956f39c57e265122ed0a71061dea1e554edcflorian      Iex_VECRET,
19189041956f39c57e265122ed0a71061dea1e554edcflorian      Iex_BBPTR
191957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   }
192057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRExprTag;
1921b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
192257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* An expression.  Stored as a tagged union.  'tag' indicates what kind
192357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   of expression this is.  'Iex' is the union that holds the fields.  If
192457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
192557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   expression, and the fields can be accessed with
192657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   'e.Iex.Load.<fieldname>'.
1927b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
192857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   For each kind of expression, we show what it looks like when
192957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   pretty-printed with ppIRExpr().
193057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
193157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjtypedef
193257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   struct _IRExpr
193357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRExpr;
19345ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
193557c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstruct _IRExpr {
193657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRExprTag tag;
193757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   union {
193857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* Used only in pattern matching within Vex.  Should not be seen
193957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         outside of Vex. */
194057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
194157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         Int binder;
194257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Binder;
19435ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
194457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* Read a guest register, at a fixed offset in the guest state.
194557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
194657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
194757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
194857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         Int    offset;    /* Offset into the guest state */
194957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRType ty;        /* Type of the value being read */
195057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Get;
19515ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
195257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* Read a guest register at a non-fixed offset in the guest
195357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         state.  This allows circular indexing into parts of the guest
195457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         state, which is essential for modelling situations where the
195557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         identity of guest registers is not known until run time.  One
195657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         example is the x87 FP register stack.
19575ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
195857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         The part of the guest state to be treated as a circular array
1959dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         is described in the IRRegArray 'descr' field.  It holds the
196057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         offset of the first element in the array, the type of each
196157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         element, and the number of elements.
19625ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
196357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         The array index is indicated rather indirectly, in a way
196457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         which makes optimisation easy: as the sum of variable part
196557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         (the 'ix' field) and a constant offset (the 'bias' field).
1966b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
196757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         Since the indexing is circular, the actual array index to use
196857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         is computed as (ix + bias) % num-of-elems-in-the-array.
1969b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
197057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         Here's an example.  The description
1971b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
197257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            (96:8xF64)[t39,-7]
1973b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
197457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         describes an array of 8 F64-typed values, the
197557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         guest-state-offset of the first being 96.  This array is
197657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         being indexed at (t39 - 7) % 8.
1977b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
197857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         It is important to get the array size/type exactly correct
197957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         since IR optimisation looks closely at such info in order to
198057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         establish aliasing/non-aliasing between seperate GetI and
198157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         PutI events, which is used to establish when they can be
198257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         reordered, etc.  Putting incorrect info in will lead to
198357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         obscure IR optimisation bugs.
1984b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
198557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            ppIRExpr output: GETI<descr>[<ix>,<bias]
198657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                         eg. GETI(128:8xI8)[t1,0]
198757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
198857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
1989dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         IRRegArray* descr; /* Part of guest state treated as circular */
1990dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         IRExpr*     ix;    /* Variable part of index into array */
1991dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         Int         bias;  /* Constant offset part of index into array */
199257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } GetI;
1993b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
199457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* The value held by a temporary.
199557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: t<tmp>, eg. t1
199657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
199757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
199857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRTemp tmp;       /* The temporary number */
1999dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      } RdTmp;
2000b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
200157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A quaternary operation.
200257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
200357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                      eg. MAddF64r32(t1, t2, t3, t4)
200457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
200557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
200696d7cc3e7d54ad5af2af2821223b21f9a8516a59florian        IRQop* details;
200757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Qop;
200857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
200957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A ternary operation.
201057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
201157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                      eg. MulF64(1, 2.0, 3.0)
201257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
201357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
2014420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian        IRTriop* details;
201557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Triop;
201657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
201757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A binary operation.
201857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
201957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
202057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
202157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IROp op;          /* op-code   */
202257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr* arg1;     /* operand 1 */
202357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr* arg2;     /* operand 2 */
202457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Binop;
2025d1725d18b61bf7912a9099686179faef5815dba1sewardj
202657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A unary operation.
202757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
202857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
202957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
203057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IROp    op;       /* op-code */
203157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr* arg;      /* operand */
203257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Unop;
2033e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
2034e768e92e054cde495849a5c842a477d287677f78sewardj      /* A load from memory -- a normal load, not a load-linked.
2035e768e92e054cde495849a5c842a477d287677f78sewardj         Load-Linkeds (and Store-Conditionals) are instead represented
2036e768e92e054cde495849a5c842a477d287677f78sewardj         by IRStmt.LLSC since Load-Linkeds have side effects and so
2037e768e92e054cde495849a5c842a477d287677f78sewardj         are not semantically valid IRExpr's.
203857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
203957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
204057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
204157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IREndness end;    /* Endian-ness of the load */
204257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRType    ty;     /* Type of the loaded value */
204357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr*   addr;   /* Address being loaded from */
204457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Load;
204557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
204657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A constant-valued expression.
204757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <con>, eg. 0x4:I32
204857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
204957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
205057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRConst* con;     /* The constant itself */
205157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      } Const;
205257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
205357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      /* A call to a pure (no side-effects) helper C function.
205457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
205557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         With the 'cee' field, 'name' is the function's name.  It is
205657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         only used for pretty-printing purposes.  The address to call
205757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         (host address, of course) is stored in the 'addr' field
205857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         inside 'cee'.
205957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
206057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         The 'args' field is a NULL-terminated array of arguments.
206157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         The stated return IRType, and the implied argument types,
206257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         must match that of the function being called well enough so
206357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         that the back end can actually generate correct code for the
206457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         call.
2065e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
206657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         The called function **must** satisfy the following:
206757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
206857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         * no side effects -- must be a pure function, the result of
206957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj           which depends only on the passed parameters.
207057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
207157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         * it may not look at, nor modify, any of the guest state
207257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj           since that would hide guest state transitions from
207357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj           instrumenters
207457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
207557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         * it may not access guest memory, since that would hide
207657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj           guest memory transactions from the instrumenters
207757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
207852af7bc8eb1ac161983e66b97a88f6f78a4e3942florian         * it must not assume that arguments are being evaluated in a
207952af7bc8eb1ac161983e66b97a88f6f78a4e3942florian           particular order. The oder of evaluation is unspecified.
208052af7bc8eb1ac161983e66b97a88f6f78a4e3942florian
208157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         This is restrictive, but makes the semantics clean, and does
208257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         not interfere with IR optimisation.
208357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
208457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         If you want to call a helper which can mess with guest state
208557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         and/or memory, instead use Ist_Dirty.  This is a lot more
208657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         flexible, but you have to give a bunch of details about what
208757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         the helper does (and you better be telling the truth,
208857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         otherwise any derived instrumentation will be wrong).  Also
208957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         Ist_Dirty inhibits various IR optimisations and so can cause
209057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         quite poor code to be generated.  Try to avoid it.
209157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
209274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         In principle it would be allowable to have the arg vector
20939041956f39c57e265122ed0a71061dea1e554edcflorian         contain an IRExpr_VECRET(), although not IRExpr_BBPTR(). However,
20949041956f39c57e265122ed0a71061dea1e554edcflorian         at the moment there is no requirement for clean helper calls to
20959041956f39c57e265122ed0a71061dea1e554edcflorian         be able to return V128 or V256 values.  Hence this is not allowed.
209674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
209757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         ppIRExpr output: <cee>(<args>):<retty>
209857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                      eg. foo{0x80489304}(t1, t2):I32
209957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
210057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
210157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRCallee* cee;    /* Function to call. */
210257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRType    retty;  /* Type of return value. */
210357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr**  args;   /* Vector of argument expressions. */
210457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      }  CCall;
210557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
210699dd03e04a6914d90d5fee727d61d76905334becflorian      /* A ternary if-then-else operator.  It returns iftrue if cond is
210799dd03e04a6914d90d5fee727d61d76905334becflorian         nonzero, iffalse otherwise.  Note that it is STRICT, ie. both
210899dd03e04a6914d90d5fee727d61d76905334becflorian         iftrue and iffalse are evaluated in all cases.
210957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
211099dd03e04a6914d90d5fee727d61d76905334becflorian         ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>),
211199dd03e04a6914d90d5fee727d61d76905334becflorian                         eg. ITE(t6,t7,t8)
211257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      */
211357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      struct {
211457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         IRExpr* cond;     /* Condition */
211599dd03e04a6914d90d5fee727d61d76905334becflorian         IRExpr* iftrue;   /* True expression */
211699dd03e04a6914d90d5fee727d61d76905334becflorian         IRExpr* iffalse;  /* False expression */
211799dd03e04a6914d90d5fee727d61d76905334becflorian      } ITE;
211857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   } Iex;
211957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj};
212057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2121cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* Expression auxiliaries: a ternary expression. */
2122420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florianstruct _IRTriop {
2123420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian   IROp op;          /* op-code   */
2124420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian   IRExpr* arg1;     /* operand 1 */
2125420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian   IRExpr* arg2;     /* operand 2 */
2126420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian   IRExpr* arg3;     /* operand 3 */
2127420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian};
2128420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian
2129cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* Expression auxiliaries: a quarternary expression. */
213096d7cc3e7d54ad5af2af2821223b21f9a8516a59florianstruct _IRQop {
213196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian   IROp op;          /* op-code   */
213296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian   IRExpr* arg1;     /* operand 1 */
213396d7cc3e7d54ad5af2af2821223b21f9a8516a59florian   IRExpr* arg2;     /* operand 2 */
213496d7cc3e7d54ad5af2af2821223b21f9a8516a59florian   IRExpr* arg3;     /* operand 3 */
213596d7cc3e7d54ad5af2af2821223b21f9a8516a59florian   IRExpr* arg4;     /* operand 4 */
213696d7cc3e7d54ad5af2af2821223b21f9a8516a59florian};
213796d7cc3e7d54ad5af2af2821223b21f9a8516a59florian
213874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
21399041956f39c57e265122ed0a71061dea1e554edcflorian/* Two special kinds of IRExpr, which can ONLY be used in
214074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   argument lists for dirty helper calls (IRDirty.args) and in NO
21419041956f39c57e265122ed0a71061dea1e554edcflorian   OTHER PLACES.  And then only in very limited ways.  */
214274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
214374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj/* Denotes an argument which (in the helper) takes a pointer to a
214474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   (naturally aligned) V128 or V256, into which the helper is expected
21459041956f39c57e265122ed0a71061dea1e554edcflorian   to write its result.  Use of IRExpr_VECRET() is strictly
214674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   controlled.  If the helper returns a V128 or V256 value then
21479041956f39c57e265122ed0a71061dea1e554edcflorian   IRExpr_VECRET() must appear exactly once in the arg list, although
214874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   it can appear anywhere, and the helper must have a C 'void' return
21499041956f39c57e265122ed0a71061dea1e554edcflorian   type.  If the helper returns any other type, IRExpr_VECRET() may
215074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   not appear in the argument list. */
215174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
215274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj/* Denotes an void* argument which is passed to the helper, which at
215374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   run time will point to the thread's guest state area.  This can
215474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   only appear at most once in an argument list, and it may not appear
215574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   at all in argument lists for clean helper calls. */
215674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
21570b70efae27eafd60bc7ea9a3955605d55a681651florianstatic inline Bool is_IRExpr_VECRET_or_BBPTR ( const IRExpr* e ) {
21589041956f39c57e265122ed0a71061dea1e554edcflorian   return e->tag == Iex_VECRET || e->tag == Iex_BBPTR;
215974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj}
216074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
216174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
216257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Expression constructors. */
2163443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardjextern IRExpr* IRExpr_Binder ( Int binder );
2164443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardjextern IRExpr* IRExpr_Get    ( Int off, IRType ty );
2165dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRExpr* IRExpr_GetI   ( IRRegArray* descr, IRExpr* ix, Int bias );
2166dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRExpr* IRExpr_RdTmp  ( IRTemp tmp );
216740c802659108a96bb87cbc1a30b7b77e2abd0829sewardjextern IRExpr* IRExpr_Qop    ( IROp op, IRExpr* arg1, IRExpr* arg2,
216840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj                                        IRExpr* arg3, IRExpr* arg4 );
2169b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjextern IRExpr* IRExpr_Triop  ( IROp op, IRExpr* arg1,
2170b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                        IRExpr* arg2, IRExpr* arg3 );
2171443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardjextern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
2172443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardjextern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
2173e768e92e054cde495849a5c842a477d287677f78sewardjextern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
2174443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardjextern IRExpr* IRExpr_Const  ( IRConst* con );
21758ea867b06de73d909c29e243407713c291c8414esewardjextern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
217699dd03e04a6914d90d5fee727d61d76905334becflorianextern IRExpr* IRExpr_ITE    ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse );
21779041956f39c57e265122ed0a71061dea1e554edcflorianextern IRExpr* IRExpr_VECRET ( void );
21789041956f39c57e265122ed0a71061dea1e554edcflorianextern IRExpr* IRExpr_BBPTR  ( void );
2179c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
218057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy an IRExpr. */
21810b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRExpr* deepCopyIRExpr ( const IRExpr* );
2182695cff9303ef5dc8079117acfd632b44edb1f010sewardj
218357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRExpr. */
21840b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRExpr ( const IRExpr* );
2185e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
218657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* NULL-terminated IRExpr vector constructors, suitable for
218757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   use as arg lists in clean/dirty helper calls. */
2188c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardjextern IRExpr** mkIRExprVec_0 ( void );
2189f96552617c82834ece36184e674e249faa899b2fsewardjextern IRExpr** mkIRExprVec_1 ( IRExpr* );
2190f96552617c82834ece36184e674e249faa899b2fsewardjextern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
2191f96552617c82834ece36184e674e249faa899b2fsewardjextern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
2192f96552617c82834ece36184e674e249faa899b2fsewardjextern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
219378ec32b319ab7b3b82711d9e8b58bc10ee6fe366sewardjextern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
219478ec32b319ab7b3b82711d9e8b58bc10ee6fe366sewardj                                IRExpr* );
219578ec32b319ab7b3b82711d9e8b58bc10ee6fe366sewardjextern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
219678ec32b319ab7b3b82711d9e8b58bc10ee6fe366sewardj                                IRExpr*, IRExpr* );
219778ec32b319ab7b3b82711d9e8b58bc10ee6fe366sewardjextern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2198f32c67d5eab8bcc5762ce67801f88b55c8f1cd05sewardj                                IRExpr*, IRExpr*, IRExpr* );
21992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjextern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
22002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                IRExpr*, IRExpr*, IRExpr*, IRExpr*);
2201c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj
220257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* IRExpr copiers:
2203dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   - shallowCopy: shallow-copy (ie. create a new vector that shares the
220457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     elements with the original).
2205dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   - deepCopy: deep-copy (ie. create a completely new vector). */
2206dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRExpr** shallowCopyIRExprVec ( IRExpr** );
22070b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRExpr** deepCopyIRExprVec ( IRExpr *const * );
2208c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj
2209f96552617c82834ece36184e674e249faa899b2fsewardj/* Make a constant expression from the given host word taking into
221057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   account (of course) the host word size. */
221149651f4b59b1ab7e0e70cccd34001630eafbe957sewardjextern IRExpr* mkIRExpr_HWord ( HWord );
221249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
2213f96552617c82834ece36184e674e249faa899b2fsewardj/* Convenience function for constructing clean helper calls. */
2214f96552617c82834ece36184e674e249faa899b2fsewardjextern
2215f96552617c82834ece36184e674e249faa899b2fsewardjIRExpr* mkIRExprCCall ( IRType retty,
22161ff4756e1731485e6bf3cd96717cd8398daec1f2florian                        Int regparms, const HChar* name, void* addr,
2217f96552617c82834ece36184e674e249faa899b2fsewardj                        IRExpr** args );
2218f96552617c82834ece36184e674e249faa899b2fsewardj
221949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
222057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
222157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * Iex_Const). */
22220b70efae27eafd60bc7ea9a3955605d55a681651florianstatic inline Bool isIRAtom ( const IRExpr* e ) {
2223dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
222449651f4b59b1ab7e0e70cccd34001630eafbe957sewardj}
222549651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
2226496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj/* Are these two IR atoms identical?  Causes an assertion
2227496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj   failure if they are passed non-atoms. */
22280b70efae27eafd60bc7ea9a3955605d55a681651florianextern Bool eqIRAtom ( const IRExpr*, const IRExpr* );
2229496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
2230e87b4840dc364d8203ccd3d6eeda348695cb4b8asewardj
2231893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* ------------------ Jump kinds ------------------ */
2232893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
2233893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* This describes hints which can be passed to the dispatcher at guest
2234893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   control-flow transfer points.
22357ce9d15f4208aa08dfb1e605b3cad53ff03a84e4sewardj
223605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   Re Ijk_InvalICache and Ijk_FlushDCache: the guest state _must_ have
223705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   two pseudo-registers, guest_CMSTART and guest_CMLEN, which specify
223805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   the start and length of the region to be invalidated.  CM stands
223905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   for "Cache Management".  These are both the size of a guest word.
224005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   It is the responsibility of the relevant toIR.c to ensure that
224105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   these are filled in with suitable values before issuing a jump of
224205f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   kind Ijk_InvalICache or Ijk_FlushDCache.
224305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj
224405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   Ijk_InvalICache requests invalidation of translations taken from
224505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   the requested range.  Ijk_FlushDCache requests flushing of the D
224605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   cache for the specified range.
224765902992da28822e4753594c7b72f7cb177fe3a6sewardj
22489dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj   Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
22496ef84bed9bb3af22060eb1759788034602bbcc88florian   pseudo-register guest_EMNOTE, which is 32-bits regardless of the
22506ef84bed9bb3af22060eb1759788034602bbcc88florian   host or guest word size.  That register should be made to hold a
22516ef84bed9bb3af22060eb1759788034602bbcc88florian   VexEmNote value to indicate the reason for the exit.
22529dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj
22539dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj   In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
22549dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj   cannot continue) and so the jump destination can be anything.
2255e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj
2256e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   Re Ijk_Sys_ (syscall jumps): the guest state must have a
2257e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
2258e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   word.  Front ends should set this to be the IP at the most recently
2259e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   executed kernel-entering (system call) instruction.  This makes it
2260e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   very much easier (viz, actually possible at all) to back up the
2261e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   guest to restart a syscall that has been interrupted by a signal.
2262893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj*/
2263893aadad7f29f7801ce26cb7575c16e90bd3767fsewardjtypedef
2264c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   enum {
2265cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ijk_INVALID=0x1A00,
2266c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      Ijk_Boring,         /* not interesting; just goto next */
2267893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj      Ijk_Call,           /* guest is doing a call */
2268893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj      Ijk_Ret,            /* guest is doing a return */
2269893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj      Ijk_ClientReq,      /* do guest client req before continuing */
2270893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj      Ijk_Yield,          /* client is yielding to thread scheduler */
227152444cb6696efd612ced78daa8feb235808ef165sewardj      Ijk_EmWarn,         /* report emulation warning before continuing */
22729dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj      Ijk_EmFail,         /* emulation critical (FATAL) error; give up */
22730b3900824b37b39c77c04cad9b4208d6e32c4c92florian      Ijk_NoDecode,       /* current instruction cannot be decoded */
22747ce9d15f4208aa08dfb1e605b3cad53ff03a84e4sewardj      Ijk_MapFail,        /* Vex-provided address translation failed */
227505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj      Ijk_InvalICache,    /* Inval icache for range [CMSTART, +CMLEN) */
227605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj      Ijk_FlushDCache,    /* Flush dcache for range [CMSTART, +CMLEN) */
2277ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj      Ijk_NoRedir,        /* Jump to un-redirected guest addr */
22780e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj      Ijk_SigILL,         /* current instruction synths SIGILL */
22790f50004eefdf1066682a016efb4a57c092ae2da2sewardj      Ijk_SigTRAP,        /* current instruction synths SIGTRAP */
22800f50004eefdf1066682a016efb4a57c092ae2da2sewardj      Ijk_SigSEGV,        /* current instruction synths SIGSEGV */
2281e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      Ijk_SigBUS,         /* current instruction synths SIGBUS */
2282a6a1986ba221f6c827662b57a7e4ef8206093475petarj      Ijk_SigFPE_IntDiv,  /* current instruction synths SIGFPE - IntDiv */
2283a6a1986ba221f6c827662b57a7e4ef8206093475petarj      Ijk_SigFPE_IntOvf,  /* current instruction synths SIGFPE - IntOvf */
22844fa325af3891d57d174a025af2e6e8810a553660sewardj      /* Unfortunately, various guest-dependent syscall kinds.  They
22854fa325af3891d57d174a025af2e6e8810a553660sewardj	 all mean: do a syscall before continuing. */
2286f0bb67912ae5b4f5e08f20d28b2c49f279eec2d6tom      Ijk_Sys_syscall,    /* amd64/x86 'syscall', ppc 'sc', arm 'svc #0' */
22874fa325af3891d57d174a025af2e6e8810a553660sewardj      Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
22884fa325af3891d57d174a025af2e6e8810a553660sewardj      Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
2289d660d41d4174e44f284bad3264601662ed68d4a1sewardj      Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
2290d660d41d4174e44f284bad3264601662ed68d4a1sewardj      Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
22913e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj      Ijk_Sys_int145,     /* amd64/x86 'int $0x91' */
22923e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj      Ijk_Sys_int210,     /* amd64/x86 'int $0xD2' */
22934fa325af3891d57d174a025af2e6e8810a553660sewardj      Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes
22944fa325af3891d57d174a025af2e6e8810a553660sewardj                             invalid at the point this happens. */
2295893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   }
2296893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   IRJumpKind;
2297893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
2298893aadad7f29f7801ce26cb7575c16e90bd3767fsewardjextern void ppIRJumpKind ( IRJumpKind );
2299893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
2300893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
2301b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj/* ------------------ Dirty helper calls ------------------ */
2302b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
230357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* A dirty call is a flexible mechanism for calling (possibly
230457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   conditionally) a helper function or procedure.  The helper function
230557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   may read, write or modify client memory, and may read, write or
230657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   modify client state.  It can take arguments and optionally return a
230757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   value.  It may return different results and/or do different things
230857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   when called repeatedly with the same arguments, by means of storing
230957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   private state.
2310b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2311c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   If a value is returned, it is assigned to the nominated return
2312c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   temporary.
2313b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2314b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   Dirty calls are statements rather than expressions for obvious
231557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   reasons.  If a dirty call is marked as writing guest state, any
2316cfe046e178666280b87da998b1b52ecda03ecd89sewardj   pre-existing values derived from the written parts of the guest
2317cfe046e178666280b87da998b1b52ecda03ecd89sewardj   state are invalid.  Similarly, if the dirty call is stated as
2318cfe046e178666280b87da998b1b52ecda03ecd89sewardj   writing memory, any pre-existing loaded values are invalidated by
2319cfe046e178666280b87da998b1b52ecda03ecd89sewardj   it.
2320b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2321b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   In order that instrumentation is possible, the call must state, and
232257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   state correctly:
2323b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2324cfe046e178666280b87da998b1b52ecda03ecd89sewardj   * Whether it reads, writes or modifies memory, and if so where.
2325b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2326cfe046e178666280b87da998b1b52ecda03ecd89sewardj   * Whether it reads, writes or modifies guest state, and if so which
2327cfe046e178666280b87da998b1b52ecda03ecd89sewardj     pieces.  Several pieces may be stated, and their extents must be
2328cfe046e178666280b87da998b1b52ecda03ecd89sewardj     known at translation-time.  Each piece is allowed to repeat some
2329cfe046e178666280b87da998b1b52ecda03ecd89sewardj     number of times at a fixed interval, if required.
2330c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj
2331c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   Normally, code is generated to pass just the args to the helper.
23329041956f39c57e265122ed0a71061dea1e554edcflorian   However, if IRExpr_BBPTR() is present in the argument list (at most
233374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   one instance is allowed), then the baseblock pointer is passed for
233474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   that arg, so that the callee can access the guest state.  It is
23359041956f39c57e265122ed0a71061dea1e554edcflorian   invalid for .nFxState to be zero but IRExpr_BBPTR() to be present,
233674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   since .nFxState==0 is a claim that the call does not access guest
233774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   state.
2338b8385d891bddf9016250435f47c06ac44ec921bfsewardj
2339b8385d891bddf9016250435f47c06ac44ec921bfsewardj   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
2340cfe046e178666280b87da998b1b52ecda03ecd89sewardj   arguments and 'mFx' are evaluated REGARDLESS of the guard value.
2341cfe046e178666280b87da998b1b52ecda03ecd89sewardj   The order of argument evaluation is unspecified.  The guard
2342cfe046e178666280b87da998b1b52ecda03ecd89sewardj   expression is evaluated AFTER the arguments and 'mFx' have been
2343cfe046e178666280b87da998b1b52ecda03ecd89sewardj   evaluated.  'mFx' is expected (by Memcheck) to be a defined value
2344cfe046e178666280b87da998b1b52ecda03ecd89sewardj   even if the guard evaluates to false.
2345b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj*/
2346e87b4840dc364d8203ccd3d6eeda348695cb4b8asewardj
2347a0e83b06f304527e3e9aec527c344e35e7023d76sewardj#define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
2348b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
234957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Effects on resources (eg. registers, memory locations) */
2350b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardjtypedef
2351b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   enum {
2352cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ifx_None=0x1B00,      /* no effect */
235317442fe8094d0f82266e5a05509f62cac8f7539esewardj      Ifx_Read,             /* reads the resource */
235417442fe8094d0f82266e5a05509f62cac8f7539esewardj      Ifx_Write,            /* writes the resource */
235517442fe8094d0f82266e5a05509f62cac8f7539esewardj      Ifx_Modify,           /* modifies the resource */
2356b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   }
2357b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   IREffect;
2358b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
235957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IREffect */
2360b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardjextern void ppIREffect ( IREffect );
2361b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2362b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardjtypedef
2363c9069f2908814843e9a4da00da9c8905440195a6sewardj   struct _IRDirty {
2364f5dfa3b51f89da43897507543cd9a5196ae02edbsewardj      /* What to call, and details of args/results.  .guard must be
2365cfe046e178666280b87da998b1b52ecda03ecd89sewardj         non-NULL.  If .tmp is not IRTemp_INVALID, then the call
2366cfe046e178666280b87da998b1b52ecda03ecd89sewardj         returns a result which is placed in .tmp.  If at runtime the
2367cfe046e178666280b87da998b1b52ecda03ecd89sewardj         guard evaluates to false, .tmp has an 0x555..555 bit pattern
2368cfe046e178666280b87da998b1b52ecda03ecd89sewardj         written to it.  Hence conditional calls that assign .tmp are
2369f5dfa3b51f89da43897507543cd9a5196ae02edbsewardj         allowed. */
23708ea867b06de73d909c29e243407713c291c8414esewardj      IRCallee* cee;    /* where to call */
2371b8385d891bddf9016250435f47c06ac44ec921bfsewardj      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
23729041956f39c57e265122ed0a71061dea1e554edcflorian      /* The args vector may contain IRExpr_BBPTR() and/or
23739041956f39c57e265122ed0a71061dea1e554edcflorian         IRExpr_VECRET(), in both cases, at most once. */
237474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      IRExpr**  args;   /* arg vector, ends in NULL. */
237592d168d0f2a985ed9f7ae4e6bba9565a13921b31sewardj      IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
2376b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2377b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj      /* Mem effects; we allow only one R/W/M region to be stated */
23788ea867b06de73d909c29e243407713c291c8414esewardj      IREffect  mFx;    /* indicates memory effects, if any */
23798ea867b06de73d909c29e243407713c291c8414esewardj      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
23808ea867b06de73d909c29e243407713c291c8414esewardj      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
2381b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
2382b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj      /* Guest state effects; up to N allowed */
2383c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
2384b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj      struct {
2385c9069f2908814843e9a4da00da9c8905440195a6sewardj         IREffect fx:16;   /* read, write or modify?  Ifx_None is invalid. */
2386c9069f2908814843e9a4da00da9c8905440195a6sewardj         UShort   offset;
2387c9069f2908814843e9a4da00da9c8905440195a6sewardj         UShort   size;
2388c9069f2908814843e9a4da00da9c8905440195a6sewardj         UChar    nRepeats;
2389c9069f2908814843e9a4da00da9c8905440195a6sewardj         UChar    repeatLen;
2390b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj      } fxState[VEX_N_FXSTATE];
2391c9069f2908814843e9a4da00da9c8905440195a6sewardj      /* The access can be repeated, as specified by nRepeats and
2392c9069f2908814843e9a4da00da9c8905440195a6sewardj         repeatLen.  To describe only a single access, nRepeats and
2393c9069f2908814843e9a4da00da9c8905440195a6sewardj         repeatLen should be zero.  Otherwise, repeatLen must be a
2394c9069f2908814843e9a4da00da9c8905440195a6sewardj         multiple of size and greater than size. */
2395c9069f2908814843e9a4da00da9c8905440195a6sewardj      /* Overall, the parts of the guest state denoted by (offset,
2396c9069f2908814843e9a4da00da9c8905440195a6sewardj         size, nRepeats, repeatLen) is
2397c9069f2908814843e9a4da00da9c8905440195a6sewardj               [offset, +size)
2398c9069f2908814843e9a4da00da9c8905440195a6sewardj            and, if nRepeats > 0,
2399c9069f2908814843e9a4da00da9c8905440195a6sewardj               for (i = 1; i <= nRepeats; i++)
2400c9069f2908814843e9a4da00da9c8905440195a6sewardj                  [offset + i * repeatLen, +size)
2401c9069f2908814843e9a4da00da9c8905440195a6sewardj         A convenient way to enumerate all segments is therefore
2402c9069f2908814843e9a4da00da9c8905440195a6sewardj            for (i = 0; i < 1 + nRepeats; i++)
2403c9069f2908814843e9a4da00da9c8905440195a6sewardj               [offset + i * repeatLen, +size)
2404c9069f2908814843e9a4da00da9c8905440195a6sewardj      */
2405b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   }
2406b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   IRDirty;
2407b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
240857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print a dirty call */
24090b70efae27eafd60bc7ea9a3955605d55a681651florianextern void     ppIRDirty ( const IRDirty* );
241057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
241157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Allocate an uninitialised dirty call */
2412b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardjextern IRDirty* emptyIRDirty ( void );
2413e87b4840dc364d8203ccd3d6eeda348695cb4b8asewardj
241457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy a dirty call */
24150b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRDirty* deepCopyIRDirty ( const IRDirty* );
2416695cff9303ef5dc8079117acfd632b44edb1f010sewardj
2417c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj/* A handy function which takes some of the tedium out of constructing
2418c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   dirty helper calls.  The called function impliedly does not return
2419b8385d891bddf9016250435f47c06ac44ec921bfsewardj   any value and has a constant-True guard.  The call is marked as
2420b8385d891bddf9016250435f47c06ac44ec921bfsewardj   accessing neither guest state nor memory (hence the "unsafe"
242157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   designation) -- you can change this marking later if need be.  A
2422b8385d891bddf9016250435f47c06ac44ec921bfsewardj   suitable IRCallee is constructed from the supplied bits. */
2423f96552617c82834ece36184e674e249faa899b2fsewardjextern
24241ff4756e1731485e6bf3cd96717cd8398daec1f2florianIRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr,
2425f96552617c82834ece36184e674e249faa899b2fsewardj                             IRExpr** args );
2426c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj
2427c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj/* Similarly, make a zero-annotation dirty call which returns a value,
2428c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   and assign that to the given temp. */
2429f96552617c82834ece36184e674e249faa899b2fsewardjextern
2430f96552617c82834ece36184e674e249faa899b2fsewardjIRDirty* unsafeIRDirty_1_N ( IRTemp dst,
24311ff4756e1731485e6bf3cd96717cd8398daec1f2florian                             Int regparms, const HChar* name, void* addr,
2432f96552617c82834ece36184e674e249faa899b2fsewardj                             IRExpr** args );
2433c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj
2434ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
2435c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj/* --------------- Memory Bus Events --------------- */
2436c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj
2437c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardjtypedef
2438c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj   enum {
2439cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Imbe_Fence=0x1C00,
24406d615ba78d168bb4319120fff5ce83d3f7433022sewardj      /* Needed only on ARM.  It cancels a reservation made by a
24416d615ba78d168bb4319120fff5ce83d3f7433022sewardj         preceding Linked-Load, and needs to be handed through to the
24426d615ba78d168bb4319120fff5ce83d3f7433022sewardj         back end, just as LL and SC themselves are. */
24436d615ba78d168bb4319120fff5ce83d3f7433022sewardj      Imbe_CancelReservation
2444c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj   }
2445c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj   IRMBusEvent;
2446c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj
2447c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardjextern void ppIRMBusEvent ( IRMBusEvent );
2448c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj
2449c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj
2450e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj/* --------------- Compare and Swap --------------- */
2451e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2452e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj/* This denotes an atomic compare and swap operation, either
2453e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   a single-element one or a double-element one.
2454e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2455e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   In the single-element case:
2456e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2457e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .addr is the memory address.
2458e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .end  is the endianness with which memory is accessed
2459e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2460e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     If .addr contains the same value as .expdLo, then .dataLo is
2461e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     written there, else there is no write.  In both cases, the
2462e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     original value at .addr is copied into .oldLo.
2463e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2464e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     Types: .expdLo, .dataLo and .oldLo must all have the same type.
2465e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2466e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     guests, I64.
2467e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2468e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2469e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     be NULL.
2470e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2471e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   In the double-element case:
2472e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2473e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .addr is the memory address.
2474e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .end  is the endianness with which memory is accessed
2475e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2476e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     The operation is the same:
2477e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2478e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     If .addr contains the same value as .expdHi:.expdLo, then
2479e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .dataHi:.dataLo is written there, else there is no write.  In
2480e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     both cases the original value at .addr is copied into
2481e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .oldHi:.oldLo.
2482e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2483e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2484e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     all have the same type, which may be any integral type, viz: I8,
2485e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     I16, I32 or, for 64-bit guests, I64.
2486e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2487e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     The double-element case is complicated by the issue of
2488e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     endianness.  In all cases, the two elements are understood to be
2489e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     located adjacently in memory, starting at the address .addr.
2490e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2491e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       If .end is Iend_LE, then the .xxxLo component is at the lower
2492e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       address and the .xxxHi component is at the higher address, and
2493e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       each component is itself stored little-endianly.
2494e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2495e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       If .end is Iend_BE, then the .xxxHi component is at the lower
2496e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       address and the .xxxLo component is at the higher address, and
2497e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj       each component is itself stored big-endianly.
2498e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2499e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   This allows representing more cases than most architectures can
2500e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   handle.  For example, x86 cannot do DCAS on 8- or 16-bit elements.
2501e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2502e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   How to know if the CAS succeeded?
2503e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2504e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2505e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2506e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     stored at .addr, and the original value there was .oldLo (resp
2507e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     .oldHi:.oldLo).
2508e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2509e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2510e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     then the CAS failed, and the original value at .addr was .oldLo
2511e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj     (resp. .oldHi:.oldLo).
2512e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2513e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   Hence it is easy to know whether or not the CAS succeeded.
2514e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj*/
2515e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjtypedef
2516e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   struct {
2517e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRTemp    oldHi;  /* old value of *addr is written here */
2518e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRTemp    oldLo;
2519e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IREndness end;    /* endianness of the data in memory */
2520e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRExpr*   addr;   /* store address */
2521e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRExpr*   expdHi; /* expected old value at *addr */
2522e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRExpr*   expdLo;
2523e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRExpr*   dataHi; /* new value for *addr */
2524e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRExpr*   dataLo;
2525e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   }
2526e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   IRCAS;
2527e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
25280b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRCAS ( const IRCAS* cas );
2529e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2530e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjextern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2531e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj                        IREndness end, IRExpr* addr,
2532e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj                        IRExpr* expdHi, IRExpr* expdLo,
2533e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj                        IRExpr* dataHi, IRExpr* dataLo );
2534e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
25350b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRCAS* deepCopyIRCAS ( const IRCAS* );
2536e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2537d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
2538d6f38b3f822f7d57adfc0da3410995d85d6a4597florian/* ------------------ Circular Array Put ------------------ */
2539cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2540d6f38b3f822f7d57adfc0da3410995d85d6a4597floriantypedef
2541d6f38b3f822f7d57adfc0da3410995d85d6a4597florian   struct {
2542d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRRegArray* descr; /* Part of guest state treated as circular */
2543d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRExpr*     ix;    /* Variable part of index into array */
2544d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      Int         bias;  /* Constant offset part of index into array */
2545d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRExpr*     data;  /* The value to write */
2546d6f38b3f822f7d57adfc0da3410995d85d6a4597florian   } IRPutI;
2547d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
25480b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRPutI ( const IRPutI* puti );
2549d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
2550d6f38b3f822f7d57adfc0da3410995d85d6a4597florianextern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2551d6f38b3f822f7d57adfc0da3410995d85d6a4597florian                          Int bias, IRExpr* data );
2552d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
25530b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRPutI* deepCopyIRPutI ( const IRPutI* );
2554d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
2555c9069f2908814843e9a4da00da9c8905440195a6sewardj
2556cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* --------------- Guarded loads and stores --------------- */
2557cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2558cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* Conditional stores are straightforward.  They are the same as
2559cfe046e178666280b87da998b1b52ecda03ecd89sewardj   normal stores, with an extra 'guard' field :: Ity_I1 that
2560cfe046e178666280b87da998b1b52ecda03ecd89sewardj   determines whether or not the store actually happens.  If not,
2561cfe046e178666280b87da998b1b52ecda03ecd89sewardj   memory is unmodified.
2562cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2563cfe046e178666280b87da998b1b52ecda03ecd89sewardj   The semantics of this is that 'addr' and 'data' are fully evaluated
2564cfe046e178666280b87da998b1b52ecda03ecd89sewardj   even in the case where 'guard' evaluates to zero (false).
2565cfe046e178666280b87da998b1b52ecda03ecd89sewardj*/
2566cfe046e178666280b87da998b1b52ecda03ecd89sewardjtypedef
2567cfe046e178666280b87da998b1b52ecda03ecd89sewardj   struct {
2568cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IREndness end;    /* Endianness of the store */
2569cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   addr;   /* store address */
2570cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   data;   /* value to write */
2571cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   guard;  /* Guarding value */
2572cfe046e178666280b87da998b1b52ecda03ecd89sewardj   }
2573cfe046e178666280b87da998b1b52ecda03ecd89sewardj   IRStoreG;
2574cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2575cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* Conditional loads are a little more complex.  'addr' is the
2576cfe046e178666280b87da998b1b52ecda03ecd89sewardj   address, 'guard' is the guarding condition.  If the load takes
2577cfe046e178666280b87da998b1b52ecda03ecd89sewardj   place, the loaded value is placed in 'dst'.  If it does not take
2578cfe046e178666280b87da998b1b52ecda03ecd89sewardj   place, 'alt' is copied to 'dst'.  However, the loaded value is not
2579cfe046e178666280b87da998b1b52ecda03ecd89sewardj   placed directly in 'dst' -- it is first subjected to the conversion
2580cfe046e178666280b87da998b1b52ecda03ecd89sewardj   specified by 'cvt'.
2581cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2582cfe046e178666280b87da998b1b52ecda03ecd89sewardj   For example, imagine doing a conditional 8-bit load, in which the
2583cfe046e178666280b87da998b1b52ecda03ecd89sewardj   loaded value is zero extended to 32 bits.  Hence:
2584cfe046e178666280b87da998b1b52ecda03ecd89sewardj   * 'dst' and 'alt' must have type I32
2585cfe046e178666280b87da998b1b52ecda03ecd89sewardj   * 'cvt' must be a unary op which converts I8 to I32.  In this
2586cfe046e178666280b87da998b1b52ecda03ecd89sewardj     example, it would be ILGop_8Uto32.
2587cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2588cfe046e178666280b87da998b1b52ecda03ecd89sewardj   There is no explicit indication of the type at which the load is
2589cfe046e178666280b87da998b1b52ecda03ecd89sewardj   done, since that is inferrable from the arg type of 'cvt'.  Note
2590cfe046e178666280b87da998b1b52ecda03ecd89sewardj   that the types of 'alt' and 'dst' and the result type of 'cvt' must
2591cfe046e178666280b87da998b1b52ecda03ecd89sewardj   all be the same.
2592cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2593cfe046e178666280b87da998b1b52ecda03ecd89sewardj   Semantically, 'addr' is evaluated even in the case where 'guard'
2594cfe046e178666280b87da998b1b52ecda03ecd89sewardj   evaluates to zero (false), and 'alt' is evaluated even when 'guard'
2595cfe046e178666280b87da998b1b52ecda03ecd89sewardj   evaluates to one (true).  That is, 'addr' and 'alt' are always
2596cfe046e178666280b87da998b1b52ecda03ecd89sewardj   evaluated.
2597cfe046e178666280b87da998b1b52ecda03ecd89sewardj*/
2598cfe046e178666280b87da998b1b52ecda03ecd89sewardjtypedef
2599cfe046e178666280b87da998b1b52ecda03ecd89sewardj   enum {
2600cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_INVALID=0x1D00,
260170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj      ILGop_IdentV128, /* 128 bit vector, no conversion */
2602802bbae6cf8fbc3b6309514b84372f24147fa64esewardj      ILGop_Ident64,   /* 64 bit, no conversion */
2603cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_Ident32,   /* 32 bit, no conversion */
2604cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_16Uto32,   /* 16 bit load, Z-widen to 32 */
2605cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_16Sto32,   /* 16 bit load, S-widen to 32 */
2606cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_8Uto32,    /* 8 bit load, Z-widen to 32 */
2607cfe046e178666280b87da998b1b52ecda03ecd89sewardj      ILGop_8Sto32     /* 8 bit load, S-widen to 32 */
2608cfe046e178666280b87da998b1b52ecda03ecd89sewardj   }
2609cfe046e178666280b87da998b1b52ecda03ecd89sewardj   IRLoadGOp;
2610cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2611cfe046e178666280b87da998b1b52ecda03ecd89sewardjtypedef
2612cfe046e178666280b87da998b1b52ecda03ecd89sewardj   struct {
2613cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IREndness end;    /* Endianness of the load */
2614cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRLoadGOp cvt;    /* Conversion to apply to the loaded value */
2615cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRTemp    dst;    /* Destination (LHS) of assignment */
2616cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   addr;   /* Address being loaded from */
2617cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   alt;    /* Value if load is not done. */
2618cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRExpr*   guard;  /* Guarding value */
2619cfe046e178666280b87da998b1b52ecda03ecd89sewardj   }
2620cfe046e178666280b87da998b1b52ecda03ecd89sewardj   IRLoadG;
2621cfe046e178666280b87da998b1b52ecda03ecd89sewardj
26220b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRStoreG ( const IRStoreG* sg );
2623cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2624cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern void ppIRLoadGOp ( IRLoadGOp cvt );
2625cfe046e178666280b87da998b1b52ecda03ecd89sewardj
26260b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRLoadG ( const IRLoadG* lg );
2627cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2628cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern IRStoreG* mkIRStoreG ( IREndness end,
2629cfe046e178666280b87da998b1b52ecda03ecd89sewardj                              IRExpr* addr, IRExpr* data,
2630cfe046e178666280b87da998b1b52ecda03ecd89sewardj                              IRExpr* guard );
2631cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2632cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
2633cfe046e178666280b87da998b1b52ecda03ecd89sewardj                            IRTemp dst, IRExpr* addr, IRExpr* alt,
2634cfe046e178666280b87da998b1b52ecda03ecd89sewardj                            IRExpr* guard );
2635cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2636cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2637c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* ------------------ Statements ------------------ */
2638b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj
263957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* The different kinds of statements.  Their meaning is explained
264057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   below in the comments for IRStmt.
26415a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj
264257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   Those marked META do not represent code, but rather extra
264357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   information about the code.  These statements can be removed
264457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   without affecting the functional behaviour of the code, however
264557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   they are required by some IR consumers such as tools that
264657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   instrument the code.
26475a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj*/
2648c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj
2649ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
2650d2445f60726580b450eca68ab40c568f9df338e2sewardj   enum {
2651cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ist_NoOp=0x1E00,
265257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_IMark,     /* META */
265357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_AbiHint,   /* META */
265457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_Put,
265557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_PutI,
2656dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      Ist_WrTmp,
265757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_Store,
2658cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ist_LoadG,
2659cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ist_StoreG,
2660e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      Ist_CAS,
2661e768e92e054cde495849a5c842a477d287677f78sewardj      Ist_LLSC,
266257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_Dirty,
2663cfe046e178666280b87da998b1b52ecda03ecd89sewardj      Ist_MBE,
266457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      Ist_Exit
2665b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj   }
2666ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   IRStmtTag;
2667ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj
266857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* A statement.  Stored as a tagged union.  'tag' indicates what kind
266957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   of expression this is.  'Ist' is the union that holds the fields.
267057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
267157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   statement, and the fields can be accessed with
267257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   'st.Ist.Store.<fieldname>'.
267357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
267457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   For each kind of statement, we show what it looks like when
2675e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   pretty-printed with ppIRStmt().
267657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
2677ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
2678ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   struct _IRStmt {
2679ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      IRStmtTag tag;
2680ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      union {
268157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* A no-op (usually resulting from IR optimisation).  Can be
268257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            omitted without any effect.
268357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2684e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: IR-NoOp
268557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2686ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj         struct {
2687d2445f60726580b450eca68ab40c568f9df338e2sewardj	 } NoOp;
268857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
268957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* META: instruction mark.  Marks the start of the statements
269057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            that represent a single machine instruction (the end of
269157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            those statements is marked by the next IMark or the end of
2692dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            the IRSB).  Contains the address and length of the
269357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            instruction.
269457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
26952f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            It also contains a delta value.  The delta must be
26962f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            subtracted from a guest program counter value before
26972f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            attempting to establish, by comparison with the address
26982f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            and length values, whether or not that program counter
26992f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            value refers to this instruction.  For x86, amd64, ppc32,
27002f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            ppc64 and arm, the delta value is zero.  For Thumb
27012f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            instructions, the delta value is one.  This is because, on
27022f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            Thumb, guest PC values (guest_R15T) are encoded using the
27032f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            top 31 bits of the instruction address and a 1 in the lsb;
27042f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            hence they appear to be (numerically) 1 past the start of
27052f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            the instruction they refer to.  IOW, guest_R15T on ARM
27062f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            holds a standard ARM interworking address.
27072f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj
27082f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
27092f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                         eg. ------ IMark(0x4000792, 5, 0) ------,
271057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2711d2445f60726580b450eca68ab40c568f9df338e2sewardj         struct {
2712dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian            Addr   addr;   /* instruction address */
2713dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian            UInt   len;    /* instruction length */
27142f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj            UChar  delta;  /* addr = program counter as encoded in guest state
27152f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     - delta */
2716f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj         } IMark;
271757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
271857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* META: An ABI hint, which says something about this
271957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            platform's ABI.
272057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
272157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            At the moment, the only AbiHint is one which indicates
272257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            that a given chunk of address space, [base .. base+len-1],
272357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            has become undefined.  This is used on amd64-linux and
272457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            some ppc variants to pass stack-redzoning hints to whoever
2725478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj            wants to see them.  It also indicates the address of the
2726478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj            next (dynamic) instruction that will be executed.  This is
2727478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj            to help Memcheck to origin tracking.
272857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2729e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
2730478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                         eg. ====== AbiHint(t1, 16, t2) ======
273157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2732f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj         struct {
273357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr* base;     /* Start  of undefined chunk */
273457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            Int     len;      /* Length of undefined chunk */
2735478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj            IRExpr* nia;      /* Address of next (guest) insn */
27365a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj         } AbiHint;
273757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
273857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* Write a guest register, at a fixed offset in the guest state.
2739e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
274057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
27415a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj         struct {
274257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            Int     offset;   /* Offset into the guest state */
274357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr* data;     /* The value to write */
2744ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj         } Put;
274557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
274657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* Write a guest register, at a non-fixed offset in the guest
274757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            state.  See the comment for GetI expressions for more
274857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            information.
274957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2750e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
275157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                         eg. PUTI(64:8xF64)[t5,0] = t1
275257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2753ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj         struct {
2754d6f38b3f822f7d57adfc0da3410995d85d6a4597florian            IRPutI* details;
2755d1725d18b61bf7912a9099686179faef5815dba1sewardj         } PutI;
275657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2757dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         /* Assign a value to a temporary.  Note that SSA rules require
2758dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            each tmp is only assigned to once.  IR sanity checking will
2759dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            reject any block containing a temporary which is not assigned
2760dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            to exactly once.
276157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2762e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
276357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2764d1725d18b61bf7912a9099686179faef5815dba1sewardj         struct {
276557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRTemp  tmp;   /* Temporary  (LHS of assignment) */
276657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr* data;  /* Expression (RHS of assignment) */
2767dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         } WrTmp;
276857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2769e768e92e054cde495849a5c842a477d287677f78sewardj         /* Write a value to memory.  This is a normal store, not a
2770e768e92e054cde495849a5c842a477d287677f78sewardj            Store-Conditional.  To represent a Store-Conditional,
2771e768e92e054cde495849a5c842a477d287677f78sewardj            instead use IRStmt.LLSC.
2772e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
277357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2774ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj         struct {
277557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IREndness end;    /* Endianness of the store */
277657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr*   addr;   /* store address */
277757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr*   data;   /* value to write */
2778af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         } Store;
277957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2780cfe046e178666280b87da998b1b52ecda03ecd89sewardj         /* Guarded store.  Note that this is defined to evaluate all
2781cfe046e178666280b87da998b1b52ecda03ecd89sewardj            expression fields (addr, data) even if the guard evaluates
2782cfe046e178666280b87da998b1b52ecda03ecd89sewardj            to false.
2783cfe046e178666280b87da998b1b52ecda03ecd89sewardj            ppIRStmt output:
2784cfe046e178666280b87da998b1b52ecda03ecd89sewardj              if (<guard>) ST<end>(<addr>) = <data> */
2785cfe046e178666280b87da998b1b52ecda03ecd89sewardj         struct {
2786cfe046e178666280b87da998b1b52ecda03ecd89sewardj            IRStoreG* details;
2787cfe046e178666280b87da998b1b52ecda03ecd89sewardj         } StoreG;
2788cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2789cfe046e178666280b87da998b1b52ecda03ecd89sewardj         /* Guarded load.  Note that this is defined to evaluate all
2790cfe046e178666280b87da998b1b52ecda03ecd89sewardj            expression fields (addr, alt) even if the guard evaluates
2791cfe046e178666280b87da998b1b52ecda03ecd89sewardj            to false.
2792cfe046e178666280b87da998b1b52ecda03ecd89sewardj            ppIRStmt output:
2793cfe046e178666280b87da998b1b52ecda03ecd89sewardj              t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */
2794cfe046e178666280b87da998b1b52ecda03ecd89sewardj         struct {
2795cfe046e178666280b87da998b1b52ecda03ecd89sewardj            IRLoadG* details;
2796cfe046e178666280b87da998b1b52ecda03ecd89sewardj         } LoadG;
2797cfe046e178666280b87da998b1b52ecda03ecd89sewardj
2798e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         /* Do an atomic compare-and-swap operation.  Semantics are
2799e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            described above on a comment at the definition of IRCAS.
2800e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2801e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output:
2802e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj               t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2803e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            eg
2804e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj               t1 = CASle(t2 :: t3->Add32(t3,1))
2805e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj               which denotes a 32-bit atomic increment
2806e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj               of a value at address t2
2807e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2808e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            A double-element CAS may also be denoted, in which case <tmp>,
2809e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            <expected> and <new> are all pairs of items, separated by
2810e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            commas.
2811e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         */
2812e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         struct {
2813e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            IRCAS* details;
2814e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         } CAS;
2815e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj
2816e768e92e054cde495849a5c842a477d287677f78sewardj         /* Either Load-Linked or Store-Conditional, depending on
2817e768e92e054cde495849a5c842a477d287677f78sewardj            STOREDATA.
2818e768e92e054cde495849a5c842a477d287677f78sewardj
2819e768e92e054cde495849a5c842a477d287677f78sewardj            If STOREDATA is NULL then this is a Load-Linked, meaning
2820e768e92e054cde495849a5c842a477d287677f78sewardj            that data is loaded from memory as normal, but a
2821e768e92e054cde495849a5c842a477d287677f78sewardj            'reservation' for the address is also lodged in the
2822e768e92e054cde495849a5c842a477d287677f78sewardj            hardware.
2823e768e92e054cde495849a5c842a477d287677f78sewardj
2824e768e92e054cde495849a5c842a477d287677f78sewardj               result = Load-Linked(addr, end)
2825e768e92e054cde495849a5c842a477d287677f78sewardj
2826e768e92e054cde495849a5c842a477d287677f78sewardj            The data transfer type is the type of RESULT (I32, I64,
2827e768e92e054cde495849a5c842a477d287677f78sewardj            etc).  ppIRStmt output:
2828e768e92e054cde495849a5c842a477d287677f78sewardj
2829e768e92e054cde495849a5c842a477d287677f78sewardj               result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2830e768e92e054cde495849a5c842a477d287677f78sewardj
2831e768e92e054cde495849a5c842a477d287677f78sewardj            If STOREDATA is not NULL then this is a Store-Conditional,
2832e768e92e054cde495849a5c842a477d287677f78sewardj            hence:
2833e768e92e054cde495849a5c842a477d287677f78sewardj
2834e768e92e054cde495849a5c842a477d287677f78sewardj               result = Store-Conditional(addr, storedata, end)
2835e768e92e054cde495849a5c842a477d287677f78sewardj
2836e768e92e054cde495849a5c842a477d287677f78sewardj            The data transfer type is the type of STOREDATA and RESULT
2837e768e92e054cde495849a5c842a477d287677f78sewardj            has type Ity_I1. The store may fail or succeed depending
2838e768e92e054cde495849a5c842a477d287677f78sewardj            on the state of a previously lodged reservation on this
2839e768e92e054cde495849a5c842a477d287677f78sewardj            address.  RESULT is written 1 if the store succeeds and 0
2840e768e92e054cde495849a5c842a477d287677f78sewardj            if it fails.  eg ppIRStmt output:
2841e768e92e054cde495849a5c842a477d287677f78sewardj
2842e768e92e054cde495849a5c842a477d287677f78sewardj               result = ( ST<end>-Cond(<addr>) = <storedata> )
2843e768e92e054cde495849a5c842a477d287677f78sewardj               eg t3 = ( STbe-Cond(t1, t2) )
2844e768e92e054cde495849a5c842a477d287677f78sewardj
2845e768e92e054cde495849a5c842a477d287677f78sewardj            In all cases, the address must be naturally aligned for
2846e768e92e054cde495849a5c842a477d287677f78sewardj            the transfer type -- any misaligned addresses should be
2847e768e92e054cde495849a5c842a477d287677f78sewardj            caught by a dominating IR check and side exit.  This
2848e768e92e054cde495849a5c842a477d287677f78sewardj            alignment restriction exists because on at least some
2849e768e92e054cde495849a5c842a477d287677f78sewardj            LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2850e768e92e054cde495849a5c842a477d287677f78sewardj            misaligned addresses, and we have to actually generate
2851e768e92e054cde495849a5c842a477d287677f78sewardj            stwcx. on the host, and we don't want it trapping on the
2852e768e92e054cde495849a5c842a477d287677f78sewardj            host.
2853e768e92e054cde495849a5c842a477d287677f78sewardj
2854e768e92e054cde495849a5c842a477d287677f78sewardj            Summary of rules for transfer type:
2855e768e92e054cde495849a5c842a477d287677f78sewardj              STOREDATA == NULL (LL):
2856e768e92e054cde495849a5c842a477d287677f78sewardj                transfer type = type of RESULT
2857e768e92e054cde495849a5c842a477d287677f78sewardj              STOREDATA != NULL (SC):
2858e768e92e054cde495849a5c842a477d287677f78sewardj                transfer type = type of STOREDATA, and RESULT :: Ity_I1
2859e768e92e054cde495849a5c842a477d287677f78sewardj         */
2860e768e92e054cde495849a5c842a477d287677f78sewardj         struct {
2861e768e92e054cde495849a5c842a477d287677f78sewardj            IREndness end;
2862e768e92e054cde495849a5c842a477d287677f78sewardj            IRTemp    result;
2863e768e92e054cde495849a5c842a477d287677f78sewardj            IRExpr*   addr;
2864e768e92e054cde495849a5c842a477d287677f78sewardj            IRExpr*   storedata; /* NULL => LL, non-NULL => SC */
2865e768e92e054cde495849a5c842a477d287677f78sewardj         } LLSC;
2866e768e92e054cde495849a5c842a477d287677f78sewardj
286757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         /* Call (possibly conditionally) a C function that has side
286857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            effects (ie. is "dirty").  See the comments above the
286957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRDirty type declaration for more information.
287057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2871e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output:
287257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj               t<tmp> = DIRTY <guard> <effects>
287357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                  ::: <callee>(<args>)
287457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            eg.
287557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj               t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
287657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                     ::: foo{0x380035f4}(t2)
287757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
287864e1d656188ead7ec5af83b3fb3effef02ae73ecsewardj         struct {
2879b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj            IRDirty* details;
2880b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj         } Dirty;
288157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2882c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         /* A memory bus event - a fence, or acquisition/release of the
2883c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            hardware bus lock.  IR optimisation treats all these as fences
2884c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            across which no memory references may be moved.
2885e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: MBusEvent-Fence,
2886c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj                             MBusEvent-BusLock, MBusEvent-BusUnlock.
288757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
2888b3bce0e2d130a9a4efcb8bcda8011fd58c4a9998sewardj         struct {
2889c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            IRMBusEvent event;
2890c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         } MBE;
289157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2892dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         /* Conditional exit from the middle of an IRSB.
2893e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            ppIRStmt output: if (<guard>) goto {<jk>} <dst>
289457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                         eg. if (t69) goto {Boring} 0x4000AAA:I32
2895c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            If <guard> is true, the guest state is also updated by
2896c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            PUT-ing <dst> at <offsIP>.  This is done because a
2897c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            taken exit must update the guest program counter.
289857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         */
28993e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj         struct {
290057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRExpr*    guard;    /* Conditional expression */
290157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            IRConst*   dst;      /* Jump target (constant only) */
2902d6f38b3f822f7d57adfc0da3410995d85d6a4597florian            IRJumpKind jk;       /* Jump kind */
2903c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            Int        offsIP;   /* Guest state offset for IP */
290464e1d656188ead7ec5af83b3fb3effef02ae73ecsewardj         } Exit;
2905ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      } Ist;
2906ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   }
2907ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   IRStmt;
2908ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
290957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Statement constructors. */
29105a9ffab9150b7cca31d44d48da998d011bbe8e6asewardjextern IRStmt* IRStmt_NoOp    ( void );
2911dcd6d236c9aef7d4c84369d4c51f6b92ac910127florianextern IRStmt* IRStmt_IMark   ( Addr addr, UInt len, UChar delta );
2912478646f54befaba01cbceb40fd5e46cdf562fdb5sewardjextern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
29135a9ffab9150b7cca31d44d48da998d011bbe8e6asewardjextern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
2914d6f38b3f822f7d57adfc0da3410995d85d6a4597florianextern IRStmt* IRStmt_PutI    ( IRPutI* details );
2915dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRStmt* IRStmt_WrTmp   ( IRTemp tmp, IRExpr* data );
2916e768e92e054cde495849a5c842a477d287677f78sewardjextern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
2917cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern IRStmt* IRStmt_StoreG  ( IREndness end, IRExpr* addr, IRExpr* data,
2918cfe046e178666280b87da998b1b52ecda03ecd89sewardj                                IRExpr* guard );
2919cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern IRStmt* IRStmt_LoadG   ( IREndness end, IRLoadGOp cvt, IRTemp dst,
2920cfe046e178666280b87da998b1b52ecda03ecd89sewardj                                IRExpr* addr, IRExpr* alt, IRExpr* guard );
2921e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjextern IRStmt* IRStmt_CAS     ( IRCAS* details );
2922e768e92e054cde495849a5c842a477d287677f78sewardjextern IRStmt* IRStmt_LLSC    ( IREndness end, IRTemp result,
2923e768e92e054cde495849a5c842a477d287677f78sewardj                                IRExpr* addr, IRExpr* storedata );
29245a9ffab9150b7cca31d44d48da998d011bbe8e6asewardjextern IRStmt* IRStmt_Dirty   ( IRDirty* details );
2925c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardjextern IRStmt* IRStmt_MBE     ( IRMBusEvent event );
2926c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjextern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2927c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                                Int offsIP );
2928c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
292957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy an IRStmt. */
29300b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRStmt* deepCopyIRStmt ( const IRStmt* );
2931695cff9303ef5dc8079117acfd632b44edb1f010sewardj
293257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print an IRStmt. */
29330b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRStmt ( const IRStmt* );
2934c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
2935ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
2936e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj/* ------------------ Basic Blocks ------------------ */
2937e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj
293857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Type environments: a bunch of statements, expressions, etc, are
293957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   incomplete without an environment indicating the type of each
294057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   IRTemp.  So this provides one.  IR temporaries are really just
294157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   unsigned ints and so this provides an array, 0 .. n_types_used-1 of
294257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   them.
2943c97096c44637ae5775ed305b19f16f0b505f17d8sewardj*/
2944c97096c44637ae5775ed305b19f16f0b505f17d8sewardjtypedef
2945c97096c44637ae5775ed305b19f16f0b505f17d8sewardj   struct {
2946e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj      IRType* types;
2947e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj      Int     types_size;
2948e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj      Int     types_used;
2949c97096c44637ae5775ed305b19f16f0b505f17d8sewardj   }
2950c97096c44637ae5775ed305b19f16f0b505f17d8sewardj   IRTypeEnv;
2951c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
295257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Obtain a new IRTemp */
295357c10c89904f7fdc4244fcbf704625e7169aafe6sewardjextern IRTemp newIRTemp ( IRTypeEnv*, IRType );
295457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
295557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Deep-copy a type environment */
29560b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* );
2957695cff9303ef5dc8079117acfd632b44edb1f010sewardj
295857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* Pretty-print a type environment */
29590b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRTypeEnv ( const IRTypeEnv* );
2960c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
2961ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
2962dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Code blocks, which in proper compiler terminology are superblocks
2963dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   (single entry, multiple exit code sequences) contain:
2964dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
296557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   - A table giving a type for each temp (the "type environment")
2966d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj   - An expandable array of statements
2967e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj   - An expression of type 32 or 64 bits, depending on the
2968dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj     guest's word size, indicating the next destination if the block
2969dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj     executes all the way to the end, without a side exit
2970d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj   - An indication of any special actions (JumpKind) needed
2971d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj     for this final jump.
2972c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   - Offset of the IP field in the guest state.  This will be
2973c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj     updated before the final jump is done.
297457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2975dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   "IRSB" stands for "IR Super Block".
2976ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj*/
2977ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjtypedef
297857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj   struct {
2979c97096c44637ae5775ed305b19f16f0b505f17d8sewardj      IRTypeEnv* tyenv;
2980d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj      IRStmt**   stmts;
2981d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj      Int        stmts_size;
2982d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj      Int        stmts_used;
2983e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj      IRExpr*    next;
2984e539a4055b785d1ee978727e51bcc4b39f3e2c1asewardj      IRJumpKind jumpkind;
2985c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      Int        offsIP;
2986ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj   }
2987dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   IRSB;
2988ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
2989dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Allocate a new, uninitialised IRSB */
2990dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern IRSB* emptyIRSB ( void );
2991695cff9303ef5dc8079117acfd632b44edb1f010sewardj
2992dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Deep-copy an IRSB */
29930b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRSB* deepCopyIRSB ( const IRSB* );
2994c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
2995dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Deep-copy an IRSB, except for the statements list, which set to be
29966f2f2834ca8098c5e0373cecb704e054f5b318e7sewardj   a new, empty, list of statements. */
29970b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRSB* deepCopyIRSBExceptStmts ( const IRSB* );
299857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
2999dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Pretty-print an IRSB */
30000b70efae27eafd60bc7ea9a3955605d55a681651florianextern void ppIRSB ( const IRSB* );
3001c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
3002dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Append an IRStmt to an IRSB */
3003dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjextern void addStmtToIRSB ( IRSB*, IRStmt* );
3004695cff9303ef5dc8079117acfd632b44edb1f010sewardj
3005695cff9303ef5dc8079117acfd632b44edb1f010sewardj
3006ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
3007c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/*--- Helper functions for the IR                             ---*/
3008ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*---------------------------------------------------------------*/
3009ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
3010c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* For messing with IR type environments */
3011d7cb8538d814660fe68ea7100571fd3ed1de8082sewardjextern IRTypeEnv* emptyIRTypeEnv  ( void );
3012c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
3013c97096c44637ae5775ed305b19f16f0b505f17d8sewardj/* What is the type of this expression? */
30140b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRType typeOfIRConst ( const IRConst* );
30150b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRType typeOfIRTemp  ( const IRTypeEnv*, IRTemp );
30160b70efae27eafd60bc7ea9a3955605d55a681651florianextern IRType typeOfIRExpr  ( const IRTypeEnv*, const IRExpr* );
3017ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
3018cfe046e178666280b87da998b1b52ecda03ecd89sewardj/* What are the arg and result type for this IRLoadGOp? */
3019cfe046e178666280b87da998b1b52ecda03ecd89sewardjextern void typeOfIRLoadGOp ( IRLoadGOp cvt,
3020cfe046e178666280b87da998b1b52ecda03ecd89sewardj                              /*OUT*/IRType* t_res,
3021cfe046e178666280b87da998b1b52ecda03ecd89sewardj                              /*OUT*/IRType* t_arg );
3022cfe046e178666280b87da998b1b52ecda03ecd89sewardj
3023354392111e47edc50442ea5095fa2367d9cc206fsewardj/* Sanity check a BB of IR */
30240b70efae27eafd60bc7ea9a3955605d55a681651florianextern void sanityCheckIRSB ( const  IRSB*  bb,
30251ff4756e1731485e6bf3cd96717cd8398daec1f2florian                              const  HChar* caller,
3026b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                              Bool   require_flatness,
3027b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                              IRType guest_word_size );
30280b70efae27eafd60bc7ea9a3955605d55a681651florianextern Bool isFlatIRStmt ( const IRStmt* );
3029ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
30306d2638e5edd8849e036f235d42a23c959e3bc3d8sewardj/* Is this any value actually in the enumeration 'IRType' ? */
3031496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjextern Bool isPlausibleIRType ( IRType ty );
30326d2638e5edd8849e036f235d42a23c959e3bc3d8sewardj
30332245ce9e834193d49261b8a433b4a0bd128c878eflorian
30342245ce9e834193d49261b8a433b4a0bd128c878eflorian/*---------------------------------------------------------------*/
30352245ce9e834193d49261b8a433b4a0bd128c878eflorian/*--- IR injection                                            ---*/
30362245ce9e834193d49261b8a433b4a0bd128c878eflorian/*---------------------------------------------------------------*/
30377d00913f2ac5014a145a899b6ee4b8511539221fsewardj
30382245ce9e834193d49261b8a433b4a0bd128c878eflorianvoid vex_inject_ir(IRSB *, IREndness);
30392245ce9e834193d49261b8a433b4a0bd128c878eflorian
30402245ce9e834193d49261b8a433b4a0bd128c878eflorian
3041887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#endif /* ndef __LIBVEX_IR_H */
3042ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj
3043ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj/*---------------------------------------------------------------*/
3044887a11a609f3e61d2ae8fe4e67f176207715da7esewardj/*---                                             libvex_ir.h ---*/
3045ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj/*---------------------------------------------------------------*/
3046