1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin libvex_ir.h ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2004-2013 OpenWorks LLP 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.net 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02110-1301, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __LIBVEX_IR_H 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __LIBVEX_IR_H 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- High-level IR description ---*/ 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Vex IR is an architecture-neutral intermediate representation. 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Unlike some IRs in systems similar to Vex, it is not like assembly 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown language (ie. a list of instructions). Rather, it is more like the 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IR that might be used in a compiler. 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Code blocks 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~ 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The code is broken into small code blocks ("superblocks", type: 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'IRSB'). Each code block typically represents from 1 to perhaps 50 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instructions. IRSBs are single-entry, multiple-exit code blocks. 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Each IRSB contains three things: 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - a type environment, which indicates the type of each temporary 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value present in the IRSB 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - a list of statements, which represent code 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - a jump that exits from the end the IRSB 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Because the blocks are multiple-exit, there can be additional 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown conditional exit statements that cause control to leave the IRSB 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown before the final exit. Also because of this, IRSBs can cover 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown multiple non-consecutive sequences of code (up to 3). These are 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown recorded in the type VexGuestExtents (see libvex.h). 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Statements and expressions 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~~~~~~~~~ 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Statements (type 'IRStmt') represent operations with side-effects, 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. guest register writes, stores, and assignments to temporaries. 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Expressions (type 'IRExpr') represent operations without 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown side-effects, eg. arithmetic operations, loads, constants. 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Expressions can contain sub-expressions, forming expression trees, 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. (3 + (4 * load(addr1)). 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Storage of guest state 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~~~~~ 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The "guest state" contains the guest registers of the guest machine 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ie. the machine that we are simulating). It is stored by default 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in a block of memory supplied by the user of the VEX library, 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown generally referred to as the guest state (area). To operate on 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown these registers, one must first read ("Get") them from the guest 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state into a temporary value. Afterwards, one can write ("Put") 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown them back into the guest state. 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Get and Put are characterised by a byte offset into the guest 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state, a small integer which effectively gives the identity of the 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown referenced guest register, and a type, which indicates the size of 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the value to be transferred. 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The basic "Get" and "Put" operations are sufficient to model normal 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fixed registers on the guest. Selected areas of the guest state 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown can be treated as a circular array of registers (type: 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'IRRegArray'), which can be indexed at run-time. This is done with 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the "GetI" and "PutI" primitives. This is necessary to describe 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rotating register files, for example the x87 FPU stack, SPARC 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register windows, and the Itanium register files. 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Examples, and flattened vs. unflattened code 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For example, consider this x86 instruction: 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addl %eax, %ebx 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown One Vex IR translation for this code would be this: 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ------ IMark(0x24F275, 7, 0) ------ 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t3 = GET:I32(0) # get %eax, a 32-bit integer 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t2 = GET:I32(12) # get %ebx, a 32-bit integer 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = Add32(t3,t2) # addl 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PUT(0) = t1 # put %eax 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (For simplicity, this ignores the effects on the condition codes, and 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the update of the instruction pointer.) 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The "IMark" is an IR statement that doesn't represent actual code. 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Instead it indicates the address and length of the original 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction. The numbers 0 and 12 are offsets into the guest state 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for %eax and %ebx. The full list of offsets for an architecture 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <ARCH> can be found in the type VexGuest<ARCH>State in the file 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VEX/pub/libvex_guest_<ARCH>.h. 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The five statements in this example are: 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - the IMark 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - three assignments to temporaries 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - one register write (put) 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The six expressions in this example are: 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - two register reads (gets) 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - one arithmetic (add) operation 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - three temporaries (two nested within the Add32, one in the PUT) 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The above IR is "flattened", ie. all sub-expressions are "atoms", 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown either constants or temporaries. An equivalent, unflattened version 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown would be: 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PUT(0) = Add32(GET:I32(0), GET:I32(12)) 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IR is guaranteed to be flattened at instrumentation-time. This makes 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instrumentation easier. Equivalent flattened and unflattened IR 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typically results in the same generated code. 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Another example, this one showing loads and stores: 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addl %edx,4(%eax) 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This becomes (again ignoring condition code and instruction pointer 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown updates): 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ------ IMark(0x4000ABA, 3, 0) ------ 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t3 = Add32(GET:I32(0),0x4:I32) 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t2 = LDle:I32(t3) 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = GET:I32(8) 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t0 = Add32(t2,t1) 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown STle(t3) = t0 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The "le" in "LDle" and "STle" is short for "little-endian". 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown No need for deallocations 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~~~~~~~~ 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Although there are allocation functions for various data structures 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in this file, there are no deallocation functions. This is because 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vex uses a memory allocation scheme that automatically reclaims the 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memory used by allocated structures once translation is completed. 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This makes things easier for tools that instruments/transforms code 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown blocks. 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SSAness and typing 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~ 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The IR is fully typed. For every IRSB (IR block) it is possible to 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown say unambiguously whether or not it is correctly typed. 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Incorrectly typed IR has no meaning and the VEX will refuse to 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown process it. At various points during processing VEX typechecks the 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IR and aborts if any violations are found. This seems overkill but 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown makes it a great deal easier to build a reliable JIT. 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IR also has the SSA property. SSA stands for Static Single 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Assignment, and what it means is that each IR temporary may be 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assigned to only once. This idea became widely used in compiler 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown construction in the mid to late 90s. It makes many IR-level 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown transformations/code improvements easier, simpler and faster. 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Whenever it typechecks an IR block, VEX also checks the SSA 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown property holds, and will abort if not so. So SSAness is 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mechanically and rigidly enforced. 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Type definitions for the IR ---*/ 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* General comments about naming schemes: 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown All publically visible functions contain the name of the primary 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type on which they operate (IRFoo, IRBar, etc). Hence you should 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be able to identify these functions by grepping for "IR[A-Z]". 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For some type 'IRFoo': 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - ppIRFoo is the printing method for IRFoo, printing it to the 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown output channel specified in the LibVEX_Initialise call. 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - eqIRFoo is a structural equality predicate for IRFoos. 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - deepCopyIRFoo is a deep copy constructor for IRFoos. 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It recursively traverses the entire argument tree and 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown produces a complete new tree. All types have a deep copy 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown constructor. 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - shallowCopyIRFoo is the shallow copy constructor for IRFoos. 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It creates a new top-level copy of the supplied object, 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown but does not copy any sub-objects. Only some types have a 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shallow copy constructor. 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Types ------------------ */ 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A type indicates the size of a value, and whether it's an integer, a 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown float, or a vector (SIMD) value. */ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ity_INVALID=0x1100, 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I1, 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I8, 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I16, 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I32, 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I64, 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_I128, /* 128-bit scalar */ 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_F32, /* IEEE 754 float */ 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ity_F64, /* IEEE 754 double */ 230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ity_D32, /* 32-bit Decimal floating point */ 231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ity_D64, /* 64-bit Decimal floating point */ 232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ity_D128, /* 128-bit Decimal floating point */ 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Ity_F128, /* 128-bit floating point; implementation defined */ 234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ity_V128, /* 128-bit SIMD */ 235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ity_V256 /* 256-bit SIMD */ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType; 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRType */ 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRType ( IRType ); 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Get the size (in bytes) of an IRType */ 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int sizeofIRType ( IRType ); 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Translate 1/2/4/8 into Ity_I{8,16,32,64} respectively. Asserts on 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov any other input. */ 247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRType integerIRTypeOfSize ( Int szB ); 248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Endianness ------------------ */ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IREndness is used in load IRExprs and store IRStmts. */ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iend_LE=0x1200, /* little endian */ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iend_BE /* big endian */ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness; 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Constants ------------------ */ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRConsts are used within 'Const' and 'Exit' IRExprs. */ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The various kinds of constant. */ 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ico_U1=0x1300, 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_U8, 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_U16, 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_U32, 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_U64, 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Ico_F32, /* 32-bit IEEE754 floating */ 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Ico_F32i, /* 32-bit unsigned int to be interpreted literally 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov as a IEEE754 single value. */ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_F64, /* 64-bit IEEE754 floating */ 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ico_F64i, /* 64-bit unsigned int to be interpreted literally 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as a IEEE754 double value. */ 279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ico_V128, /* 128-bit restricted vector constant, with 1 bit 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (repeated 8 times) for each of the 16 x 1-byte lanes */ 281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ico_V256 /* 256-bit restricted vector constant, with 1 bit 282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (repeated 8 times) for each of the 32 x 1-byte lanes */ 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConstTag; 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A constant. Stored as a tagged union. 'tag' indicates what kind of 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown constant this is. 'Ico' is the union that holds the fields. If an 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant, 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and its value can be accessed with 'c.Ico.U32'. */ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _IRConst { 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConstTag tag; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool U1; 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar U8; 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort U16; 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt U32; 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong U64; 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Float F32; 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt F32i; 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Double F64; 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong F64i; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort V128; /* 16-bit value; see Ico_V128 comment above */ 304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt V256; /* 32-bit value; see Ico_V256 comment above */ 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Ico; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRConst constructors */ 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U1 ( Bool ); 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U8 ( UChar ); 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U16 ( UShort ); 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U32 ( UInt ); 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_U64 ( ULong ); 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRConst* IRConst_F32 ( Float ); 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRConst* IRConst_F32i ( UInt ); 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_F64 ( Double ); 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_F64i ( ULong ); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* IRConst_V128 ( UShort ); 320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRConst* IRConst_V256 ( UInt ); 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRConst */ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRConst* deepCopyIRConst ( IRConst* ); 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRConst */ 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRConst ( IRConst* ); 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Compare two IRConsts for equality */ 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRConst ( IRConst*, IRConst* ); 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Call targets ------------------ */ 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Describes a helper function to call. The name part is purely for 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pretty printing and not actually used. regparms=n tells the back 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end that the callee has been declared 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "__attribute__((regparm(n)))", although indirectly using the 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VEX_REGPARM(n) macro. On some targets (x86) the back end will need 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to construct a non-standard sequence to call a function declared 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov like this. 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mcx_mask is a sop to Memcheck. It indicates which args should be 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown considered 'always defined' when lazily computing definedness of 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[1], etc. If a bit is set, the corresponding arg is excluded 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (hence "x" in "mcx") from definedness checking. 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int regparms; 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* name; 353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void* addr; 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt mcx_mask; 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCallee; 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create an IRCallee. */ 359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr ); 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRCallee. */ 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCallee* deepCopyIRCallee ( IRCallee* ); 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRCallee. */ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRCallee ( IRCallee* ); 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Guest state arrays ------------------ */ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This describes a section of the guest state that we want to 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be able to index at run time, so as to be able to describe 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indexed or rotating register files on the guest. */ 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int base; /* guest state offset of start of indexed area */ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType elemTy; /* type of each element in the indexed area */ 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int nElems; /* number of elements in the indexed area */ 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray; 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRRegArray* mkIRRegArray ( Int, IRType, Int ); 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRRegArray* deepCopyIRRegArray ( IRRegArray* ); 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRRegArray ( IRRegArray* ); 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRRegArray ( IRRegArray*, IRRegArray* ); 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Temporaries ------------------ */ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This represents a temporary, eg. t1. The IR optimiser relies on the 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fact that IRTemps are 32-bit ints. Do not change them to be ints of 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any other size. */ 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef UInt IRTemp; 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRTemp. */ 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRTemp ( IRTemp ); 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF) 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Primops (arity 1,2,3 and 4) --------------- */ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Primitive operations that are used in Unop, Binop, Triop and Qop 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExprs. Once we take into account integer, floating point and SIMD 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown operations of all the different sizes, there are quite a lot of them. 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Most instructions supported by the architectures that Vex supports 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid) 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are not; they are instead handled with dirty helpers that emulate 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown their functionality. Such obscure ones are thus not directly visible 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the IR, but their effects on guest state (memory and registers) 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are made visible via the annotations in IRDirty structures. 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Do not change this ordering. The IR generators rely on 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (eg) Iop_Add64 == IopAdd8 + 3. -- */ 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_INVALID=0x1400, 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64, 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Signless mul. MullS/MullU is elsewhere. */ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64, 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64, 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_And8, Iop_And16, Iop_And32, Iop_And64, 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64, 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64, 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64, 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64, 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Integer comparisons. */ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64, 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Tags for unary ops */ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Exactly like CmpEQ8/16/32/64, but carrying the additional 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hint that these compute the success/failure of a CAS 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown operation, and hence are almost certainly applied to two 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown copies of the same value, which in turn has implications for 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memcheck's instrumentation. */ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64, 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64, 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Exactly like CmpNE8/16/32/64, but carrying the additional 445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hint that these needs expensive definedness tracking. */ 446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64, 447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Ordering not important after here. -- */ 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Widening multiplies */ 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64, 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64, 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Wierdo integer stuff */ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Clz64, Iop_Clz32, /* count leading zeroes */ 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */ 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zero. You must ensure they are never given a zero argument. 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Standard integer comparisons */ 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpLT32S, Iop_CmpLT64S, 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpLE32S, Iop_CmpLE64S, 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpLT32U, Iop_CmpLT64U, 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpLE32U, Iop_CmpLE64U, 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* As a sop to Valgrind-Memcheck, the following are useful. */ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64, 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */ 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */ 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max32U, /* unsigned max */ 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* PowerPC-style 3-way integer comparisons. Without them it is 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown difficult to simulate PPC efficiently. 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown op(x,y) | x < y = 0x8 else 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | x > y = 0x4 else 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | x == y = 0x2 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpORD32U, Iop_CmpORD64U, 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpORD32S, Iop_CmpORD64S, 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Division */ 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* TODO: clarify semantics wrt rounding, negative values, whatever */ 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod) 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivS32, // ditto, signed 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod) 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivS64, // ditto, signed 488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_DivU64E, // :: I64,I64 -> I64 (dividend is 64-bit arg (hi) 489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // concat with 64 0's (low)) 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_DivS64E, // ditto, signed 491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_DivU32E, // :: I32,I32 -> I32 (dividend is 32-bit arg (hi) 492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // concat with 32 0's (low)) 493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_DivS32E, // ditto, signed 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivModU64to32, // :: I64,I32 -> I64 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // of which lo half is div and hi half is mod 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivModS64to32, // ditto, signed 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivModU128to64, // :: V128,I64 -> V128 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // of which lo half is div and hi half is mod 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_DivModS128to64, // ditto, signed 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_DivModS64to64, // :: I64,I64 -> I128 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // of which lo half is div and hi half is mod 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Integer conversions. Some of these are redundant (eg 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown having a complete set reduces the typical dynamic size of IR 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and makes the instruction selectors easier to write. */ 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Widening conversions */ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_8Uto16, Iop_8Uto32, Iop_8Uto64, 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_16Uto32, Iop_16Uto64, 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32Uto64, 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_8Sto16, Iop_8Sto32, Iop_8Sto64, 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_16Sto32, Iop_16Sto64, 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32Sto64, 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Narrowing conversions */ 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64to8, Iop_32to8, Iop_64to16, 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8 <-> 16 bit conversions */ 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_16to8, // :: I16 -> I8, low half 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_16HIto8, // :: I16 -> I8, high half 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_8HLto16, // :: (I8,I8) -> I16 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 16 <-> 32 bit conversions */ 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32to16, // :: I32 -> I16, low half 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32HIto16, // :: I32 -> I16, high half 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_16HLto32, // :: (I16,I16) -> I32 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32 <-> 64 bit conversions */ 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64to32, // :: I64 -> I32, low half 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64HIto32, // :: I64 -> I32, high half 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32HLto64, // :: (I32,I32) -> I64 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64 <-> 128 bit conversions */ 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_128to64, // :: I128 -> I64, low half 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_128HIto64, // :: I128 -> I64, high half 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64HLto128, // :: (I64,I64) -> I128 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 1-bit stuff */ 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Not1, /* :: Ity_Bit -> Ity_Bit */ 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */ 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */ 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */ 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */ 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */ 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------ Floating point. We try to be IEEE754 compliant. ------ */ 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Simple stuff as mandated by 754. --- */ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Binary operations, with rounding. */ 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */ 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32, 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Variants of the above which produce a 64-bit result but which 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown round their result to a IEEE float range first. */ 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32, 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unary operations, without rounding. */ 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: F64 -> F64 */ 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_NegF64, Iop_AbsF64, 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: F32 -> F32 */ 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_NegF32, Iop_AbsF32, 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unary operations, with rounding. */ 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 -> F64 */ 574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_SqrtF64, 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F32 -> F32 */ 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SqrtF32, 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following: 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x45 Unordered 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x01 LT 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00 GT 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x40 EQ 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This just happens to be the Intel encoding. The values 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are recorded in the type IRCmpF64Result. 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: F64 x F64 -> IRCmpF64Result(I32) */ 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpF64, 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_CmpF32, 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_CmpF128, 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Int to/from FP conversions. --- */ 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* For the most part, these take a first argument :: Ity_I32 (as 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRoundingMode) which is an indication of the rounding mode 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to use, as per the following encoding ("the standard 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown encoding"): 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 00b to nearest (the default) 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 01b to -infinity 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10b to +infinity 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11b to zero 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This just happens to be the Intel encoding. For reference only, 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the PPC encoding is: 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 00b to nearest (the default) 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 01b to zero 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10b to +infinity 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11b to -infinity 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Any PPC -> IR front end will have to translate these PPC 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown encodings, as encoded in the guest state, to the standard 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown encodings, to pass to the primops. 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For reference only, the ARM VFP encoding is: 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 00b to nearest 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 01b to +infinity 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10b to -infinity 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11b to zero 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Again, this will have to be converted to the standard encoding 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to pass to primops. 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If one of these conversions gets an out-of-range condition, 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or a NaN, as an argument, the result is host-defined. On x86 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the "integer indefinite" value 0x80..00 is produced. On PPC 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it is either 0x80..00 or 0x7F..FF depending on the sign of 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the argument. 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On ARMvfp, when converting to a signed integer result, the 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overflow result is 0x80..00 for negative args and 0x7F..FF 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for positive args. For unsigned integer results it is 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00..00 and 0xFF..FF respectively. 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Rounding is required whenever the destination type cannot 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown represent exactly all values of the source type. 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */ 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */ 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */ 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */ 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */ 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_I32StoF64, /* signed I32 -> F64 */ 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */ 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */ 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */ 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */ 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_I32UtoF64, /* unsigned I32 -> F64 */ 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */ 649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */ 650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */ 651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */ 652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */ 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */ 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Conversion between floating point formats */ 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F32toF64, /* F32 -> F64 */ 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */ 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Reinterpretation. Take an F64 and produce an I64 with 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the same bit pattern, or vice versa. */ 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ReinterpF64asI64, Iop_ReinterpI64asF64, 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ReinterpF32asI32, Iop_ReinterpI32asF32, 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Support for 128-bit floating point */ 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */ 667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */ 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128LOtoF64,/* F128 -> low half of F128 into a F64 register */ 669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */ 671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128, 672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* :: F128 -> F128 */ 674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_NegF128, Iop_AbsF128, 675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* :: IRRoundingMode(I32) x F128 -> F128 */ 677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_SqrtF128, 678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I32StoF128, /* signed I32 -> F128 */ 680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_I64StoF128, /* signed I64 -> F128 */ 681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32UtoF128, /* unsigned I32 -> F128 */ 682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I64UtoF128, /* unsigned I64 -> F128 */ 683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F32toF128, /* F32 -> F128 */ 684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F64toF128, /* F64 -> F128 */ 685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32 */ 687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64 */ 688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32 */ 689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64 */ 690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128toF64, /* IRRoundingMode(I32) x F128 -> F64 */ 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_F128toF32, /* IRRoundingMode(I32) x F128 -> F32 */ 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- guest x86/amd64 specifics, not mandated by 754. --- */ 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Binary ops, with rounding. */ 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */ 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */ 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */ 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */ 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */ 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */ 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */ 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */ 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note that on x86 guest, PRem1{C3210} has the same behaviour 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as the IEEE mandated RemF64, except it is limited in the 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown range of its operand. Hence the partialness. */ 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unary ops, with rounding. */ 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 -> F64 */ 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SinF64, /* FSIN */ 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CosF64, /* FCOS */ 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_TanF64, /* FTAN */ 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_2xm1F64, /* (2^arg - 1.0) */ 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toInt, /* F64 value to nearest integral value (still 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as F64) */ 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF32toInt, /* F32 value to nearest integral value (still 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as F32) */ 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* --- guest s390 specifics, not mandated by 754. --- */ 721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Fused multiply-add/sub */ 723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32 724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (computes arg2 * arg3 +/- arg4) */ 725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_MAddF32, Iop_MSubF32, 726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- guest ppc32/64 specifics, not mandated by 754. --- */ 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ternary operations, with rounding. */ 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Fused multiply-add/sub, with 112-bit intermediate 731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov precision for ppc. 732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Also used to implement fused multiply-add/sub for s390. */ 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (computes arg2 * arg3 +/- arg4) */ 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MAddF64, Iop_MSubF64, 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Variants of the above which produce a 64-bit result but which 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown round their result to a IEEE float range first. */ 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */ 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MAddF64r32, Iop_MSubF64r32, 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: F64 -> F64 */ 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */ 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toF64_NEAREST, /* frin */ 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toF64_NegINF, /* frim */ 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toF64_PosINF, /* frip */ 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toF64_ZERO, /* friz */ 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: F64 -> F32 */ 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */ 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* :: IRRoundingMode(I32) x F64 -> F64 */ 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */ 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* NB: pretty much the same as Iop_F64toF32, except no change 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of type. */ 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------------------ 32-bit SIMD Integer ------------------ */ 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32x1 saturating add/sub (ok, well, not really SIMD :) */ 760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_QAdd32S, 761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_QSub32S, 762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 16x2 add/sub, also signed/unsigned saturating variants */ 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add16x2, Iop_Sub16x2, 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd16Sx2, Iop_QAdd16Ux2, 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub16Sx2, Iop_QSub16Ux2, 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 16x2 signed/unsigned halving add/sub. For each lane, these 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown compute bits 16:1 of (eg) sx(argL) + sx(argR), 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or zx(argL) - zx(argR) etc. */ 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_HAdd16Ux2, Iop_HAdd16Sx2, 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_HSub16Ux2, Iop_HSub16Sx2, 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8x4 add/sub, also signed/unsigned saturating variants */ 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add8x4, Iop_Sub8x4, 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd8Sx4, Iop_QAdd8Ux4, 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub8Sx4, Iop_QSub8Ux4, 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8x4 signed/unsigned halving add/sub. For each lane, these 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown compute bits 8:1 of (eg) sx(argL) + sx(argR), 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or zx(argL) - zx(argR) etc. */ 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_HAdd8Ux4, Iop_HAdd8Sx4, 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_HSub8Ux4, Iop_HSub8Sx4, 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8x4 sum of absolute unsigned differences. */ 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sad8Ux4, 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MISC (vector integer cmp != 0) */ 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNEZ16x2, Iop_CmpNEZ8x4, 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------------------ 64-bit SIMD FP ------------------------ */ 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Convertion to/from int */ 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */ 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */ 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Fixed32 format is floating-point number with fixed number of fraction 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bits. The number of fraction bits is passed as a second argument of 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type I8. */ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */ 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */ 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Binary operations */ 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max32Fx2, Iop_Min32Fx2, 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Pairwise Min and Max. See integer pairwise operations for more 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown details. */ 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMax32Fx2, Iop_PwMin32Fx2, 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: For the following compares, the arm front-end assumes a 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nan in a lane of either argument returns zero for that lane. */ 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2, 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Estimate finds an approximate reciprocal of each 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown element in the operand vector, and places the results in the destination 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vector. */ 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recip32Fx2, 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Step computes (2.0 - arg1 * arg2). 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note, that if one of the arguments is zero and another one is infinity 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of arbitrary sign the result of the operation is 2.0. */ 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recps32Fx2, 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown square root of each element in the operand vector. */ 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Rsqrte32Fx2, 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0. 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note, that of one of the arguments is zero and another one is infiinty 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of arbitrary sign the result of the operation is 1.5. */ 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Rsqrts32Fx2, 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unary */ 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Neg32Fx2, Iop_Abs32Fx2, 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------------------ 64-bit SIMD Integer. ------------------ */ 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MISC (vector integer cmp != 0) */ 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2, 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ADDITION (normal / unsigned sat / signed sat) */ 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add8x8, Iop_Add16x4, Iop_Add32x2, 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1, 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1, 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* PAIRWISE operations */ 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) = 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */ 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2, 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2, 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2, 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2, 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2, 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Longening variant is unary. The resulting vector contains two times 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown less elements than operand, but they are two times wider. 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Example: 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d] 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown where a+b and c+d are unsigned 32-bit values. */ 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2, 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2, 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* SUBTRACTION (normal / unsigned sat / signed sat) */ 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2, 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1, 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1, 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ABSOLUTE VALUE */ 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2, 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */ 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2, 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mul32Fx2, 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MulHi16Ux4, 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MulHi16Sx4, 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Plynomial multiplication treats it's arguments as coefficients of 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown polynoms over {0, 1}. */ 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PolynomialMul8x8, 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Saturating Doubling Multiply Returning High Half and 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vector Saturating Rounding Doubling Multiply Returning High Half */ 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* These IROp's multiply corresponding elements in two vectors, double 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the results, and place the most significant half of the final results 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the destination vector. The results are truncated or rounded. If 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any of the results overflow, they are saturated. */ 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2, 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2, 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Avg8Ux8, 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Avg16Ux4, 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MIN/MAX */ 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2, 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2, 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2, 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2, 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COMPARISON */ 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2, 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2, 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2, 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COUNT ones / leading zeroes / leading sign bits (not including topmost 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bit) */ 902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Cnt8x8, 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2, 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2, 905436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Clz64x2, 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x VECTOR SHIFT / ROTATE */ 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2, 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2, 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2, 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1, 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2, 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2, 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2, 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x VECTOR SATURATING SHIFT */ 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1, 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1, 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x INTEGER SATURATING SHIFT */ 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1, 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1, 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1, 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* NARROWING (binary) 927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov -- narrow 2xI64 into 1xI64, hi half from left arg */ 928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* For saturated narrowing, I believe there are 4 variants of 929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the basic arithmetic operation, depending on the signedness 930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov of argument and result. Here are examples that exemplify 931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov what I mean: 932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255; 934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return x[7:0]; 935b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128; 937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (x >s 127) x = 127; 938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return x[7:0]; 939b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 940b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127; 941b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return x[7:0]; 942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0; 944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (x >s 255) x = 255; 945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return x[7:0]; 946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowBin16Sto8Ux8, 948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4, 949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4, 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* INTERLEAVING */ 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Interleave lanes from low or high halves of 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown operands. Most-significant result lane is from the left 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg. */ 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2, 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2, 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Interleave odd/even lanes of operands. Most-significant result lane 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identical to Interleave{HI,LO}32x2 and so are omitted.*/ 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8, 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4, 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CONCATENATION -- build a new value by concatenating either 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the even or odd lanes of both operands. Note that 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and so are omitted. */ 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CatOddLanes8x8, Iop_CatOddLanes16x4, 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4, 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* GET / SET elements of VECTOR 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GET is binop (I64, I8) -> I<elem_size> 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET is triop (I64, I8, I<elem_size>) -> I64 */ 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the arm back-end handles only constant second argument */ 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2, 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2, 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* DUPLICATING -- copy value to all lanes */ 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2, 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of result and arg3 lowest bytes of arg2 to arg3 highest bytes of 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result. 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It is a triop: (I64, I64, I8) -> I64 */ 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the arm back-end handles only constant third argumnet. */ 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Extract64, 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* REVERSE the order of elements in each Half-words, Words, 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Double-words */ 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Examples: 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g] 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */ 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse16_8x8, 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse32_8x8, Iop_Reverse32_16x4, 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2, 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* PERMUTING -- copy src bytes to dst, 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as indexed by control vector bytes: 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for i in 0 .. 7 . result[i] = argL[ argR[i] ] 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR[i] values may only be in the range 0 .. 7, else behaviour 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is undefined. */ 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Perm8x8, 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1004436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* MISC CONVERSION -- get high bits of each byte lane, a la 1005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov x86/amd64 pmovmskb */ 1006436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_GetMSBs8x8, /* I64 -> I8 */ 1007436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown See floating-point equiwalents for details. */ 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recip32x2, Iop_Rsqrte32x2, 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ------------------ Decimal Floating Point ------------------ */ 1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ARITHMETIC INSTRUCTIONS 64-bit 1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ---------------------------------- 1016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRRoundingMode(I32) X D64 X D64 -> D64 1017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64, 1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ARITHMETIC INSTRUCTIONS 128-bit 1021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ---------------------------------- 1022436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRRoundingMode(I32) X D128 X D128 -> D128 1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128, 1025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* SHIFT SIGNIFICAND INSTRUCTIONS 1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The DFP significand is shifted by the number of digits specified 1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * by the U8 operand. Digits shifted out of the leftmost digit are 1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * lost. Zeros are supplied to the vacated positions on the right. 1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The sign of the result is the same as the sign of the original 1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * operand. 1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * D64 x U8 -> D64 left shift and right shift respectively */ 1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ShlD64, Iop_ShrD64, 1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* D128 x U8 -> D128 left shift and right shift respectively */ 1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ShlD128, Iop_ShrD128, 1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* FORMAT CONVERSION INSTRUCTIONS 1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * D32 -> D64 1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D32toD64, 1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* D64 -> D128 */ 1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D64toD128, 1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1048436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I32S -> D128 */ 1049436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32StoD128, 1050436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1051436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I32U -> D128 */ 1052436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32UtoD128, 1053436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* I64S -> D128 */ 1055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_I64StoD128, 1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1057436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I64U -> D128 */ 1058436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I64UtoD128, 1059436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1060436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> D32 */ 1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D64toD32, 1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1063436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> D64 */ 1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D128toD64, 1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1066436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I32S -> D64 */ 1067436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32StoD64, 1068436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1069436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I32U -> D64 */ 1070436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32UtoD64, 1071436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1072436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x I64 -> D64 */ 1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_I64StoD64, 1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1075436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x I64 -> D64 */ 1076436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I64UtoD64, 1077436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1078436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> I32 */ 1079436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toI32S, 1080436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1081436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> I32 */ 1082436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toI32U, 1083436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1084436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> I64 */ 1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D64toI64S, 1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1087436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> I64 */ 1088436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toI64U, 1089436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1090436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> I32 */ 1091436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toI32S, 1092436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1093436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> I32 */ 1094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toI32U, 1095436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1096436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> I64 */ 1097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D128toI64S, 1098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1099436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> I64 */ 1100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toI64U, 1101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F32 -> D32 */ 1103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F32toD32, 1104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F32 -> D64 */ 1106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F32toD64, 1107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F32 -> D128 */ 1109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F32toD128, 1110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F64 -> D32 */ 1112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F64toD32, 1113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F64 -> D64 */ 1115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F64toD64, 1116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F64 -> D128 */ 1118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F64toD128, 1119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F128 -> D32 */ 1121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F128toD32, 1122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F128 -> D64 */ 1124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F128toD64, 1125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x F128 -> D128 */ 1127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_F128toD128, 1128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D32 -> F32 */ 1130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D32toF32, 1131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D32 -> F64 */ 1133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D32toF64, 1134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D32 -> F128 */ 1136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D32toF128, 1137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> F32 */ 1139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toF32, 1140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> F64 */ 1142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toF64, 1143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D64 -> F128 */ 1145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D64toF128, 1146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> F32 */ 1148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toF32, 1149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> F64 */ 1151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toF64, 1152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 -> F128 */ 1154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_D128toF128, 1155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ROUNDING INSTRUCTIONS 1157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * IRRoundingMode(I32) x D64 -> D64 1158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * The D64 operand, if a finite number, it is rounded to a 1159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * floating point integer value, i.e. no fractional part. 1160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_RoundD64toInt, 1162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* IRRoundingMode(I32) x D128 -> D128 */ 1164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_RoundD128toInt, 1165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* COMPARE INSTRUCTIONS 1167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * D64 x D64 -> IRCmpD64Result(I32) */ 1168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_CmpD64, 1169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* D128 x D128 -> IRCmpD128Result(I32) */ 1171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_CmpD128, 1172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* COMPARE BIASED EXPONENET INSTRUCTIONS 1174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * D64 x D64 -> IRCmpD64Result(I32) */ 1175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpExpD64, 1176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* D128 x D128 -> IRCmpD128Result(I32) */ 1178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpExpD128, 1179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* QUANTIZE AND ROUND INSTRUCTIONS 1181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The source operand is converted and rounded to the form with the 1182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * immediate exponent specified by the rounding and exponent parameter. 1183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 1184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The second operand is converted and rounded to the form 1185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * of the first operand's exponent and the rounded based on the specified 1186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * rounding mode parameter. 1187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 1188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * IRRoundingMode(I32) x D64 x D64-> D64 */ 1189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_QuantizeD64, 1190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x D128 x D128 -> D128 */ 1192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_QuantizeD128, 1193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x I8 x D64 -> D64 1195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The Decimal Floating point operand is rounded to the requested 1196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * significance given by the I8 operand as specified by the rounding 1197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * mode. 1198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_SignificanceRoundD64, 1200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IRRoundingMode(I32) x I8 x D128 -> D128 */ 1202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_SignificanceRoundD128, 1203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* EXTRACT AND INSERT INSTRUCTIONS 1205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * D64 -> I64 1206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The exponent of the D32 or D64 operand is extracted. The 1207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * extracted exponent is converted to a 64-bit signed binary integer. 1208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ExtractExpD64, 1210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* D128 -> I64 */ 1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ExtractExpD128, 1213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* D64 -> I64 1215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * The number of significand digits of the D64 operand is extracted. 1216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * The number is stored as a 64-bit signed binary integer. 1217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 1218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ExtractSigD64, 1219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* D128 -> I64 */ 1221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ExtractSigD128, 1222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I64 x D64 -> D64 1224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * The exponent is specified by the first I64 operand the signed 1225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * significand is given by the second I64 value. The result is a D64 1226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * value consisting of the specified significand and exponent whose 1227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * sign is that of the specified significand. 1228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_InsertExpD64, 1230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* I64 x D128 -> D128 */ 1232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_InsertExpD128, 1233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Support for 128-bit DFP type */ 1235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64, 1236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* I64 -> I64 1238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Convert 50-bit densely packed BCD string to 60 bit BCD string 1239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_DPBtoBCD, 1241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* I64 -> I64 1243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Convert 60 bit BCD string to 50-bit densely packed BCD string 1244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_BCDtoDPB, 1246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* BCD arithmetic instructions, (V128, V128) -> V128 1248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * The BCD format is the same as that used in the BCD<->DPB conversion 1249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * routines, except using 124 digits (vs 60) plus the trailing 4-bit 1250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * signed code. */ 1251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_BCDAdd, Iop_BCDSub, 1252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Conversion I64 -> D64 */ 1254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ReinterpI64asD64, 1255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Conversion D64 -> I64 */ 1257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_ReinterpD64asI64, 1258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------------------ 128-bit SIMD FP. ------------------ */ 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- 32x4 vector FP --- */ 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */ 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 1265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* binary */ 1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max32Fx4, Iop_Min32Fx4, 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add32Fx2, Iop_Sub32Fx2, 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: For the following compares, the ppc and arm front-ends assume a 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nan in a lane of either argument returns zero for that lane. */ 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpGT32Fx4, Iop_CmpGE32Fx4, 1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Pairwise Max and Min. See integer pairwise operations for details. */ 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwMax32Fx4, Iop_PwMin32Fx4, 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unary */ 1278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Abs32Fx4, 1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, 1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Neg32Fx4, 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Estimate finds an approximate reciprocal of each 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown element in the operand vector, and places the results in the destination 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vector. */ 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recip32Fx4, 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Step computes (2.0 - arg1 * arg2). 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note, that if one of the arguments is zero and another one is infinity 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of arbitrary sign the result of the operation is 2.0. */ 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recps32Fx4, 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown square root of each element in the operand vector. */ 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Rsqrte32Fx4, 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0. 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note, that of one of the arguments is zero and another one is infiinty 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of arbitrary sign the result of the operation is 1.5. */ 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Rsqrts32Fx4, 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Int to/from FP conversion --- */ 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unlike the standard fp conversions, these irops take no 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rounding mode argument. Instead the irop trailers _R{M,P,N,Z} 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indicate the mode: {-inf, +inf, nearest, zero} respectively. */ 1305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */ 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */ 1307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (saturating) */ 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */ 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */ 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Fixed32 format is floating-point number with fixed number of fraction 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bits. The number of fraction bits is passed as a second argument of 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type I8. */ 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */ 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */ 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Single to/from half conversion --- */ 1317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */ 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */ 1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- 32x4 lowest-lane-only scalar FP --- */ 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* In binary cases, upper 3/4 is copied from first operand. In 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unary cases, upper 3/4 is copied from the operand. */ 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* binary */ 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max32F0x4, Iop_Min32F0x4, 1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unary */ 1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, 1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- 64x2 vector FP --- */ 1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */ 1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 1337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* binary */ 1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max64Fx2, Iop_Min64Fx2, 1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unary */ 1343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Abs64Fx2, 1344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Sqrt64Fx2, Iop_RSqrt64Fx2, 1345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Neg64Fx2, 1346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Vector Reciprocal Estimate */ 1348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Recip64Fx2, 1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- 64x2 lowest-lane-only scalar FP --- */ 1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* In binary cases, upper half is copied from first operand. In 1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unary cases, upper half is copied from the operand. */ 1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* binary */ 1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Max64F0x2, Iop_Min64F0x2, 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unary */ 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2, 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- pack / unpack --- */ 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64 <-> 128 bit vector */ 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_V128to64, // :: V128 -> I64, low half 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_V128HIto64, // :: V128 -> I64, high half 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64HLtoV128, // :: (I64,I64) -> V128 1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_64UtoV128, 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SetV128lo64, 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Copies lower 64/32/16/8 bits, zeroes out the rest. */ 1374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ZeroHI64ofV128, // :: V128 -> V128 1375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ZeroHI96ofV128, // :: V128 -> V128 1376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ZeroHI112ofV128, // :: V128 -> V128 1377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ZeroHI120ofV128, // :: V128 -> V128 1378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32 <-> 128 bit vector */ 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_32UtoV128, 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_V128to32, // :: V128 -> I32, lowest lane 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SetV128lo32, // :: (V128,I32) -> V128 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------------------ 128-bit SIMD Integer. ------------------ */ 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* BITWISE OPS */ 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_NotV128, 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_AndV128, Iop_OrV128, Iop_XorV128, 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR SHIFT (shift amt :: Ity_I8) */ 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ShlV128, Iop_ShrV128, 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MISC (vector integer cmp != 0) */ 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2, 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ADDITION (normal / unsigned sat / signed sat) */ 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2, 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2, 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2, 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* SUBTRACTION (normal / unsigned sat / signed sat) */ 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2, 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2, 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2, 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MULTIPLICATION (normal / high half of signed/unsigned) */ 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4, 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MulHi16Ux8, Iop_MulHi32Ux4, 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_MulHi16Sx8, Iop_MulHi32Sx4, 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* (widening signed/unsigned of even lanes, with lowest lane=zero) */ 1411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4, 1412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4, 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME: document these */ 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mull8Ux8, Iop_Mull8Sx8, 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mull16Ux4, Iop_Mull16Sx4, 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Mull32Ux2, Iop_Mull32Sx2, 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Saturating Doubling Multiply Returning High Half and 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vector Saturating Rounding Doubling Multiply Returning High Half */ 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* These IROp's multiply corresponding elements in two vectors, double 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the results, and place the most significant half of the final results 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the destination vector. The results are truncated or rounded. If 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any of the results overflow, they are saturated. */ 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4, 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Doubling saturating multiplication (long) (I64, I64) -> V128 */ 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2, 1427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Polynomial multiplication treats its arguments as 1428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov coefficients of polynomials over {0, 1}. */ 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */ 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */ 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Vector Polynomial multiplication add. (V128, V128) -> V128 1433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *** Below is the algorithm for the instructions. These Iops could 1435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov be emulated to get this functionality, but the emulation would 1436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov be long and messy. 1437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Example for polynomial multiply add for vector of bytes 1439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do i = 0 to 15 1440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov prod[i].bit[0:14] <- 0 1441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srcA <- VR[argL].byte[i] 1442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srcB <- VR[argR].byte[i] 1443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do j = 0 to 7 1444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do k = 0 to j 1445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gbit <- srcA.bit[k] & srcB.bit[j-k] 1446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov prod[i].bit[j] <- prod[i].bit[j] ^ gbit 1447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do j = 8 to 14 1451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do k = j-7 to 7 1452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gbit <- (srcA.bit[k] & srcB.bit[j-k]) 1453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov prod[i].bit[j] <- prod[i].bit[j] ^ gbit 1454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do i = 0 to 7 1459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VR[dst].hword[i] <- 0b0 || (prod[2×i] ^ prod[2×i+1]) 1460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov end 1461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 1462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_PolynomialMulAdd8x16, Iop_PolynomialMulAdd16x8, 1463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_PolynomialMulAdd32x4, Iop_PolynomialMulAdd64x2, 1464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* PAIRWISE operations */ 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) = 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */ 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4, 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAdd32Fx2, 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Longening variant is unary. The resulting vector contains two times 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown less elements than operand, but they are two times wider. 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Example: 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d] 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown where a+b and c+d are unsigned 32-bit values. */ 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4, 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4, 1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Other unary pairwise ops */ 1479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Vector bit matrix transpose. (V128) -> V128 */ 1481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* For each doubleword element of the source vector, an 8-bit x 8-bit 1482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * matrix transpose is performed. */ 1483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_PwBitMtxXpose64x2, 1484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ABSOLUTE VALUE */ 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, 1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* MIN/MAX */ 1493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2, 1494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2, 1495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2, 1496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2, 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COMPARISON */ 1499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2, 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2, 1501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, Iop_CmpGT64Ux2, 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COUNT ones / leading zeroes / leading sign bits (not including topmost 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bit) */ 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Cnt8x16, 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4, 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4, 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1509051d3b5d6376aa10a65793c3c2267d6ab233b896Dmitriy Ivanov /* Sum vector (signed/unsigned)*/ 1510051d3b5d6376aa10a65793c3c2267d6ab233b896Dmitriy Ivanov Iop_AddLV8Ux16, Iop_AddLV16Ux8, Iop_AddLV32Ux4, 1511051d3b5d6376aa10a65793c3c2267d6ab233b896Dmitriy Ivanov Iop_AddLV8Sx16, Iop_AddLV16Sx8, Iop_AddLV32Sx4, 1512051d3b5d6376aa10a65793c3c2267d6ab233b896Dmitriy Ivanov 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2, 1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2, 1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2, 1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x VECTOR SHIFT / ROTATE */ 1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2, 1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2, 1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2, 1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2, 1523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2, 1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x VECTOR SATURATING SHIFT */ 1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2, 1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2, 1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VECTOR x INTEGER SATURATING SHIFT */ 1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2, 1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2, 1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2, 1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* NARROWING (binary) 1534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov -- narrow 2xV128 into 1xV128, hi half from left arg */ 1535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* See comments above w.r.t. U vs S issues in saturated narrowing. */ 1536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8, 1537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8, 1538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8, 1539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8, 1540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QNarrowBin64Sto32Sx4, Iop_QNarrowBin64Uto32Ux4, 1541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_NarrowBin64to32x4, 1542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* NARROWING (unary) -- narrow V128 into I64 */ 1544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2, 1545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Saturating narrowing from signed source to signed/unsigned 1546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov destination */ 1547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2, 1548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2, 1549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Saturating narrowing from unsigned source to unsigned destination */ 1550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2, 1551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* WIDENING -- sign or zero extend each element of the argument 1553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vector to the twice original size. The resulting vector consists of 1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the same number of elements but each element and the vector itself 1555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov are twice as wide. 1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown All operations are I64->V128. 1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Example 1558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_Widen32Sto64x2( [a, b] ) = [c, d] 1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */ 1560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2, 1561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2, 1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* INTERLEAVING */ 1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Interleave lanes from low or high halves of 1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown operands. Most-significant result lane is from the left 1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg. */ 1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveHI8x16, Iop_InterleaveHI16x8, 1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveHI32x4, Iop_InterleaveHI64x2, 1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, 1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveLO32x4, Iop_InterleaveLO64x2, 1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Interleave odd/even lanes of operands. Most-significant result lane 1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is from the left arg. */ 1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16, 1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8, 1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4, 1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CONCATENATION -- build a new value by concatenating either 1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the even or odd lanes of both operands. */ 1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4, 1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4, 1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* GET elements of VECTOR 1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GET is binop (V128, I8) -> I<elem_size> */ 1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the arm back-end handles only constant second argument. */ 1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2, 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* DUPLICATING -- copy value to all lanes */ 1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4, 1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes 1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of result and arg3 lowest bytes of arg2 to arg3 highest bytes of 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result. 1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It is a triop: (V128, V128, I8) -> V128 */ 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the ARM back end handles only constant arg3 in this operation. */ 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_ExtractV128, 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* REVERSE the order of elements in each Half-words, Words, 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Double-words */ 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Examples: 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g] 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */ 1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse16_8x16, 1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse32_8x16, Iop_Reverse32_16x8, 1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4, 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* PERMUTING -- copy src bytes to dst, 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as indexed by control vector bytes: 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for i in 0 .. 15 . result[i] = argL[ argR[i] ] 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR[i] values may only be in the range 0 .. 15, else behaviour 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is undefined. */ 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Perm8x16, 1612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */ 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* MISC CONVERSION -- get high bits of each byte lane, a la 1615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov x86/amd64 pmovmskb */ 1616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_GetMSBs8x16, /* V128 -> I16 */ 1617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate 1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown See floating-point equiwalents for details. */ 1620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Recip32x4, Iop_Rsqrte32x4, 1621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ------------------ 256-bit SIMD Integer. ------------------ */ 1623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Pack/unpack */ 1625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256to64_0, // V256 -> I64, extract least significant lane 1626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256to64_1, 1627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256to64_2, 1628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256to64_3, // V256 -> I64, extract most significant lane 1629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_64x4toV256, // (I64,I64,I64,I64)->V256 1631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // first arg is most significant lane 1632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256toV128_0, // V256 -> V128, less significant lane 1634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V256toV128_1, // V256 -> V128, more significant lane 1635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif 1636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_AndV256, 1638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_OrV256, 1639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_XorV256, 1640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_NotV256, 1641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* MISC (vector integer cmp != 0) */ 1643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4, 1644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Add8x32, Iop_Add16x16, Iop_Add32x8, Iop_Add64x4, 1646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Sub8x32, Iop_Sub16x16, Iop_Sub32x8, Iop_Sub64x4, 1647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpEQ8x32, Iop_CmpEQ16x16, Iop_CmpEQ32x8, Iop_CmpEQ64x4, 1649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4, 1650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4, 1652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4, 1653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_SarN16x16, Iop_SarN32x8, 1654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8, 1656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8, 1657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8, 1658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8, 1659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Mul16x16, Iop_Mul32x8, 1661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_MulHi16Ux16, Iop_MulHi16Sx16, 1662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QAdd8Ux32, Iop_QAdd16Ux16, 1664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QAdd8Sx32, Iop_QAdd16Sx16, 1665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QSub8Ux32, Iop_QSub16Ux16, 1666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_QSub8Sx32, Iop_QSub16Sx16, 1667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Avg8Ux32, Iop_Avg16Ux16, 1669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Perm32x8, 1671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (V128, V128) -> V128 */ 1673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_CipherV128, Iop_CipherLV128, Iop_CipherSV128, 1674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_NCipherV128, Iop_NCipherLV128, 1675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Hash instructions, Federal Information Processing Standards 1677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Publication 180-3 Secure Hash Standard. */ 1678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (V128, I8) -> V128; The I8 input arg is (ST | SIX), where ST and 1679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * SIX are fields from the insn. See ISA 2.07 description of 1680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * vshasigmad and vshasigmaw insns.*/ 1681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_SHA512, Iop_SHA256, 1682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* ------------------ 256-bit SIMD FP. ------------------ */ 1684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* ternary :: IRRoundingMode(I32) x V256 x V256 -> V256 */ 1686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Add64Fx4, Iop_Sub64Fx4, Iop_Mul64Fx4, Iop_Div64Fx4, 1687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Add32Fx8, Iop_Sub32Fx8, Iop_Mul32Fx8, Iop_Div32Fx8, 1688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Sqrt32Fx8, 1690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Sqrt64Fx4, 1691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_RSqrt32Fx8, 1692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Recip32Fx8, 1693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Max32Fx8, Iop_Min32Fx8, 1695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_Max64Fx4, Iop_Min64Fx4, 1696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iop_LAST /* must be the last enumerator */ 1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp; 1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an op. */ 1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIROp ( IROp ); 1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Encoding of IEEE754-specified rounding modes. 1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note, various front and back ends rely on the actual numerical 1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown values of these, so do not change them. */ 1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 1709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_NEAREST = 0, // Round to nearest, ties to even 1710436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_NegINF = 1, // Round to negative infinity 1711436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_PosINF = 2, // Round to positive infinity 1712436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_ZERO = 3, // Round toward zero 1713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0 1714436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_PREPARE_SHORTER = 5, // Round to prepare for shorter 1715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // precision 1716436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_AWAY_FROM_ZERO = 6, // Round to away from 0 1717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Irrm_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0 1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRoundingMode; 1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1721436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Binary floating point comparison result values. 1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This is also derived from what IA32 does. */ 1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ircr_UN = 0x45, 1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ircr_LT = 0x01, 1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ircr_GT = 0x00, 1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ircr_EQ = 0x40 1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRCmpFResult; 1731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpFResult IRCmpF32Result; 1733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpFResult IRCmpF64Result; 1734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpFResult IRCmpF128Result; 1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Decimal floating point result values. */ 1737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpFResult IRCmpDResult; 1738436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpDResult IRCmpD64Result; 1739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef IRCmpDResult IRCmpD128Result; 1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Expressions ------------------ */ 1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct _IRQop IRQop; /* forward declaration */ 1744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct _IRTriop IRTriop; /* forward declaration */ 1745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The different kinds of expressions. Their meaning is explained below 1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the comments for IRExpr. */ 1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 1751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iex_Binder=0x1900, 1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Get, 1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_GetI, 1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_RdTmp, 1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Qop, 1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Triop, 1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Binop, 1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Unop, 1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Load, 1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iex_Const, 1761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iex_ITE, 1762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iex_CCall, 1763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iex_VECRET, 1764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Iex_BBPTR 1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExprTag; 1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* An expression. Stored as a tagged union. 'tag' indicates what kind 1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of expression this is. 'Iex' is the union that holds the fields. If 1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load 1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expression, and the fields can be accessed with 1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'e.Iex.Load.<fieldname>'. 1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For each kind of expression, we show what it looks like when 1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pretty-printed with ppIRExpr(). 1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _IRExpr 1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr; 1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _IRExpr { 1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExprTag tag; 1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Used only in pattern matching within Vex. Should not be seen 1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown outside of Vex. */ 1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int binder; 1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Binder; 1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read a guest register, at a fixed offset in the guest state. 1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0) 1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int offset; /* Offset into the guest state */ 1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType ty; /* Type of the value being read */ 1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Get; 1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read a guest register at a non-fixed offset in the guest 1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state. This allows circular indexing into parts of the guest 1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state, which is essential for modelling situations where the 1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identity of guest registers is not known until run time. One 1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown example is the x87 FP register stack. 1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The part of the guest state to be treated as a circular array 1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is described in the IRRegArray 'descr' field. It holds the 1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown offset of the first element in the array, the type of each 1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown element, and the number of elements. 1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The array index is indicated rather indirectly, in a way 1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which makes optimisation easy: as the sum of variable part 1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (the 'ix' field) and a constant offset (the 'bias' field). 1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Since the indexing is circular, the actual array index to use 1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is computed as (ix + bias) % num-of-elems-in-the-array. 1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Here's an example. The description 1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (96:8xF64)[t39,-7] 1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describes an array of 8 F64-typed values, the 1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest-state-offset of the first being 96. This array is 1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown being indexed at (t39 - 7) % 8. 1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It is important to get the array size/type exactly correct 1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since IR optimisation looks closely at such info in order to 1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown establish aliasing/non-aliasing between seperate GetI and 1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PutI events, which is used to establish when they can be 1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reordered, etc. Putting incorrect info in will lead to 1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown obscure IR optimisation bugs. 1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: GETI<descr>[<ix>,<bias] 1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. GETI(128:8xI8)[t1,0] 1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descr; /* Part of guest state treated as circular */ 1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* ix; /* Variable part of index into array */ 1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int bias; /* Constant offset part of index into array */ 1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } GetI; 1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The value held by a temporary. 1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: t<tmp>, eg. t1 1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp tmp; /* The temporary number */ 1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } RdTmp; 1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A quaternary operation. 1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>), 1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. MAddF64r32(t1, t2, t3, t4) 1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRQop* details; 1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Qop; 1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A ternary operation. 1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>), 1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. MulF64(1, 2.0, 3.0) 1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTriop* details; 1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Triop; 1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A binary operation. 1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2) 1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; /* op-code */ 1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* arg1; /* operand 1 */ 1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* arg2; /* operand 2 */ 1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Binop; 1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A unary operation. 1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <op>(<arg>), eg. Neg8(t1) 1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; /* op-code */ 1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* arg; /* operand */ 1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Unop; 1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A load from memory -- a normal load, not a load-linked. 1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Load-Linkeds (and Store-Conditionals) are instead represented 1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by IRStmt.LLSC since Load-Linkeds have side effects and so 1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are not semantically valid IRExpr's. 1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1) 1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness end; /* Endian-ness of the load */ 1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType ty; /* Type of the loaded value */ 1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* addr; /* Address being loaded from */ 1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Load; 1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A constant-valued expression. 1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <con>, eg. 0x4:I32 1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst* con; /* The constant itself */ 1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Const; 1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A call to a pure (no side-effects) helper C function. 1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown With the 'cee' field, 'name' is the function's name. It is 1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown only used for pretty-printing purposes. The address to call 1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (host address, of course) is stored in the 'addr' field 1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inside 'cee'. 1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The 'args' field is a NULL-terminated array of arguments. 1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The stated return IRType, and the implied argument types, 1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown must match that of the function being called well enough so 1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that the back end can actually generate correct code for the 1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown call. 1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The called function **must** satisfy the following: 1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * no side effects -- must be a pure function, the result of 1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which depends only on the passed parameters. 1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * it may not look at, nor modify, any of the guest state 1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since that would hide guest state transitions from 1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instrumenters 1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * it may not access guest memory, since that would hide 1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest memory transactions from the instrumenters 1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * it must not assume that arguments are being evaluated in a 1925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng particular order. The oder of evaluation is unspecified. 1926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This is restrictive, but makes the semantics clean, and does 1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not interfere with IR optimisation. 1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If you want to call a helper which can mess with guest state 1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and/or memory, instead use Ist_Dirty. This is a lot more 1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flexible, but you have to give a bunch of details about what 1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the helper does (and you better be telling the truth, 1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown otherwise any derived instrumentation will be wrong). Also 1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_Dirty inhibits various IR optimisations and so can cause 1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown quite poor code to be generated. Try to avoid it. 1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1938436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov In principle it would be allowable to have the arg vector 1939436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov contain an IRExpr_VECRET(), although not IRExpr_BBPTR(). However, 1940436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov at the moment there is no requirement for clean helper calls to 1941436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov be able to return V128 or V256 values. Hence this is not allowed. 1942436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr output: <cee>(<args>):<retty> 1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. foo{0x80489304}(t1, t2):I32 1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCallee* cee; /* Function to call. */ 1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType retty; /* Type of return value. */ 1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args; /* Vector of argument expressions. */ 1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } CCall; 1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1952436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* A ternary if-then-else operator. It returns iftrue if cond is 1953436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nonzero, iffalse otherwise. Note that it is STRICT, ie. both 1954436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iftrue and iffalse are evaluated in all cases. 1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1956436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>), 1957436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov eg. ITE(t6,t7,t8) 1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* cond; /* Condition */ 1961436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* iftrue; /* True expression */ 1962436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* iffalse; /* False expression */ 1963436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } ITE; 1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Iex; 1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1967436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Expression auxiliaries: a ternary expression. */ 1968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _IRTriop { 1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IROp op; /* op-code */ 1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg1; /* operand 1 */ 1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg2; /* operand 2 */ 1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg3; /* operand 3 */ 1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 1974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1975436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Expression auxiliaries: a quarternary expression. */ 1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _IRQop { 1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IROp op; /* op-code */ 1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg1; /* operand 1 */ 1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg2; /* operand 2 */ 1980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg3; /* operand 3 */ 1981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg4; /* operand 4 */ 1982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 1983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1984436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1985436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Two special kinds of IRExpr, which can ONLY be used in 1986436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argument lists for dirty helper calls (IRDirty.args) and in NO 1987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov OTHER PLACES. And then only in very limited ways. */ 1988436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1989436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Denotes an argument which (in the helper) takes a pointer to a 1990436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (naturally aligned) V128 or V256, into which the helper is expected 1991436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to write its result. Use of IRExpr_VECRET() is strictly 1992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov controlled. If the helper returns a V128 or V256 value then 1993436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr_VECRET() must appear exactly once in the arg list, although 1994436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov it can appear anywhere, and the helper must have a C 'void' return 1995436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov type. If the helper returns any other type, IRExpr_VECRET() may 1996436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov not appear in the argument list. */ 1997436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1998436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Denotes an void* argument which is passed to the helper, which at 1999436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov run time will point to the thread's guest state area. This can 2000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov only appear at most once in an argument list, and it may not appear 2001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov at all in argument lists for clean helper calls. */ 2002436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2003436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic inline Bool is_IRExpr_VECRET_or_BBPTR ( IRExpr* e ) { 2004436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return e->tag == Iex_VECRET || e->tag == Iex_BBPTR; 2005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 2006436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2007436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Expression constructors. */ 2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Binder ( Int binder ); 2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Get ( Int off, IRType ty ); 2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ); 2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_RdTmp ( IRTemp tmp ); 2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2, 2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* arg3, IRExpr* arg4 ); 2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1, 2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* arg2, IRExpr* arg3 ); 2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ); 2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_Const ( IRConst* con ); 2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ); 2022436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRExpr* IRExpr_ITE ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse ); 2023436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRExpr* IRExpr_VECRET ( void ); 2024436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRExpr* IRExpr_BBPTR ( void ); 2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRExpr. */ 2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* deepCopyIRExpr ( IRExpr* ); 2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRExpr. */ 2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRExpr ( IRExpr* ); 2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* NULL-terminated IRExpr vector constructors, suitable for 2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use as arg lists in clean/dirty helper calls. */ 2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_0 ( void ); 2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_1 ( IRExpr* ); 2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* ); 2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* ); 2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* ); 2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* ); 2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr*, IRExpr* ); 2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr*, IRExpr*, IRExpr* ); 2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr*, IRExpr*, IRExpr*, IRExpr*); 2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* IRExpr copiers: 2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - shallowCopy: shallow-copy (ie. create a new vector that shares the 2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elements with the original). 2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - deepCopy: deep-copy (ie. create a completely new vector). */ 2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** shallowCopyIRExprVec ( IRExpr** ); 2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr** deepCopyIRExprVec ( IRExpr** ); 2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a constant expression from the given host word taking into 2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown account (of course) the host word size. */ 2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRExpr* mkIRExpr_HWord ( HWord ); 2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convenience function for constructing clean helper calls. */ 2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern 2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRExpr* mkIRExprCCall ( IRType retty, 2062436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int regparms, const HChar* name, void* addr, 2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args ); 2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or 2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Iex_Const). */ 2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool isIRAtom ( IRExpr* e ) { 2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const); 2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Are these two IR atoms identical? Causes an assertion 2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown failure if they are passed non-atoms. */ 2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool eqIRAtom ( IRExpr*, IRExpr* ); 2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Jump kinds ------------------ */ 2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This describes hints which can be passed to the dispatcher at guest 2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown control-flow transfer points. 2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2082eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Re Ijk_InvalICache and Ijk_FlushDCache: the guest state _must_ have 2083eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov two pseudo-registers, guest_CMSTART and guest_CMLEN, which specify 2084eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov the start and length of the region to be invalidated. CM stands 2085eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov for "Cache Management". These are both the size of a guest word. 2086eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov It is the responsibility of the relevant toIR.c to ensure that 2087eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov these are filled in with suitable values before issuing a jump of 2088eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov kind Ijk_InvalICache or Ijk_FlushDCache. 2089eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov 2090eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Ijk_InvalICache requests invalidation of translations taken from 2091eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov the requested range. Ijk_FlushDCache requests flushing of the D 2092eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov cache for the specified range. 2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a 2095436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pseudo-register guest_EMNOTE, which is 32-bits regardless of the 2096436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov host or guest word size. That register should be made to hold a 2097436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote value to indicate the reason for the exit. 2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In the case of Ijk_EmFail, the exit is fatal (Vex-generated code 2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cannot continue) and so the jump destination can be anything. 2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Re Ijk_Sys_ (syscall jumps): the guest state must have a 2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest 2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown word. Front ends should set this to be the IP at the most recently 2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown executed kernel-entering (system call) instruction. This makes it 2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown very much easier (viz, actually possible at all) to back up the 2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest to restart a syscall that has been interrupted by a signal. 2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng enum { 2111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_INVALID=0x1A00, 2112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ijk_Boring, /* not interesting; just goto next */ 2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Call, /* guest is doing a call */ 2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Ret, /* guest is doing a return */ 2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_ClientReq, /* do guest client req before continuing */ 2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Yield, /* client is yielding to thread scheduler */ 2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_EmWarn, /* report emulation warning before continuing */ 2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_EmFail, /* emulation critical (FATAL) error; give up */ 2119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_NoDecode, /* current instruction cannot be decoded */ 2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_MapFail, /* Vex-provided address translation failed */ 2121eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Ijk_InvalICache, /* Inval icache for range [CMSTART, +CMLEN) */ 2122eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Ijk_FlushDCache, /* Flush dcache for range [CMSTART, +CMLEN) */ 2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_NoRedir, /* Jump to un-redirected guest addr */ 2124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_SigILL, /* current instruction synths SIGILL */ 2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_SigTRAP, /* current instruction synths SIGTRAP */ 2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_SigSEGV, /* current instruction synths SIGSEGV */ 2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_SigBUS, /* current instruction synths SIGBUS */ 2128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_SigFPE_IntDiv, /* current instruction synths SIGFPE - IntDiv */ 2129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_SigFPE_IntOvf, /* current instruction synths SIGFPE - IntOvf */ 2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Unfortunately, various guest-dependent syscall kinds. They 2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown all mean: do a syscall before continuing. */ 2132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_Sys_syscall, /* amd64/x86 'syscall', ppc 'sc', arm 'svc #0' */ 2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Sys_int32, /* amd64/x86 'int $0x20' */ 2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Sys_int128, /* amd64/x86 'int $0x80' */ 2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Sys_int129, /* amd64/x86 'int $0x81' */ 2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ijk_Sys_int130, /* amd64/x86 'int $0x82' */ 2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes 2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalid at the point this happens. */ 2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRJumpKind; 2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRJumpKind ( IRJumpKind ); 2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Dirty helper calls ------------------ */ 2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A dirty call is a flexible mechanism for calling (possibly 2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown conditionally) a helper function or procedure. The helper function 2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown may read, write or modify client memory, and may read, write or 2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify client state. It can take arguments and optionally return a 2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value. It may return different results and/or do different things 2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when called repeatedly with the same arguments, by means of storing 2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private state. 2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If a value is returned, it is assigned to the nominated return 2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown temporary. 2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Dirty calls are statements rather than expressions for obvious 2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reasons. If a dirty call is marked as writing guest state, any 2160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pre-existing values derived from the written parts of the guest 2161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov state are invalid. Similarly, if the dirty call is stated as 2162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov writing memory, any pre-existing loaded values are invalidated by 2163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov it. 2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In order that instrumentation is possible, the call must state, and 2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state correctly: 2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Whether it reads, writes or modifies memory, and if so where. 2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Whether it reads, writes or modifies guest state, and if so which 2171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pieces. Several pieces may be stated, and their extents must be 2172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov known at translation-time. Each piece is allowed to repeat some 2173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov number of times at a fixed interval, if required. 2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Normally, code is generated to pass just the args to the helper. 2176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov However, if IRExpr_BBPTR() is present in the argument list (at most 2177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov one instance is allowed), then the baseblock pointer is passed for 2178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov that arg, so that the callee can access the guest state. It is 2179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov invalid for .nFxState to be zero but IRExpr_BBPTR() to be present, 2180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov since .nFxState==0 is a claim that the call does not access guest 2181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov state. 2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The 2184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov arguments and 'mFx' are evaluated REGARDLESS of the guard value. 2185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov The order of argument evaluation is unspecified. The guard 2186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov expression is evaluated AFTER the arguments and 'mFx' have been 2187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov evaluated. 'mFx' is expected (by Memcheck) to be a defined value 2188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov even if the guard evaluates to false. 2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */ 2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Effects on resources (eg. registers, memory locations) */ 2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 2196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ifx_None=0x1B00, /* no effect */ 2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ifx_Read, /* reads the resource */ 2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ifx_Write, /* writes the resource */ 2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ifx_Modify, /* modifies the resource */ 2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREffect; 2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IREffect */ 2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIREffect ( IREffect ); 2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct _IRDirty { 2208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* What to call, and details of args/results. .guard must be 2209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov non-NULL. If .tmp is not IRTemp_INVALID, then the call 2210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov returns a result which is placed in .tmp. If at runtime the 2211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov guard evaluates to false, .tmp has an 0x555..555 bit pattern 2212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov written to it. Hence conditional calls that assign .tmp are 2213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng allowed. */ 2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCallee* cee; /* where to call */ 2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */ 2216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The args vector may contain IRExpr_BBPTR() and/or 2217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr_VECRET(), in both cases, at most once. */ 2218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr** args; /* arg vector, ends in NULL. */ 2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */ 2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Mem effects; we allow only one R/W/M region to be stated */ 2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREffect mFx; /* indicates memory effects, if any */ 2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */ 2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int mSize; /* of access, or zero if mFx==Ifx_None */ 2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Guest state effects; up to N allowed */ 2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int nFxState; /* must be 0 .. VEX_N_FXSTATE */ 2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */ 2230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort offset; 2231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort size; 2232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar nRepeats; 2233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar repeatLen; 2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } fxState[VEX_N_FXSTATE]; 2235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* The access can be repeated, as specified by nRepeats and 2236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng repeatLen. To describe only a single access, nRepeats and 2237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng repeatLen should be zero. Otherwise, repeatLen must be a 2238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng multiple of size and greater than size. */ 2239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Overall, the parts of the guest state denoted by (offset, 2240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size, nRepeats, repeatLen) is 2241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [offset, +size) 2242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and, if nRepeats > 0, 2243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 1; i <= nRepeats; i++) 2244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [offset + i * repeatLen, +size) 2245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng A convenient way to enumerate all segments is therefore 2246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 1 + nRepeats; i++) 2247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [offset + i * repeatLen, +size) 2248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty; 2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print a dirty call */ 2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRDirty ( IRDirty* ); 2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate an uninitialised dirty call */ 2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRDirty* emptyIRDirty ( void ); 2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy a dirty call */ 2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRDirty* deepCopyIRDirty ( IRDirty* ); 2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A handy function which takes some of the tedium out of constructing 2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dirty helper calls. The called function impliedly does not return 2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any value and has a constant-True guard. The call is marked as 2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown accessing neither guest state nor memory (hence the "unsafe" 2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown designation) -- you can change this marking later if need be. A 2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown suitable IRCallee is constructed from the supplied bits. */ 2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern 2268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovIRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr, 2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args ); 2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Similarly, make a zero-annotation dirty call which returns a value, 2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and assign that to the given temp. */ 2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern 2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRDirty* unsafeIRDirty_1_N ( IRTemp dst, 2275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int regparms, const HChar* name, void* addr, 2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args ); 2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Memory Bus Events --------------- */ 2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 2283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Imbe_Fence=0x1C00, 2284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Needed only on ARM. It cancels a reservation made by a 2285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov preceding Linked-Load, and needs to be handed through to the 2286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov back end, just as LL and SC themselves are. */ 2287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Imbe_CancelReservation 2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRMBusEvent; 2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRMBusEvent ( IRMBusEvent ); 2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------- Compare and Swap --------------- */ 2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This denotes an atomic compare and swap operation, either 2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a single-element one or a double-element one. 2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In the single-element case: 2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .addr is the memory address. 2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .end is the endianness with which memory is accessed 2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If .addr contains the same value as .expdLo, then .dataLo is 2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown written there, else there is no write. In both cases, the 2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown original value at .addr is copied into .oldLo. 2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Types: .expdLo, .dataLo and .oldLo must all have the same type. 2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It may be any integral type, viz: I8, I16, I32 or, for 64-bit 2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guests, I64. 2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must 2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be NULL. 2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In the double-element case: 2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .addr is the memory address. 2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .end is the endianness with which memory is accessed 2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The operation is the same: 2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If .addr contains the same value as .expdHi:.expdLo, then 2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .dataHi:.dataLo is written there, else there is no write. In 2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown both cases the original value at .addr is copied into 2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .oldHi:.oldLo. 2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must 2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown all have the same type, which may be any integral type, viz: I8, 2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown I16, I32 or, for 64-bit guests, I64. 2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The double-element case is complicated by the issue of 2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown endianness. In all cases, the two elements are understood to be 2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown located adjacently in memory, starting at the address .addr. 2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If .end is Iend_LE, then the .xxxLo component is at the lower 2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address and the .xxxHi component is at the higher address, and 2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each component is itself stored little-endianly. 2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If .end is Iend_BE, then the .xxxHi component is at the lower 2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address and the .xxxLo component is at the higher address, and 2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each component is itself stored big-endianly. 2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This allows representing more cases than most architectures can 2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handle. For example, x86 cannot do DCAS on 8- or 16-bit elements. 2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown How to know if the CAS succeeded? 2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo), 2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now 2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stored at .addr, and the original value there was .oldLo (resp 2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .oldHi:.oldLo). 2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo), 2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown then the CAS failed, and the original value at .addr was .oldLo 2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (resp. .oldHi:.oldLo). 2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Hence it is easy to know whether or not the CAS succeeded. 2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp oldHi; /* old value of *addr is written here */ 2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp oldLo; 2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness end; /* endianness of the data in memory */ 2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* addr; /* store address */ 2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* expdHi; /* expected old value at *addr */ 2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* expdLo; 2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* dataHi; /* new value for *addr */ 2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* dataLo; 2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS; 2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRCAS ( IRCAS* cas ); 2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo, 2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness end, IRExpr* addr, 2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* expdHi, IRExpr* expdLo, 2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* dataHi, IRExpr* dataLo ); 2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRCAS* deepCopyIRCAS ( IRCAS* ); 2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------ Circular Array Put ------------------ */ 2383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef 2385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct { 2386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRRegArray* descr; /* Part of guest state treated as circular */ 2387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* ix; /* Variable part of index into array */ 2388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int bias; /* Constant offset part of index into array */ 2389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* data; /* The value to write */ 2390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } IRPutI; 2391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern void ppIRPutI ( IRPutI* puti ); 2393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix, 2395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int bias, IRExpr* data ); 2396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRPutI* deepCopyIRPutI ( IRPutI* ); 2398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* --------------- Guarded loads and stores --------------- */ 2401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Conditional stores are straightforward. They are the same as 2403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov normal stores, with an extra 'guard' field :: Ity_I1 that 2404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov determines whether or not the store actually happens. If not, 2405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov memory is unmodified. 2406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov The semantics of this is that 'addr' and 'data' are fully evaluated 2408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov even in the case where 'guard' evaluates to zero (false). 2409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 2410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef 2411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct { 2412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IREndness end; /* Endianness of the store */ 2413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr; /* store address */ 2414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* data; /* value to write */ 2415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard; /* Guarding value */ 2416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRStoreG; 2418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Conditional loads are a little more complex. 'addr' is the 2420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov address, 'guard' is the guarding condition. If the load takes 2421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov place, the loaded value is placed in 'dst'. If it does not take 2422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov place, 'alt' is copied to 'dst'. However, the loaded value is not 2423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov placed directly in 'dst' -- it is first subjected to the conversion 2424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov specified by 'cvt'. 2425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2426436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov For example, imagine doing a conditional 8-bit load, in which the 2427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov loaded value is zero extended to 32 bits. Hence: 2428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * 'dst' and 'alt' must have type I32 2429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * 'cvt' must be a unary op which converts I8 to I32. In this 2430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov example, it would be ILGop_8Uto32. 2431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov There is no explicit indication of the type at which the load is 2433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov done, since that is inferrable from the arg type of 'cvt'. Note 2434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov that the types of 'alt' and 'dst' and the result type of 'cvt' must 2435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov all be the same. 2436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Semantically, 'addr' is evaluated even in the case where 'guard' 2438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov evaluates to zero (false), and 'alt' is evaluated even when 'guard' 2439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov evaluates to one (true). That is, 'addr' and 'alt' are always 2440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov evaluated. 2441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 2442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef 2443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov enum { 2444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_INVALID=0x1D00, 2445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_Ident32, /* 32 bit, no conversion */ 2446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_16Uto32, /* 16 bit load, Z-widen to 32 */ 2447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_16Sto32, /* 16 bit load, S-widen to 32 */ 2448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_8Uto32, /* 8 bit load, Z-widen to 32 */ 2449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ILGop_8Sto32 /* 8 bit load, S-widen to 32 */ 2450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRLoadGOp; 2452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef 2454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct { 2455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IREndness end; /* Endianness of the load */ 2456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRLoadGOp cvt; /* Conversion to apply to the loaded value */ 2457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRTemp dst; /* Destination (LHS) of assignment */ 2458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr; /* Address being loaded from */ 2459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* alt; /* Value if load is not done. */ 2460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard; /* Guarding value */ 2461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRLoadG; 2463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void ppIRStoreG ( IRStoreG* sg ); 2465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void ppIRLoadGOp ( IRLoadGOp cvt ); 2467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void ppIRLoadG ( IRLoadG* lg ); 2469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRStoreG* mkIRStoreG ( IREndness end, 2471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr, IRExpr* data, 2472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard ); 2473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt, 2475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRTemp dst, IRExpr* addr, IRExpr* alt, 2476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard ); 2477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Statements ------------------ */ 2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The different kinds of statements. Their meaning is explained 2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown below in the comments for IRStmt. 2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Those marked META do not represent code, but rather extra 2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown information about the code. These statements can be removed 2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without affecting the functional behaviour of the code, however 2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown they are required by some IR consumers such as tools that 2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instrument the code. 2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 2493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ist_NoOp=0x1E00, 2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_IMark, /* META */ 2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_AbiHint, /* META */ 2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_Put, 2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_PutI, 2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_WrTmp, 2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_Store, 2500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ist_LoadG, 2501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ist_StoreG, 2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_CAS, 2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_LLSC, 2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_Dirty, 2505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ist_MBE, 2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ist_Exit 2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmtTag; 2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A statement. Stored as a tagged union. 'tag' indicates what kind 2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of expression this is. 'Ist' is the union that holds the fields. 2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store 2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown statement, and the fields can be accessed with 2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'st.Ist.Store.<fieldname>'. 2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For each kind of statement, we show what it looks like when 2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pretty-printed with ppIRStmt(). 2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _IRStmt { 2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmtTag tag; 2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A no-op (usually resulting from IR optimisation). Can be 2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown omitted without any effect. 2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: IR-NoOp 2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } NoOp; 2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* META: instruction mark. Marks the start of the statements 2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that represent a single machine instruction (the end of 2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown those statements is marked by the next IMark or the end of 2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the IRSB). Contains the address and length of the 2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction. 2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov It also contains a delta value. The delta must be 2538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov subtracted from a guest program counter value before 2539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov attempting to establish, by comparison with the address 2540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and length values, whether or not that program counter 2541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov value refers to this instruction. For x86, amd64, ppc32, 2542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ppc64 and arm, the delta value is zero. For Thumb 2543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov instructions, the delta value is one. This is because, on 2544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Thumb, guest PC values (guest_R15T) are encoded using the 2545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov top 31 bits of the instruction address and a 1 in the lsb; 2546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov hence they appear to be (numerically) 1 past the start of 2547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the instruction they refer to. IOW, guest_R15T on ARM 2548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov holds a standard ARM interworking address. 2549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------, 2551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eg. ------ IMark(0x4000792, 5, 0) ------, 2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr64 addr; /* instruction address */ 2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int len; /* instruction length */ 2556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar delta; /* addr = program counter as encoded in guest state 2557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov - delta */ 2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } IMark; 2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* META: An ABI hint, which says something about this 2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown platform's ABI. 2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown At the moment, the only AbiHint is one which indicates 2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that a given chunk of address space, [base .. base+len-1], 2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has become undefined. This is used on amd64-linux and 2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown some ppc variants to pass stack-redzoning hints to whoever 2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wants to see them. It also indicates the address of the 2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next (dynamic) instruction that will be executed. This is 2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to help Memcheck to origin tracking. 2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ====== 2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. ====== AbiHint(t1, 16, t2) ====== 2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* base; /* Start of undefined chunk */ 2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int len; /* Length of undefined chunk */ 2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* nia; /* Address of next (guest) insn */ 2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } AbiHint; 2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Write a guest register, at a fixed offset in the guest state. 2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1 2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int offset; /* Offset into the guest state */ 2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* data; /* The value to write */ 2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Put; 2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Write a guest register, at a non-fixed offset in the guest 2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state. See the comment for GetI expressions for more 2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown information. 2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>, 2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. PUTI(64:8xF64)[t5,0] = t1 2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI* details; 2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } PutI; 2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Assign a value to a temporary. Note that SSA rules require 2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each tmp is only assigned to once. IR sanity checking will 2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reject any block containing a temporary which is not assigned 2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to exactly once. 2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: t<tmp> = <data>, eg. t1 = 3 2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp tmp; /* Temporary (LHS of assignment) */ 2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* data; /* Expression (RHS of assignment) */ 2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } WrTmp; 2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Write a value to memory. This is a normal store, not a 2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Store-Conditional. To represent a Store-Conditional, 2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instead use IRStmt.LLSC. 2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2 2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness end; /* Endianness of the store */ 2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* addr; /* store address */ 2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* data; /* value to write */ 2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Store; 2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Guarded store. Note that this is defined to evaluate all 2623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov expression fields (addr, data) even if the guard evaluates 2624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to false. 2625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ppIRStmt output: 2626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (<guard>) ST<end>(<addr>) = <data> */ 2627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct { 2628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRStoreG* details; 2629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } StoreG; 2630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Guarded load. Note that this is defined to evaluate all 2632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov expression fields (addr, alt) even if the guard evaluates 2633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to false. 2634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ppIRStmt output: 2635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */ 2636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct { 2637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRLoadG* details; 2638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } LoadG; 2639436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do an atomic compare-and-swap operation. Semantics are 2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown described above on a comment at the definition of IRCAS. 2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: 2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t<tmp> = CAS<end>(<addr> :: <expected> -> <new>) 2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg 2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = CASle(t2 :: t3->Add32(t3,1)) 2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which denotes a 32-bit atomic increment 2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of a value at address t2 2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A double-element CAS may also be denoted, in which case <tmp>, 2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <expected> and <new> are all pairs of items, separated by 2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commas. 2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS* details; 2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } CAS; 2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Either Load-Linked or Store-Conditional, depending on 2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown STOREDATA. 2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If STOREDATA is NULL then this is a Load-Linked, meaning 2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that data is loaded from memory as normal, but a 2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'reservation' for the address is also lodged in the 2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hardware. 2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = Load-Linked(addr, end) 2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The data transfer type is the type of RESULT (I32, I64, 2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown etc). ppIRStmt output: 2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1) 2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If STOREDATA is not NULL then this is a Store-Conditional, 2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hence: 2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = Store-Conditional(addr, storedata, end) 2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The data transfer type is the type of STOREDATA and RESULT 2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has type Ity_I1. The store may fail or succeed depending 2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown on the state of a previously lodged reservation on this 2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address. RESULT is written 1 if the store succeeds and 0 2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if it fails. eg ppIRStmt output: 2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = ( ST<end>-Cond(<addr>) = <storedata> ) 2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg t3 = ( STbe-Cond(t1, t2) ) 2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In all cases, the address must be naturally aligned for 2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the transfer type -- any misaligned addresses should be 2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown caught by a dominating IR check and side exit. This 2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown alignment restriction exists because on at least some 2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on 2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown misaligned addresses, and we have to actually generate 2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stwcx. on the host, and we don't want it trapping on the 2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown host. 2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Summary of rules for transfer type: 2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown STOREDATA == NULL (LL): 2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown transfer type = type of RESULT 2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown STOREDATA != NULL (SC): 2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown transfer type = type of STOREDATA, and RESULT :: Ity_I1 2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREndness end; 2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp result; 2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* addr; 2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* storedata; /* NULL => LL, non-NULL => SC */ 2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } LLSC; 2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Call (possibly conditionally) a C function that has side 2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown effects (ie. is "dirty"). See the comments above the 2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty type declaration for more information. 2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: 2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t<tmp> = DIRTY <guard> <effects> 2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ::: <callee>(<args>) 2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. 2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4) 2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ::: foo{0x380035f4}(t2) 2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* details; 2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Dirty; 2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A memory bus event - a fence, or acquisition/release of the 2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hardware bus lock. IR optimisation treats all these as fences 2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown across which no memory references may be moved. 2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: MBusEvent-Fence, 2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MBusEvent-BusLock, MBusEvent-BusUnlock. 2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRMBusEvent event; 2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } MBE; 2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Conditional exit from the middle of an IRSB. 2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt output: if (<guard>) goto {<jk>} <dst> 2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eg. if (t69) goto {Boring} 0x4000AAA:I32 2737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng If <guard> is true, the guest state is also updated by 2738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng PUT-ing <dst> at <offsIP>. This is done because a 2739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng taken exit must update the guest program counter. 2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* guard; /* Conditional expression */ 2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst* dst; /* Jump target (constant only) */ 2744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRJumpKind jk; /* Jump kind */ 2745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int offsIP; /* Guest state offset for IP */ 2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Exit; 2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Ist; 2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt; 2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Statement constructors. */ 2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_NoOp ( void ); 2753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern IRStmt* IRStmt_IMark ( Addr64 addr, Int len, UChar delta ); 2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ); 2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Put ( Int off, IRExpr* data ); 2756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRStmt* IRStmt_PutI ( IRPutI* details ); 2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ); 2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ); 2759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRStmt* IRStmt_StoreG ( IREndness end, IRExpr* addr, IRExpr* data, 2760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard ); 2761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern IRStmt* IRStmt_LoadG ( IREndness end, IRLoadGOp cvt, IRTemp dst, 2762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr, IRExpr* alt, IRExpr* guard ); 2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_CAS ( IRCAS* details ); 2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result, 2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* addr, IRExpr* storedata ); 2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_Dirty ( IRDirty* details ); 2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* IRStmt_MBE ( IRMBusEvent event ); 2768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst, 2769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int offsIP ); 2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRStmt. */ 2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRStmt* deepCopyIRStmt ( IRStmt* ); 2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRStmt. */ 2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRStmt ( IRStmt* ); 2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Basic Blocks ------------------ */ 2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Type environments: a bunch of statements, expressions, etc, are 2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown incomplete without an environment indicating the type of each 2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp. So this provides one. IR temporaries are really just 2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned ints and so this provides an array, 0 .. n_types_used-1 of 2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown them. 2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType* types; 2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int types_size; 2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int types_used; 2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTypeEnv; 2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Obtain a new IRTemp */ 2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy a type environment */ 2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* ); 2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print a type environment */ 2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRTypeEnv ( IRTypeEnv* ); 2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Code blocks, which in proper compiler terminology are superblocks 2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (single entry, multiple exit code sequences) contain: 2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - A table giving a type for each temp (the "type environment") 2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - An expandable array of statements 2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - An expression of type 32 or 64 bits, depending on the 2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest's word size, indicating the next destination if the block 2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown executes all the way to the end, without a side exit 2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - An indication of any special actions (JumpKind) needed 2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for this final jump. 2814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - Offset of the IP field in the guest state. This will be 2815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng updated before the final jump is done. 2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "IRSB" stands for "IR Super Block". 2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTypeEnv* tyenv; 2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt** stmts; 2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int stmts_size; 2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int stmts_used; 2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* next; 2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRJumpKind jumpkind; 2827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int offsIP; 2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB; 2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate a new, uninitialised IRSB */ 2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* emptyIRSB ( void ); 2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRSB */ 2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* deepCopyIRSB ( IRSB* ); 2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Deep-copy an IRSB, except for the statements list, which set to be 2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a new, empty, list of statements. */ 2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRSB* deepCopyIRSBExceptStmts ( IRSB* ); 2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pretty-print an IRSB */ 2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ppIRSB ( IRSB* ); 2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append an IRStmt to an IRSB */ 2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void addStmtToIRSB ( IRSB*, IRStmt* ); 2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for the IR ---*/ 2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* For messing with IR type environments */ 2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRTypeEnv* emptyIRTypeEnv ( void ); 2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* What is the type of this expression? */ 2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRConst ( IRConst* ); 2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp ); 2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2860436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* What are the arg and result type for this IRLoadGOp? */ 2861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void typeOfIRLoadGOp ( IRLoadGOp cvt, 2862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/IRType* t_res, 2863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/IRType* t_arg ); 2864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Sanity check a BB of IR */ 2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void sanityCheckIRSB ( IRSB* bb, 2867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* caller, 2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool require_flatness, 2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType guest_word_size ); 2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool isFlatIRStmt ( IRStmt* ); 2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this any value actually in the enumeration 'IRType' ? */ 2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool isPlausibleIRType ( IRType ty ); 2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2876436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 2877436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- IR injection ---*/ 2878436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 2879436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2880436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid vex_inject_ir(IRSB *, IREndness); 2881436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2882436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif /* ndef __LIBVEX_IR_H */ 2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- libvex_ir.h ---*/ 2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2888