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