blob: 005809c7fc14cadcc318f8f6909016954f04ba9d [file] [log] [blame]
sewardjec6ad592004-06-20 12:26:53 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin libvex_ir.h ---*/
sewardjec6ad592004-06-20 12:26:53 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardje6c53e02011-10-23 07:33:43 +000010 Copyright (C) 2004-2011 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#ifndef __LIBVEX_IR_H
37#define __LIBVEX_IR_H
sewardjac9af022004-07-05 01:15:34 +000038
sewardj887a11a2004-07-05 17:26:47 +000039#include "libvex_basictypes.h"
sewardjec6ad592004-06-20 12:26:53 +000040
sewardj57c10c82006-11-15 02:57:05 +000041
sewardjec6ad592004-06-20 12:26:53 +000042/*---------------------------------------------------------------*/
sewardj57c10c82006-11-15 02:57:05 +000043/*--- High-level IR description ---*/
44/*---------------------------------------------------------------*/
45
46/* Vex IR is an architecture-neutral intermediate representation.
47 Unlike some IRs in systems similar to Vex, it is not like assembly
48 language (ie. a list of instructions). Rather, it is more like the
49 IR that might be used in a compiler.
50
51 Code blocks
52 ~~~~~~~~~~~
sewardjdd40fdf2006-12-24 02:20:24 +000053 The code is broken into small code blocks ("superblocks", type:
54 'IRSB'). Each code block typically represents from 1 to perhaps 50
55 instructions. IRSBs are single-entry, multiple-exit code blocks.
56 Each IRSB contains three things:
sewardj57c10c82006-11-15 02:57:05 +000057 - a type environment, which indicates the type of each temporary
sewardjdd40fdf2006-12-24 02:20:24 +000058 value present in the IRSB
sewardj57c10c82006-11-15 02:57:05 +000059 - a list of statements, which represent code
sewardjdd40fdf2006-12-24 02:20:24 +000060 - a jump that exits from the end the IRSB
sewardj57c10c82006-11-15 02:57:05 +000061 Because the blocks are multiple-exit, there can be additional
sewardjdd40fdf2006-12-24 02:20:24 +000062 conditional exit statements that cause control to leave the IRSB
63 before the final exit. Also because of this, IRSBs can cover
64 multiple non-consecutive sequences of code (up to 3). These are
65 recorded in the type VexGuestExtents (see libvex.h).
sewardj57c10c82006-11-15 02:57:05 +000066
67 Statements and expressions
68 ~~~~~~~~~~~~~~~~~~~~~~~~~~
69 Statements (type 'IRStmt') represent operations with side-effects,
70 eg. guest register writes, stores, and assignments to temporaries.
71 Expressions (type 'IRExpr') represent operations without
72 side-effects, eg. arithmetic operations, loads, constants.
73 Expressions can contain sub-expressions, forming expression trees,
74 eg. (3 + (4 * load(addr1)).
75
76 Storage of guest state
77 ~~~~~~~~~~~~~~~~~~~~~~
78 The "guest state" contains the guest registers of the guest machine
79 (ie. the machine that we are simulating). It is stored by default
80 in a block of memory supplied by the user of the VEX library,
81 generally referred to as the guest state (area). To operate on
82 these registers, one must first read ("Get") them from the guest
83 state into a temporary value. Afterwards, one can write ("Put")
84 them back into the guest state.
85
86 Get and Put are characterised by a byte offset into the guest
87 state, a small integer which effectively gives the identity of the
88 referenced guest register, and a type, which indicates the size of
89 the value to be transferred.
90
91 The basic "Get" and "Put" operations are sufficient to model normal
92 fixed registers on the guest. Selected areas of the guest state
sewardjdd40fdf2006-12-24 02:20:24 +000093 can be treated as a circular array of registers (type:
94 'IRRegArray'), which can be indexed at run-time. This is done with
95 the "GetI" and "PutI" primitives. This is necessary to describe
96 rotating register files, for example the x87 FPU stack, SPARC
97 register windows, and the Itanium register files.
sewardj57c10c82006-11-15 02:57:05 +000098
99 Examples, and flattened vs. unflattened code
100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101 For example, consider this x86 instruction:
102
103 addl %eax, %ebx
104
105 One Vex IR translation for this code would be this:
106
sewardj2f10aa62011-05-27 13:20:56 +0000107 ------ IMark(0x24F275, 7, 0) ------
sewardj57c10c82006-11-15 02:57:05 +0000108 t3 = GET:I32(0) # get %eax, a 32-bit integer
109 t2 = GET:I32(12) # get %ebx, a 32-bit integer
110 t1 = Add32(t3,t2) # addl
111 PUT(0) = t1 # put %eax
112
113 (For simplicity, this ignores the effects on the condition codes, and
114 the update of the instruction pointer.)
115
116 The "IMark" is an IR statement that doesn't represent actual code.
117 Instead it indicates the address and length of the original
118 instruction. The numbers 0 and 12 are offsets into the guest state
119 for %eax and %ebx. The full list of offsets for an architecture
120 <ARCH> can be found in the type VexGuest<ARCH>State in the file
121 VEX/pub/libvex_guest_<ARCH>.h.
122
123 The five statements in this example are:
124 - the IMark
125 - three assignments to temporaries
126 - one register write (put)
127
128 The six expressions in this example are:
129 - two register reads (gets)
130 - one arithmetic (add) operation
131 - three temporaries (two nested within the Add32, one in the PUT)
132
133 The above IR is "flattened", ie. all sub-expressions are "atoms",
134 either constants or temporaries. An equivalent, unflattened version
135 would be:
136
137 PUT(0) = Add32(GET:I32(0), GET:I32(12))
138
139 IR is guaranteed to be flattened at instrumentation-time. This makes
140 instrumentation easier. Equivalent flattened and unflattened IR
141 typically results in the same generated code.
142
143 Another example, this one showing loads and stores:
144
145 addl %edx,4(%eax)
146
147 This becomes (again ignoring condition code and instruction pointer
148 updates):
149
sewardj2f10aa62011-05-27 13:20:56 +0000150 ------ IMark(0x4000ABA, 3, 0) ------
sewardj57c10c82006-11-15 02:57:05 +0000151 t3 = Add32(GET:I32(0),0x4:I32)
152 t2 = LDle:I32(t3)
153 t1 = GET:I32(8)
154 t0 = Add32(t2,t1)
155 STle(t3) = t0
156
157 The "le" in "LDle" and "STle" is short for "little-endian".
158
159 No need for deallocations
160 ~~~~~~~~~~~~~~~~~~~~~~~~~
161 Although there are allocation functions for various data structures
162 in this file, there are no deallocation functions. This is because
163 Vex uses a memory allocation scheme that automatically reclaims the
164 memory used by allocated structures once translation is completed.
165 This makes things easier for tools that instruments/transforms code
166 blocks.
167
168 SSAness and typing
169 ~~~~~~~~~~~~~~~~~~
sewardjdd40fdf2006-12-24 02:20:24 +0000170 The IR is fully typed. For every IRSB (IR block) it is possible to
sewardj57c10c82006-11-15 02:57:05 +0000171 say unambiguously whether or not it is correctly typed.
172 Incorrectly typed IR has no meaning and the VEX will refuse to
173 process it. At various points during processing VEX typechecks the
174 IR and aborts if any violations are found. This seems overkill but
175 makes it a great deal easier to build a reliable JIT.
176
177 IR also has the SSA property. SSA stands for Static Single
178 Assignment, and what it means is that each IR temporary may be
179 assigned to only once. This idea became widely used in compiler
180 construction in the mid to late 90s. It makes many IR-level
181 transformations/code improvements easier, simpler and faster.
182 Whenever it typechecks an IR block, VEX also checks the SSA
183 property holds, and will abort if not so. So SSAness is
184 mechanically and rigidly enforced.
185*/
186
187/*---------------------------------------------------------------*/
sewardjac6b7122004-06-27 01:03:57 +0000188/*--- Type definitions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +0000189/*---------------------------------------------------------------*/
190
sewardj496a58d2005-03-20 18:44:44 +0000191/* General comments about naming schemes:
192
193 All publically visible functions contain the name of the primary
194 type on which they operate (IRFoo, IRBar, etc). Hence you should
195 be able to identify these functions by grepping for "IR[A-Z]".
196
197 For some type 'IRFoo':
198
199 - ppIRFoo is the printing method for IRFoo, printing it to the
200 output channel specified in the LibVEX_Initialise call.
201
202 - eqIRFoo is a structural equality predicate for IRFoos.
203
sewardjdd40fdf2006-12-24 02:20:24 +0000204 - deepCopyIRFoo is a deep copy constructor for IRFoos.
sewardj496a58d2005-03-20 18:44:44 +0000205 It recursively traverses the entire argument tree and
sewardjf6c8ebf2007-02-06 01:52:52 +0000206 produces a complete new tree. All types have a deep copy
207 constructor.
sewardj496a58d2005-03-20 18:44:44 +0000208
sewardjdd40fdf2006-12-24 02:20:24 +0000209 - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
sewardj496a58d2005-03-20 18:44:44 +0000210 It creates a new top-level copy of the supplied object,
sewardjf6c8ebf2007-02-06 01:52:52 +0000211 but does not copy any sub-objects. Only some types have a
212 shallow copy constructor.
sewardj496a58d2005-03-20 18:44:44 +0000213*/
214
sewardjc97096c2004-06-30 09:28:04 +0000215/* ------------------ Types ------------------ */
sewardje3d0d2e2004-06-27 10:42:44 +0000216
sewardj57c10c82006-11-15 02:57:05 +0000217/* A type indicates the size of a value, and whether it's an integer, a
218 float, or a vector (SIMD) value. */
sewardje3d0d2e2004-06-27 10:42:44 +0000219typedef
sewardjc9a43662004-11-30 18:51:59 +0000220 enum {
sewardjc4356f02007-11-09 21:15:04 +0000221 Ity_INVALID=0x11000,
222 Ity_I1,
sewardjc9a43662004-11-30 18:51:59 +0000223 Ity_I8,
224 Ity_I16,
225 Ity_I32,
226 Ity_I64,
sewardj9b967672005-02-08 11:13:09 +0000227 Ity_I128, /* 128-bit scalar */
sewardjc9a43662004-11-30 18:51:59 +0000228 Ity_F32, /* IEEE 754 float */
229 Ity_F64, /* IEEE 754 double */
sewardjc6bbd472012-04-02 10:20:48 +0000230 Ity_D32, /* 32-bit Decimal floating point */
231 Ity_D64, /* 64-bit Decimal floating point */
232 Ity_D128, /* 128-bit Decimal floating point */
sewardj2019a972011-03-07 16:04:07 +0000233 Ity_F128, /* 128-bit floating point; implementation defined */
sewardjc4530ae2012-05-21 10:18:49 +0000234 Ity_V128, /* 128-bit SIMD */
235 Ity_V256 /* 256-bit SIMD */
sewardjd1725d12004-08-12 20:46:53 +0000236 }
sewardje3d0d2e2004-06-27 10:42:44 +0000237 IRType;
238
sewardj57c10c82006-11-15 02:57:05 +0000239/* Pretty-print an IRType */
sewardj35421a32004-07-05 13:12:34 +0000240extern void ppIRType ( IRType );
sewardj57c10c82006-11-15 02:57:05 +0000241
242/* Get the size (in bytes) of an IRType */
243extern Int sizeofIRType ( IRType );
sewardje3d0d2e2004-06-27 10:42:44 +0000244
sewardjc97096c2004-06-30 09:28:04 +0000245
sewardjaf1ceca2005-06-30 23:31:27 +0000246/* ------------------ Endianness ------------------ */
247
sewardj57c10c82006-11-15 02:57:05 +0000248/* IREndness is used in load IRExprs and store IRStmts. */
sewardjaf1ceca2005-06-30 23:31:27 +0000249typedef
250 enum {
sewardjc4356f02007-11-09 21:15:04 +0000251 Iend_LE=0x12000, /* little endian */
252 Iend_BE /* big endian */
sewardjaf1ceca2005-06-30 23:31:27 +0000253 }
254 IREndness;
255
256
sewardjc97096c2004-06-30 09:28:04 +0000257/* ------------------ Constants ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000258
sewardj57c10c82006-11-15 02:57:05 +0000259/* IRConsts are used within 'Const' and 'Exit' IRExprs. */
260
261/* The various kinds of constant. */
sewardjac6b7122004-06-27 01:03:57 +0000262typedef
sewardjc9a43662004-11-30 18:51:59 +0000263 enum {
sewardjc4356f02007-11-09 21:15:04 +0000264 Ico_U1=0x13000,
sewardjc9a43662004-11-30 18:51:59 +0000265 Ico_U8,
266 Ico_U16,
267 Ico_U32,
268 Ico_U64,
sewardj2019a972011-03-07 16:04:07 +0000269 Ico_F32, /* 32-bit IEEE754 floating */
270 Ico_F32i, /* 32-bit unsigned int to be interpreted literally
271 as a IEEE754 single value. */
sewardj1e6ad742004-12-02 16:16:11 +0000272 Ico_F64, /* 64-bit IEEE754 floating */
273 Ico_F64i, /* 64-bit unsigned int to be interpreted literally
274 as a IEEE754 double value. */
sewardj37a505b2012-06-29 15:28:24 +0000275 Ico_V128, /* 128-bit restricted vector constant, with 1 bit
sewardj57c10c82006-11-15 02:57:05 +0000276 (repeated 8 times) for each of the 16 x 1-byte lanes */
sewardj37a505b2012-06-29 15:28:24 +0000277 Ico_V256 /* 256-bit restricted vector constant, with 1 bit
278 (repeated 8 times) for each of the 32 x 1-byte lanes */
sewardj207557a2004-08-27 12:00:18 +0000279 }
sewardjac6b7122004-06-27 01:03:57 +0000280 IRConstTag;
281
sewardj57c10c82006-11-15 02:57:05 +0000282/* A constant. Stored as a tagged union. 'tag' indicates what kind of
283 constant this is. 'Ico' is the union that holds the fields. If an
284 IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
285 and its value can be accessed with 'c.Ico.U32'. */
sewardjac6b7122004-06-27 01:03:57 +0000286typedef
sewardje3d0d2e2004-06-27 10:42:44 +0000287 struct _IRConst {
sewardjac6b7122004-06-27 01:03:57 +0000288 IRConstTag tag;
289 union {
sewardjba999312004-11-15 15:21:17 +0000290 Bool U1;
sewardjc97096c2004-06-30 09:28:04 +0000291 UChar U8;
292 UShort U16;
293 UInt U32;
294 ULong U64;
sewardj2019a972011-03-07 16:04:07 +0000295 Float F32;
296 UInt F32i;
sewardja58ea662004-08-15 03:12:41 +0000297 Double F64;
sewardj17442fe2004-09-20 14:54:28 +0000298 ULong F64i;
sewardj57c10c82006-11-15 02:57:05 +0000299 UShort V128; /* 16-bit value; see Ico_V128 comment above */
sewardj37a505b2012-06-29 15:28:24 +0000300 UInt V256; /* 32-bit value; see Ico_V256 comment above */
sewardjac6b7122004-06-27 01:03:57 +0000301 } Ico;
302 }
303 IRConst;
sewardjec6ad592004-06-20 12:26:53 +0000304
sewardj57c10c82006-11-15 02:57:05 +0000305/* IRConst constructors */
sewardjba999312004-11-15 15:21:17 +0000306extern IRConst* IRConst_U1 ( Bool );
sewardj17442fe2004-09-20 14:54:28 +0000307extern IRConst* IRConst_U8 ( UChar );
308extern IRConst* IRConst_U16 ( UShort );
309extern IRConst* IRConst_U32 ( UInt );
310extern IRConst* IRConst_U64 ( ULong );
sewardj2019a972011-03-07 16:04:07 +0000311extern IRConst* IRConst_F32 ( Float );
312extern IRConst* IRConst_F32i ( UInt );
sewardj17442fe2004-09-20 14:54:28 +0000313extern IRConst* IRConst_F64 ( Double );
314extern IRConst* IRConst_F64i ( ULong );
sewardj1e6ad742004-12-02 16:16:11 +0000315extern IRConst* IRConst_V128 ( UShort );
sewardj37a505b2012-06-29 15:28:24 +0000316extern IRConst* IRConst_V256 ( UInt );
sewardjec6ad592004-06-20 12:26:53 +0000317
sewardj57c10c82006-11-15 02:57:05 +0000318/* Deep-copy an IRConst */
sewardjdd40fdf2006-12-24 02:20:24 +0000319extern IRConst* deepCopyIRConst ( IRConst* );
sewardj695cff92004-10-13 14:50:14 +0000320
sewardj57c10c82006-11-15 02:57:05 +0000321/* Pretty-print an IRConst */
sewardj35421a32004-07-05 13:12:34 +0000322extern void ppIRConst ( IRConst* );
sewardj57c10c82006-11-15 02:57:05 +0000323
324/* Compare two IRConsts for equality */
sewardj4345f7a2004-09-22 19:49:27 +0000325extern Bool eqIRConst ( IRConst*, IRConst* );
sewardjc97096c2004-06-30 09:28:04 +0000326
327
sewardj8ea867b2004-10-30 19:03:02 +0000328/* ------------------ Call targets ------------------ */
329
330/* Describes a helper function to call. The name part is purely for
sewardj77352542004-10-30 20:39:01 +0000331 pretty printing and not actually used. regparms=n tells the back
sewardj8ea867b2004-10-30 19:03:02 +0000332 end that the callee has been declared
sewardj03d91142011-03-14 12:35:18 +0000333 "__attribute__((regparm(n)))", although indirectly using the
334 VEX_REGPARM(n) macro. On some targets (x86) the back end will need
335 to construct a non-standard sequence to call a function declared
336 like this.
sewardj43c56462004-11-06 12:17:57 +0000337
338 mcx_mask is a sop to Memcheck. It indicates which args should be
339 considered 'always defined' when lazily computing definedness of
340 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to
341 args[1], etc. If a bit is set, the corresponding arg is excluded
342 (hence "x" in "mcx") from definedness checking.
343*/
sewardj8ea867b2004-10-30 19:03:02 +0000344
345typedef
346 struct {
sewardj2d49b432005-02-01 00:37:06 +0000347 Int regparms;
348 HChar* name;
349 void* addr;
350 UInt mcx_mask;
sewardj8ea867b2004-10-30 19:03:02 +0000351 }
352 IRCallee;
353
sewardj57c10c82006-11-15 02:57:05 +0000354/* Create an IRCallee. */
sewardj2d49b432005-02-01 00:37:06 +0000355extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
sewardj8ea867b2004-10-30 19:03:02 +0000356
sewardj57c10c82006-11-15 02:57:05 +0000357/* Deep-copy an IRCallee. */
sewardjdd40fdf2006-12-24 02:20:24 +0000358extern IRCallee* deepCopyIRCallee ( IRCallee* );
sewardj8ea867b2004-10-30 19:03:02 +0000359
sewardj57c10c82006-11-15 02:57:05 +0000360/* Pretty-print an IRCallee. */
sewardj8ea867b2004-10-30 19:03:02 +0000361extern void ppIRCallee ( IRCallee* );
362
363
sewardj2d3f77c2004-09-22 23:49:09 +0000364/* ------------------ Guest state arrays ------------------ */
365
sewardj57c10c82006-11-15 02:57:05 +0000366/* This describes a section of the guest state that we want to
367 be able to index at run time, so as to be able to describe
368 indexed or rotating register files on the guest. */
sewardj2d3f77c2004-09-22 23:49:09 +0000369typedef
370 struct {
sewardj57c10c82006-11-15 02:57:05 +0000371 Int base; /* guest state offset of start of indexed area */
372 IRType elemTy; /* type of each element in the indexed area */
373 Int nElems; /* number of elements in the indexed area */
sewardj2d3f77c2004-09-22 23:49:09 +0000374 }
sewardjdd40fdf2006-12-24 02:20:24 +0000375 IRRegArray;
sewardj2d3f77c2004-09-22 23:49:09 +0000376
sewardjdd40fdf2006-12-24 02:20:24 +0000377extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
sewardj2d3f77c2004-09-22 23:49:09 +0000378
sewardjdd40fdf2006-12-24 02:20:24 +0000379extern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
sewardj695cff92004-10-13 14:50:14 +0000380
sewardjdd40fdf2006-12-24 02:20:24 +0000381extern void ppIRRegArray ( IRRegArray* );
382extern Bool eqIRRegArray ( IRRegArray*, IRRegArray* );
sewardj2d3f77c2004-09-22 23:49:09 +0000383
384
sewardjc97096c2004-06-30 09:28:04 +0000385/* ------------------ Temporaries ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000386
sewardj57c10c82006-11-15 02:57:05 +0000387/* This represents a temporary, eg. t1. The IR optimiser relies on the
388 fact that IRTemps are 32-bit ints. Do not change them to be ints of
389 any other size. */
sewardjfbcaf332004-07-08 01:46:01 +0000390typedef UInt IRTemp;
sewardjec6ad592004-06-20 12:26:53 +0000391
sewardj57c10c82006-11-15 02:57:05 +0000392/* Pretty-print an IRTemp. */
sewardj35421a32004-07-05 13:12:34 +0000393extern void ppIRTemp ( IRTemp );
sewardjec6ad592004-06-20 12:26:53 +0000394
sewardj92d168d2004-11-15 14:22:12 +0000395#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
sewardjfbcaf332004-07-08 01:46:01 +0000396
sewardjc97096c2004-06-30 09:28:04 +0000397
sewardj40c80262006-02-08 19:30:46 +0000398/* --------------- Primops (arity 1,2,3 and 4) --------------- */
sewardjec6ad592004-06-20 12:26:53 +0000399
sewardj57c10c82006-11-15 02:57:05 +0000400/* Primitive operations that are used in Unop, Binop, Triop and Qop
401 IRExprs. Once we take into account integer, floating point and SIMD
402 operations of all the different sizes, there are quite a lot of them.
403 Most instructions supported by the architectures that Vex supports
404 (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid)
405 are not; they are instead handled with dirty helpers that emulate
406 their functionality. Such obscure ones are thus not directly visible
407 in the IR, but their effects on guest state (memory and registers)
408 are made visible via the annotations in IRDirty structures.
409*/
sewardjac6b7122004-06-27 01:03:57 +0000410typedef
sewardj41f43bc2004-07-08 14:23:22 +0000411 enum {
sewardj71a35e72005-05-03 12:20:15 +0000412 /* -- Do not change this ordering. The IR generators rely on
413 (eg) Iop_Add64 == IopAdd8 + 3. -- */
414
sewardjc4356f02007-11-09 21:15:04 +0000415 Iop_INVALID=0x14000,
sewardj66de2272004-07-16 21:19:05 +0000416 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
sewardj41f43bc2004-07-08 14:23:22 +0000417 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
sewardj41f43bc2004-07-08 14:23:22 +0000418 /* Signless mul. MullS/MullU is elsewhere. */
419 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
420 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
421 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
422 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
423 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
424 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
425 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
sewardje90ad6a2004-07-10 19:02:10 +0000426 /* Integer comparisons. */
427 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
428 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
sewardj41f43bc2004-07-08 14:23:22 +0000429 /* Tags for unary ops */
430 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
sewardj71a35e72005-05-03 12:20:15 +0000431
sewardj1fb8c922009-07-12 12:56:53 +0000432 /* Exactly like CmpEQ8/16/32/64, but carrying the additional
433 hint that these compute the success/failure of a CAS
434 operation, and hence are almost certainly applied to two
435 copies of the same value, which in turn has implications for
436 Memcheck's instrumentation. */
437 Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
438 Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
439
sewardj71a35e72005-05-03 12:20:15 +0000440 /* -- Ordering not important after here. -- */
441
sewardj9690d922004-07-14 01:39:17 +0000442 /* Widening multiplies */
sewardj9b967672005-02-08 11:13:09 +0000443 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
444 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
sewardj8f3debf2004-09-08 23:42:23 +0000445
sewardjce646f22004-08-31 23:55:54 +0000446 /* Wierdo integer stuff */
sewardjf53b7352005-04-06 20:01:56 +0000447 Iop_Clz64, Iop_Clz32, /* count leading zeroes */
448 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
449 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
450 zero. You must ensure they are never given a zero argument.
sewardj8f3debf2004-09-08 23:42:23 +0000451 */
452
sewardjb51f0f42005-07-18 11:38:02 +0000453 /* Standard integer comparisons */
sewardj98540072005-04-26 01:52:01 +0000454 Iop_CmpLT32S, Iop_CmpLT64S,
455 Iop_CmpLE32S, Iop_CmpLE64S,
456 Iop_CmpLT32U, Iop_CmpLT64U,
457 Iop_CmpLE32U, Iop_CmpLE64U,
sewardj343b9d02005-01-31 18:08:45 +0000458
sewardj0033ddc2005-04-26 23:34:34 +0000459 /* As a sop to Valgrind-Memcheck, the following are useful. */
460 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
sewardjeb17e492007-08-25 23:07:44 +0000461 Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
462 Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
sewardj478646f2008-05-01 20:13:04 +0000463 Iop_Max32U, /* unsigned max */
sewardj0033ddc2005-04-26 23:34:34 +0000464
sewardj57c10c82006-11-15 02:57:05 +0000465 /* PowerPC-style 3-way integer comparisons. Without them it is
466 difficult to simulate PPC efficiently.
sewardjb51f0f42005-07-18 11:38:02 +0000467 op(x,y) | x < y = 0x8 else
468 | x > y = 0x4 else
469 | x == y = 0x2
470 */
cerion2831b002005-11-30 19:55:22 +0000471 Iop_CmpORD32U, Iop_CmpORD64U,
472 Iop_CmpORD32S, Iop_CmpORD64S,
sewardjb51f0f42005-07-18 11:38:02 +0000473
sewardj9690d922004-07-14 01:39:17 +0000474 /* Division */
sewardj8f3debf2004-09-08 23:42:23 +0000475 /* TODO: clarify semantics wrt rounding, negative values, whatever */
cerion5c8a0cb2005-02-03 13:59:46 +0000476 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod)
477 Iop_DivS32, // ditto, signed
cerionf0de28c2005-12-13 20:21:11 +0000478 Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod)
479 Iop_DivS64, // ditto, signed
sewardje71e56a2011-09-05 12:11:06 +0000480 Iop_DivU64E, // :: I64,I64 -> I64 (dividend is 64-bit arg (hi) concat with 64 0's (low))
481 Iop_DivS64E, // ditto, signed
sewardj4aa412a2011-07-24 14:13:21 +0000482 Iop_DivU32E, // :: I32,I32 -> I32 (dividend is 32-bit arg (hi) concat with 32 0's (low))
sewardje71e56a2011-09-05 12:11:06 +0000483 Iop_DivS32E, // ditto, signed
cerion5c8a0cb2005-02-03 13:59:46 +0000484
sewardj9690d922004-07-14 01:39:17 +0000485 Iop_DivModU64to32, // :: I64,I32 -> I64
486 // of which lo half is div and hi half is mod
487 Iop_DivModS64to32, // ditto, signed
sewardj89d4e982004-09-12 19:14:46 +0000488
sewardj343b9d02005-01-31 18:08:45 +0000489 Iop_DivModU128to64, // :: V128,I64 -> V128
490 // of which lo half is div and hi half is mod
491 Iop_DivModS128to64, // ditto, signed
492
sewardj2019a972011-03-07 16:04:07 +0000493 Iop_DivModS64to64, // :: I64,I64 -> I128
494 // of which lo half is div and hi half is mod
495
sewardj0033ddc2005-04-26 23:34:34 +0000496 /* Integer conversions. Some of these are redundant (eg
497 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
498 having a complete set reduces the typical dynamic size of IR
499 and makes the instruction selectors easier to write. */
500
sewardj9690d922004-07-14 01:39:17 +0000501 /* Widening conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000502 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64,
503 Iop_16Uto32, Iop_16Uto64,
504 Iop_32Uto64,
505 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64,
506 Iop_16Sto32, Iop_16Sto64,
507 Iop_32Sto64,
508
sewardja2384712004-07-29 14:36:40 +0000509 /* Narrowing conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000510 Iop_64to8, Iop_32to8, Iop_64to16,
sewardjb81f8b32004-07-30 10:17:50 +0000511 /* 8 <-> 16 bit conversions */
512 Iop_16to8, // :: I16 -> I8, low half
513 Iop_16HIto8, // :: I16 -> I8, high half
514 Iop_8HLto16, // :: (I8,I8) -> I16
sewardj8c7f1ab2004-07-29 20:31:09 +0000515 /* 16 <-> 32 bit conversions */
516 Iop_32to16, // :: I32 -> I16, low half
517 Iop_32HIto16, // :: I32 -> I16, high half
518 Iop_16HLto32, // :: (I16,I16) -> I32
sewardj9690d922004-07-14 01:39:17 +0000519 /* 32 <-> 64 bit conversions */
sewardj8c7f1ab2004-07-29 20:31:09 +0000520 Iop_64to32, // :: I64 -> I32, low half
sewardj9690d922004-07-14 01:39:17 +0000521 Iop_64HIto32, // :: I64 -> I32, high half
522 Iop_32HLto64, // :: (I32,I32) -> I64
sewardj9b967672005-02-08 11:13:09 +0000523 /* 64 <-> 128 bit conversions */
524 Iop_128to64, // :: I128 -> I64, low half
525 Iop_128HIto64, // :: I128 -> I64, high half
526 Iop_64HLto128, // :: (I64,I64) -> I128
sewardjcf780b42004-07-13 18:42:17 +0000527 /* 1-bit stuff */
sewardj6e797c52004-10-13 15:20:17 +0000528 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */
sewardj84ff0652004-08-23 16:16:08 +0000529 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
sewardj291a7e82005-04-27 11:42:44 +0000530 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
531 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
sewardj84ff0652004-08-23 16:16:08 +0000532 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
sewardj291a7e82005-04-27 11:42:44 +0000533 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
sewardjfd332772004-11-09 16:01:40 +0000534 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */
sewardj8eda6302004-11-05 01:55:46 +0000535 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
sewardjcf787902004-11-03 09:08:33 +0000536 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
sewardjb5874aa2004-11-04 16:57:50 +0000537 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
sewardj8f3debf2004-09-08 23:42:23 +0000538
sewardjbaf971a2006-01-27 15:09:35 +0000539 /* ------ Floating point. We try to be IEEE754 compliant. ------ */
sewardj8f3debf2004-09-08 23:42:23 +0000540
sewardjb183b852006-02-03 16:08:03 +0000541 /* --- Simple stuff as mandated by 754. --- */
sewardjcfded9a2004-09-09 11:44:16 +0000542
sewardjb183b852006-02-03 16:08:03 +0000543 /* Binary operations, with rounding. */
544 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
545 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
sewardj52ace3e2004-09-11 17:10:08 +0000546
sewardj6c299f32009-12-31 18:00:12 +0000547 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
548 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
549
sewardjb183b852006-02-03 16:08:03 +0000550 /* Variants of the above which produce a 64-bit result but which
551 round their result to a IEEE float range first. */
552 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
553 Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
sewardj52ace3e2004-09-11 17:10:08 +0000554
sewardjb183b852006-02-03 16:08:03 +0000555 /* Unary operations, without rounding. */
556 /* :: F64 -> F64 */
557 Iop_NegF64, Iop_AbsF64,
sewardj8f3debf2004-09-08 23:42:23 +0000558
sewardj6c299f32009-12-31 18:00:12 +0000559 /* :: F32 -> F32 */
560 Iop_NegF32, Iop_AbsF32,
561
sewardjb183b852006-02-03 16:08:03 +0000562 /* Unary operations, with rounding. */
563 /* :: IRRoundingMode(I32) x F64 -> F64 */
564 Iop_SqrtF64, Iop_SqrtF64r32,
sewardjbaf971a2006-01-27 15:09:35 +0000565
sewardj6c299f32009-12-31 18:00:12 +0000566 /* :: IRRoundingMode(I32) x F32 -> F32 */
567 Iop_SqrtF32,
568
sewardj8f3debf2004-09-08 23:42:23 +0000569 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
sewardj883b00b2004-09-11 09:30:24 +0000570 0x45 Unordered
sewardj8f3debf2004-09-08 23:42:23 +0000571 0x01 LT
572 0x00 GT
sewardj883b00b2004-09-11 09:30:24 +0000573 0x40 EQ
sewardj8f3debf2004-09-08 23:42:23 +0000574 This just happens to be the Intel encoding. The values
575 are recorded in the type IRCmpF64Result.
576 */
sewardj6c299f32009-12-31 18:00:12 +0000577 /* :: F64 x F64 -> IRCmpF64Result(I32) */
sewardj8f3debf2004-09-08 23:42:23 +0000578 Iop_CmpF64,
sewardj2019a972011-03-07 16:04:07 +0000579 Iop_CmpF32,
580 Iop_CmpF128,
sewardj8f3debf2004-09-08 23:42:23 +0000581
sewardj3bca9062004-12-04 14:36:09 +0000582 /* --- Int to/from FP conversions. --- */
sewardjb183b852006-02-03 16:08:03 +0000583
sewardj6c299f32009-12-31 18:00:12 +0000584 /* For the most part, these take a first argument :: Ity_I32 (as
585 IRRoundingMode) which is an indication of the rounding mode
586 to use, as per the following encoding ("the standard
587 encoding"):
sewardj8f3debf2004-09-08 23:42:23 +0000588 00b to nearest (the default)
589 01b to -infinity
590 10b to +infinity
591 11b to zero
592 This just happens to be the Intel encoding. For reference only,
593 the PPC encoding is:
594 00b to nearest (the default)
595 01b to zero
596 10b to +infinity
597 11b to -infinity
598 Any PPC -> IR front end will have to translate these PPC
sewardj6c299f32009-12-31 18:00:12 +0000599 encodings, as encoded in the guest state, to the standard
600 encodings, to pass to the primops.
601 For reference only, the ARM VFP encoding is:
602 00b to nearest
603 01b to +infinity
604 10b to -infinity
605 11b to zero
606 Again, this will have to be converted to the standard encoding
607 to pass to primops.
sewardj8f3debf2004-09-08 23:42:23 +0000608
609 If one of these conversions gets an out-of-range condition,
610 or a NaN, as an argument, the result is host-defined. On x86
sewardj6c299f32009-12-31 18:00:12 +0000611 the "integer indefinite" value 0x80..00 is produced. On PPC
612 it is either 0x80..00 or 0x7F..FF depending on the sign of
613 the argument.
614
615 On ARMvfp, when converting to a signed integer result, the
616 overflow result is 0x80..00 for negative args and 0x7F..FF
617 for positive args. For unsigned integer results it is
618 0x00..00 and 0xFF..FF respectively.
sewardj52ace3e2004-09-11 17:10:08 +0000619
sewardj3bca9062004-12-04 14:36:09 +0000620 Rounding is required whenever the destination type cannot
621 represent exactly all values of the source type.
622 */
sewardj6c299f32009-12-31 18:00:12 +0000623 Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
624 Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
625 Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
sewardj4aa412a2011-07-24 14:13:21 +0000626 Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
sewardj3bca9062004-12-04 14:36:09 +0000627
sewardj6c299f32009-12-31 18:00:12 +0000628 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
sewardj3bca9062004-12-04 14:36:09 +0000629
sewardj6c299f32009-12-31 18:00:12 +0000630 Iop_I16StoF64, /* signed I16 -> F64 */
631 Iop_I32StoF64, /* signed I32 -> F64 */
632 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
sewardj66d5ef22011-04-15 11:55:00 +0000633 Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
634 Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
sewardj6c299f32009-12-31 18:00:12 +0000635
636 Iop_I32UtoF64, /* unsigned I32 -> F64 */
637
sewardj2019a972011-03-07 16:04:07 +0000638 Iop_F32toI16S, /* IRRoundingMode(I32) x F32 -> signed I16 */
639 Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
640 Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
641
642 Iop_I16StoF32, /* signed I16 -> F32 */
643 Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
644 Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
645
sewardj6c299f32009-12-31 18:00:12 +0000646 /* Conversion between floating point formats */
sewardj3bca9062004-12-04 14:36:09 +0000647 Iop_F32toF64, /* F32 -> F64 */
648 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */
sewardj4cb918d2004-12-03 19:43:31 +0000649
sewardj17442fe2004-09-20 14:54:28 +0000650 /* Reinterpretation. Take an F64 and produce an I64 with
651 the same bit pattern, or vice versa. */
sewardjc9a43662004-11-30 18:51:59 +0000652 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
sewardjfc1b5412007-01-09 15:20:07 +0000653 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
sewardjb183b852006-02-03 16:08:03 +0000654
sewardj2019a972011-03-07 16:04:07 +0000655 /* Support for 128-bit floating point */
656 Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
657 Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
658 Iop_F128LOtoF64,/* F128 -> low half of F128 into a F64 register */
659
660 /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
661 Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
662
663 /* :: F128 -> F128 */
664 Iop_NegF128, Iop_AbsF128,
665
666 /* :: IRRoundingMode(I32) x F128 -> F128 */
667 Iop_SqrtF128,
668
669 Iop_I32StoF128, /* signed I32 -> F128 */
670 Iop_I64StoF128, /* signed I64 -> F128 */
671 Iop_F32toF128, /* F32 -> F128 */
672 Iop_F64toF128, /* F64 -> F128 */
673
674 Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32 */
675 Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64 */
676 Iop_F128toF64, /* IRRoundingMode(I32) x F128 -> F64 */
677 Iop_F128toF32, /* IRRoundingMode(I32) x F128 -> F32 */
678
sewardjb183b852006-02-03 16:08:03 +0000679 /* --- guest x86/amd64 specifics, not mandated by 754. --- */
680
681 /* Binary ops, with rounding. */
682 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
683 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
684 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
685 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
686 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */
687 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
688 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */
689 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
690 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
691 /* Note that on x86 guest, PRem1{C3210} has the same behaviour
692 as the IEEE mandated RemF64, except it is limited in the
693 range of its operand. Hence the partialness. */
694
695 /* Unary ops, with rounding. */
696 /* :: IRRoundingMode(I32) x F64 -> F64 */
697 Iop_SinF64, /* FSIN */
698 Iop_CosF64, /* FCOS */
699 Iop_TanF64, /* FTAN */
700 Iop_2xm1F64, /* (2^arg - 1.0) */
701 Iop_RoundF64toInt, /* F64 value to nearest integral value (still
702 as F64) */
sewardjd15b5972010-06-27 09:06:34 +0000703 Iop_RoundF32toInt, /* F32 value to nearest integral value (still
704 as F32) */
sewardjb183b852006-02-03 16:08:03 +0000705
sewardj2019a972011-03-07 16:04:07 +0000706 /* --- guest s390 specifics, not mandated by 754. --- */
707
708 /* Fused multiply-add/sub */
709 /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
710 (computes op3 * op2 +/- op1 */
711 Iop_MAddF32, Iop_MSubF32,
712
sewardjb183b852006-02-03 16:08:03 +0000713 /* --- guest ppc32/64 specifics, not mandated by 754. --- */
714
sewardj40c80262006-02-08 19:30:46 +0000715 /* Ternary operations, with rounding. */
716 /* Fused multiply-add/sub, with 112-bit intermediate
sewardj2019a972011-03-07 16:04:07 +0000717 precision for ppc.
718 Also used to implement fused multiply-add/sub for s390. */
sewardj40c80262006-02-08 19:30:46 +0000719 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
720 (computes arg2 * arg3 +/- arg4) */
721 Iop_MAddF64, Iop_MSubF64,
722
723 /* Variants of the above which produce a 64-bit result but which
724 round their result to a IEEE float range first. */
725 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
726 Iop_MAddF64r32, Iop_MSubF64r32,
727
sewardjb183b852006-02-03 16:08:03 +0000728 /* :: F64 -> F64 */
729 Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */
sewardj0f1ef862008-08-08 08:37:06 +0000730 Iop_RoundF64toF64_NEAREST, /* frin */
731 Iop_RoundF64toF64_NegINF, /* frim */
732 Iop_RoundF64toF64_PosINF, /* frip */
733 Iop_RoundF64toF64_ZERO, /* friz */
sewardjb183b852006-02-03 16:08:03 +0000734
735 /* :: F64 -> F32 */
736 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
737
738 /* :: IRRoundingMode(I32) x F64 -> F64 */
739 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
740 /* NB: pretty much the same as Iop_F64toF32, except no change
741 of type. */
742
743 /* :: F64 -> I32 */
744 Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord)
745 from FP result */
sewardjc9a43662004-11-30 18:51:59 +0000746
sewardje2ea1762010-09-22 00:56:37 +0000747 /* ------------------ 32-bit SIMD Integer ------------------ */
748
749 /* 16x2 add/sub, also signed/unsigned saturating variants */
750 Iop_Add16x2, Iop_Sub16x2,
751 Iop_QAdd16Sx2, Iop_QAdd16Ux2,
752 Iop_QSub16Sx2, Iop_QSub16Ux2,
753
754 /* 16x2 signed/unsigned halving add/sub. For each lane, these
755 compute bits 16:1 of (eg) sx(argL) + sx(argR),
756 or zx(argL) - zx(argR) etc. */
757 Iop_HAdd16Ux2, Iop_HAdd16Sx2,
758 Iop_HSub16Ux2, Iop_HSub16Sx2,
759
760 /* 8x4 add/sub, also signed/unsigned saturating variants */
761 Iop_Add8x4, Iop_Sub8x4,
762 Iop_QAdd8Sx4, Iop_QAdd8Ux4,
763 Iop_QSub8Sx4, Iop_QSub8Ux4,
764
765 /* 8x4 signed/unsigned halving add/sub. For each lane, these
766 compute bits 8:1 of (eg) sx(argL) + sx(argR),
767 or zx(argL) - zx(argR) etc. */
768 Iop_HAdd8Ux4, Iop_HAdd8Sx4,
769 Iop_HSub8Ux4, Iop_HSub8Sx4,
770
sewardj310d6b22010-10-18 16:29:40 +0000771 /* 8x4 sum of absolute unsigned differences. */
772 Iop_Sad8Ux4,
773
sewardje2ea1762010-09-22 00:56:37 +0000774 /* MISC (vector integer cmp != 0) */
775 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
776
sewardj2fdd4162010-08-22 12:59:02 +0000777 /* ------------------ 64-bit SIMD FP ------------------------ */
778
779 /* Convertion to/from int */
780 Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */
781 Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */
782 /* Fixed32 format is floating-point number with fixed number of fraction
783 bits. The number of fraction bits is passed as a second argument of
784 type I8. */
785 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
786 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
787
788 /* Binary operations */
789 Iop_Max32Fx2, Iop_Min32Fx2,
790 /* Pairwise Min and Max. See integer pairwise operations for more
791 details. */
792 Iop_PwMax32Fx2, Iop_PwMin32Fx2,
793 /* Note: For the following compares, the arm front-end assumes a
794 nan in a lane of either argument returns zero for that lane. */
795 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
796
797 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
798 element in the operand vector, and places the results in the destination
799 vector. */
800 Iop_Recip32Fx2,
801
802 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
803 Note, that if one of the arguments is zero and another one is infinity
804 of arbitrary sign the result of the operation is 2.0. */
805 Iop_Recps32Fx2,
806
807 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
808 square root of each element in the operand vector. */
809 Iop_Rsqrte32Fx2,
810
811 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
812 Note, that of one of the arguments is zero and another one is infiinty
813 of arbitrary sign the result of the operation is 1.5. */
814 Iop_Rsqrts32Fx2,
815
816 /* Unary */
817 Iop_Neg32Fx2, Iop_Abs32Fx2,
818
sewardj38a3f862005-01-13 15:06:51 +0000819 /* ------------------ 64-bit SIMD Integer. ------------------ */
820
821 /* MISC (vector integer cmp != 0) */
sewardj18069182005-01-13 19:16:04 +0000822 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
sewardj38a3f862005-01-13 15:06:51 +0000823
824 /* ADDITION (normal / unsigned sat / signed sat) */
825 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000826 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
827 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
828
829 /* PAIRWISE operations */
830 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
831 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
832 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2,
833 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
834 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
835 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
836 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
837 /* Longening variant is unary. The resulting vector contains two times
838 less elements than operand, but they are two times wider.
839 Example:
840 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
841 where a+b and c+d are unsigned 32-bit values. */
842 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
843 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000844
845 /* SUBTRACTION (normal / unsigned sat / signed sat) */
846 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000847 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
848 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
sewardj38a3f862005-01-13 15:06:51 +0000849
sewardj2fdd4162010-08-22 12:59:02 +0000850 /* ABSOLUTE VALUE */
851 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
852
853 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
854 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
855 Iop_Mul32Fx2,
sewardj38a3f862005-01-13 15:06:51 +0000856 Iop_MulHi16Ux4,
857 Iop_MulHi16Sx4,
sewardj2fdd4162010-08-22 12:59:02 +0000858 /* Plynomial multiplication treats it's arguments as coefficients of
859 polynoms over {0, 1}. */
860 Iop_PolynomialMul8x8,
861
862 /* Vector Saturating Doubling Multiply Returning High Half and
863 Vector Saturating Rounding Doubling Multiply Returning High Half */
864 /* These IROp's multiply corresponding elements in two vectors, double
865 the results, and place the most significant half of the final results
866 in the destination vector. The results are truncated or rounded. If
867 any of the results overflow, they are saturated. */
868 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
869 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000870
sewardj5ce5fd62005-04-19 23:06:11 +0000871 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
sewardj38a3f862005-01-13 15:06:51 +0000872 Iop_Avg8Ux8,
873 Iop_Avg16Ux4,
874
875 /* MIN/MAX */
sewardj2fdd4162010-08-22 12:59:02 +0000876 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
877 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
878 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
879 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000880
881 /* COMPARISON */
882 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000883 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000884 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
885
sewardj2fdd4162010-08-22 12:59:02 +0000886 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
887 bit) */
888 Iop_Cnt8x8,
889 Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2,
890 Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2,
891
892 /* VECTOR x VECTOR SHIFT / ROTATE */
893 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
894 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
895 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
896 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
897
sewardj38a3f862005-01-13 15:06:51 +0000898 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
sewardjd166e282008-02-06 11:42:45 +0000899 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000900 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
sewardjd71ba832006-12-27 01:15:29 +0000901 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
sewardj38a3f862005-01-13 15:06:51 +0000902
sewardj2fdd4162010-08-22 12:59:02 +0000903 /* VECTOR x VECTOR SATURATING SHIFT */
904 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
905 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
906 /* VECTOR x INTEGER SATURATING SHIFT */
907 Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1,
908 Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1,
909 Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1,
910
sewardj5f438dd2011-06-16 11:36:23 +0000911 /* NARROWING (binary)
912 -- narrow 2xI64 into 1xI64, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +0000913 /* For saturated narrowing, I believe there are 4 variants of
914 the basic arithmetic operation, depending on the signedness
915 of argument and result. Here are examples that exemplify
916 what I mean:
917
918 QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255;
919 return x[7:0];
920
921 QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128;
922 if (x >s 127) x = 127;
923 return x[7:0];
924
925 QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127;
926 return x[7:0];
927
928 QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0;
929 if (x >s 255) x = 255;
930 return x[7:0];
931 */
sewardj5f438dd2011-06-16 11:36:23 +0000932 Iop_QNarrowBin16Sto8Ux8,
933 Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
sewardjad2c9ea2011-10-22 09:32:16 +0000934 Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4,
sewardj38a3f862005-01-13 15:06:51 +0000935
sewardj2fdd4162010-08-22 12:59:02 +0000936 /* INTERLEAVING */
937 /* Interleave lanes from low or high halves of
sewardj38a3f862005-01-13 15:06:51 +0000938 operands. Most-significant result lane is from the left
939 arg. */
940 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
941 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000942 /* Interleave odd/even lanes of operands. Most-significant result lane
943 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are
944 identical to Interleave{HI,LO}32x2 and so are omitted.*/
945 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
946 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
947
sewardj38a3f862005-01-13 15:06:51 +0000948
sewardjd166e282008-02-06 11:42:45 +0000949 /* CONCATENATION -- build a new value by concatenating either
950 the even or odd lanes of both operands. Note that
951 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
952 and so are omitted. */
sewardj2fdd4162010-08-22 12:59:02 +0000953 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
954 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
955
956 /* GET / SET elements of VECTOR
957 GET is binop (I64, I8) -> I<elem_size>
958 SET is triop (I64, I8, I<elem_size>) -> I64 */
959 /* Note: the arm back-end handles only constant second argument */
960 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
961 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
962
963 /* DUPLICATING -- copy value to all lanes */
964 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2,
965
966 /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes
967 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
968 result.
969 It is a triop: (I64, I64, I8) -> I64 */
970 /* Note: the arm back-end handles only constant third argumnet. */
971 Iop_Extract64,
972
973 /* REVERSE the order of elements in each Half-words, Words,
974 Double-words */
975 /* Examples:
976 Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
977 Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
978 Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
979 Iop_Reverse16_8x8,
980 Iop_Reverse32_8x8, Iop_Reverse32_16x4,
981 Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2,
sewardjd166e282008-02-06 11:42:45 +0000982
983 /* PERMUTING -- copy src bytes to dst,
984 as indexed by control vector bytes:
985 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
986 argR[i] values may only be in the range 0 .. 7, else behaviour
987 is undefined. */
988 Iop_Perm8x8,
989
sewardj2fdd4162010-08-22 12:59:02 +0000990 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
991 See floating-point equiwalents for details. */
992 Iop_Recip32x2, Iop_Rsqrte32x2,
993
sewardjc6bbd472012-04-02 10:20:48 +0000994 /* ------------------ Decimal Floating Point ------------------ */
995
996 /* ARITHMETIC INSTRUCTIONS 64-bit
997 ----------------------------------
998 IRRoundingModeDFP(I32) X D64 X D64 -> D64
sewardjc6bbd472012-04-02 10:20:48 +0000999 */
1000 Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1001
1002 /* ARITHMETIC INSTRUCTIONS 128-bit
1003 ----------------------------------
1004 IRRoundingModeDFP(I32) X D128 X D128 -> D128
sewardjc6bbd472012-04-02 10:20:48 +00001005 */
1006 Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1007
sewardj26217b02012-04-12 17:19:48 +00001008 /* SHIFT SIGNIFICAND INSTRUCTIONS
1009 * The DFP significand is shifted by the number of digits specified
1010 * by the U8 operand. Digits shifted out of the leftmost digit are
1011 * lost. Zeros are supplied to the vacated positions on the right.
1012 * The sign of the result is the same as the sign of the original
1013 * operand.
sewardjcdc376d2012-04-23 11:21:12 +00001014 *
1015 * D64 x U8 -> D64 left shift and right shift respectively */
sewardj26217b02012-04-12 17:19:48 +00001016 Iop_ShlD64, Iop_ShrD64,
1017
1018 /* D128 x U8 -> D128 left shift and right shift respectively */
1019 Iop_ShlD128, Iop_ShrD128,
1020
1021
1022 /* FORMAT CONVERSION INSTRUCTIONS
1023 * D32 -> D64
1024 */
1025 Iop_D32toD64,
1026
1027 /* D64 -> D128 */
1028 Iop_D64toD128,
1029
1030 /* I64S -> D128 */
1031 Iop_I64StoD128,
1032
1033 /* IRRoundingModeDFP(I32) x D64 -> D32 */
1034 Iop_D64toD32,
1035
1036 /* IRRoundingModeDFP(I32) x D128 -> D64 */
1037 Iop_D128toD64,
1038
1039 /* IRRoundingModeDFP(I32) x I64 -> D64 */
1040 Iop_I64StoD64,
1041
1042 /* IRRoundingModeDFP(I32) x D64 -> I64 */
1043 Iop_D64toI64S,
1044
1045 /* IRRoundingModeDFP(I32) x D128 -> I64 */
1046 Iop_D128toI64S,
1047
sewardjcdc376d2012-04-23 11:21:12 +00001048 /* ROUNDING INSTRUCTIONS
1049 * IRRoundingMode(I32) x D64 -> D64
1050 * The D64 operand, if a finite number, is rounded to an integer value.
1051 */
1052 Iop_RoundD64toInt,
1053
1054 /* IRRoundingMode(I32) x D128 -> D128 */
1055 Iop_RoundD128toInt,
1056
1057 /* COMPARE INSTRUCTIONS
1058 * D64 x D64 -> IRCmpD64Result(I32) */
1059 Iop_CmpD64,
1060
1061 /* D128 x D128 -> IRCmpD64Result(I32) */
1062 Iop_CmpD128,
1063
1064 /* QUANTIZE AND ROUND INSTRUCTIONS
1065 * The source operand is converted and rounded to the form with the
1066 * immediate exponent specified by the rounding and exponent parameter.
1067 *
1068 * The second operand is converted and rounded to the form
1069 * of the first operand's exponent and the rounded based on the specified
1070 * rounding mode parameter.
1071 *
1072 * IRRoundingModeDFP(I32) x D64 x D64-> D64 */
1073 Iop_QuantizeD64,
1074
1075 /* IRRoundingModeDFP(I32) x D128 x D128 -> D128 */
1076 Iop_QuantizeD128,
1077
1078 /* IRRoundingModeDFP(I32) x I8 x D64 -> D64
1079 * The Decimal Floating point operand is rounded to the requested
1080 * significance given by the I8 operand as specified by the rounding
1081 * mode.
1082 */
1083 Iop_SignificanceRoundD64,
1084
1085 /* IRRoundingModeDFP(I32) x I8 x D128 -> D128 */
1086 Iop_SignificanceRoundD128,
1087
1088 /* EXTRACT AND INSERT INSTRUCTIONS
1089 * D64 -> I64
1090 * The exponent of the D32 or D64 operand is extracted. The
1091 * extracted exponent is converted to a 64-bit signed binary integer.
1092 */
1093 Iop_ExtractExpD64,
1094
1095 /* D128 -> I64 */
1096 Iop_ExtractExpD128,
1097
1098 /* I64 x I64 -> D64
1099 * The exponent is specified by the first I64 operand the signed
1100 * significand is given by the second I64 value. The result is a D64
1101 * value consisting of the specified significand and exponent whose
1102 * sign is that of the specified significand.
1103 */
1104 Iop_InsertExpD64,
1105
1106 /* I64 x I128 -> D128 */
1107 Iop_InsertExpD128,
1108
sewardjc6bbd472012-04-02 10:20:48 +00001109 /* Support for 128-bit DFP type */
1110 Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1111
sewardj4c96e612012-06-02 23:47:02 +00001112 /* I64 -> I64
1113 * Convert 50-bit densely packed BCD string to 60 bit BCD string
1114 */
1115 Iop_DPBtoBCD,
1116
1117 /* I64 -> I64
1118 * Convert 60 bit BCD string to 50-bit densely packed BCD string
1119 */
1120 Iop_BCDtoDPB,
1121
sewardjcdc376d2012-04-23 11:21:12 +00001122 /* Conversion I64 -> D64 */
1123 Iop_ReinterpI64asD64,
1124
sewardj5eff1c52012-04-29 20:19:17 +00001125 /* Conversion D64 -> I64 */
1126 Iop_ReinterpD64asI64,
1127
sewardj164f9272004-12-09 00:39:32 +00001128 /* ------------------ 128-bit SIMD FP. ------------------ */
sewardjc9a43662004-11-30 18:51:59 +00001129
1130 /* --- 32x4 vector FP --- */
1131
1132 /* binary */
1133 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
1134 Iop_Max32Fx4, Iop_Min32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001135 Iop_Add32Fx2, Iop_Sub32Fx2,
1136 /* Note: For the following compares, the ppc and arm front-ends assume a
cerionf294eb32005-11-16 17:21:10 +00001137 nan in a lane of either argument returns zero for that lane. */
sewardj2fdd4162010-08-22 12:59:02 +00001138 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
cerion206c3642005-11-14 00:35:59 +00001139 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
sewardjc9a43662004-11-30 18:51:59 +00001140
sewardj2fdd4162010-08-22 12:59:02 +00001141 /* Vector Absolute */
1142 Iop_Abs32Fx4,
1143
1144 /* Pairwise Max and Min. See integer pairwise operations for details. */
1145 Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1146
sewardjc9a43662004-11-30 18:51:59 +00001147 /* unary */
sewardj2fdd4162010-08-22 12:59:02 +00001148 Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
1149 Iop_Neg32Fx4,
1150
1151 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1152 element in the operand vector, and places the results in the destination
1153 vector. */
1154 Iop_Recip32Fx4,
1155
1156 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1157 Note, that if one of the arguments is zero and another one is infinity
1158 of arbitrary sign the result of the operation is 2.0. */
1159 Iop_Recps32Fx4,
1160
1161 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1162 square root of each element in the operand vector. */
1163 Iop_Rsqrte32Fx4,
1164
1165 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1166 Note, that of one of the arguments is zero and another one is infiinty
1167 of arbitrary sign the result of the operation is 1.5. */
1168 Iop_Rsqrts32Fx4,
1169
sewardjc9a43662004-11-30 18:51:59 +00001170
cerionf294eb32005-11-16 17:21:10 +00001171 /* --- Int to/from FP conversion --- */
1172 /* Unlike the standard fp conversions, these irops take no
1173 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1174 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
sewardj2fdd4162010-08-22 12:59:02 +00001175 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */
1176 Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */
1177 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (with saturation) */
cerionf294eb32005-11-16 17:21:10 +00001178 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
1179 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
sewardj2fdd4162010-08-22 12:59:02 +00001180 /* Fixed32 format is floating-point number with fixed number of fraction
1181 bits. The number of fraction bits is passed as a second argument of
1182 type I8. */
1183 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1184 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1185
1186 /* --- Single to/from half conversion --- */
sewardj5f438dd2011-06-16 11:36:23 +00001187 /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
sewardj2fdd4162010-08-22 12:59:02 +00001188 Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */
cerionf294eb32005-11-16 17:21:10 +00001189
sewardjc9a43662004-11-30 18:51:59 +00001190 /* --- 32x4 lowest-lane-only scalar FP --- */
1191
1192 /* In binary cases, upper 3/4 is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001193 unary cases, upper 3/4 is copied from the operand. */
sewardjc9a43662004-11-30 18:51:59 +00001194
1195 /* binary */
1196 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1197 Iop_Max32F0x4, Iop_Min32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001198 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
sewardjc9a43662004-11-30 18:51:59 +00001199
1200 /* unary */
1201 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001202
1203 /* --- 64x2 vector FP --- */
1204
1205 /* binary */
1206 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
1207 Iop_Max64Fx2, Iop_Min64Fx2,
1208 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1209
1210 /* unary */
1211 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
1212
1213 /* --- 64x2 lowest-lane-only scalar FP --- */
1214
1215 /* In binary cases, upper half is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001216 unary cases, upper half is copied from the operand. */
sewardj636ad762004-12-07 11:16:04 +00001217
1218 /* binary */
1219 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1220 Iop_Max64F0x2, Iop_Min64F0x2,
1221 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1222
1223 /* unary */
1224 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
sewardjc9a43662004-11-30 18:51:59 +00001225
1226 /* --- pack / unpack --- */
1227
sewardjf0c1c582005-02-07 23:47:38 +00001228 /* 64 <-> 128 bit vector */
1229 Iop_V128to64, // :: V128 -> I64, low half
1230 Iop_V128HIto64, // :: V128 -> I64, high half
1231 Iop_64HLtoV128, // :: (I64,I64) -> V128
sewardjc9a43662004-11-30 18:51:59 +00001232
sewardjf0c1c582005-02-07 23:47:38 +00001233 Iop_64UtoV128,
1234 Iop_SetV128lo64,
sewardj164f9272004-12-09 00:39:32 +00001235
sewardjf0c1c582005-02-07 23:47:38 +00001236 /* 32 <-> 128 bit vector */
1237 Iop_32UtoV128,
1238 Iop_V128to32, // :: V128 -> I32, lowest lane
1239 Iop_SetV128lo32, // :: (V128,I32) -> V128
sewardj70f676d2004-12-10 14:59:57 +00001240
sewardj164f9272004-12-09 00:39:32 +00001241 /* ------------------ 128-bit SIMD Integer. ------------------ */
1242
1243 /* BITWISE OPS */
sewardjf0c1c582005-02-07 23:47:38 +00001244 Iop_NotV128,
1245 Iop_AndV128, Iop_OrV128, Iop_XorV128,
sewardj164f9272004-12-09 00:39:32 +00001246
cerionf887b3e2005-09-13 16:34:28 +00001247 /* VECTOR SHIFT (shift amt :: Ity_I8) */
1248 Iop_ShlV128, Iop_ShrV128,
1249
sewardj2e383862004-12-12 16:46:47 +00001250 /* MISC (vector integer cmp != 0) */
1251 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
sewardj70f676d2004-12-10 14:59:57 +00001252
sewardj164f9272004-12-09 00:39:32 +00001253 /* ADDITION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001254 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2,
1255 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1256 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001257
1258 /* SUBTRACTION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001259 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2,
1260 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1261 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001262
1263 /* MULTIPLICATION (normal / high half of signed/unsigned) */
sewardj2fdd4162010-08-22 12:59:02 +00001264 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4,
1265 Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1266 Iop_MulHi16Sx8, Iop_MulHi32Sx4,
cerion24d06f12005-11-09 21:34:20 +00001267 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
cerion1ac656a2005-11-04 19:44:48 +00001268 Iop_MullEven8Ux16, Iop_MullEven16Ux8,
1269 Iop_MullEven8Sx16, Iop_MullEven16Sx8,
sewardj2fdd4162010-08-22 12:59:02 +00001270 /* FIXME: document these */
1271 Iop_Mull8Ux8, Iop_Mull8Sx8,
1272 Iop_Mull16Ux4, Iop_Mull16Sx4,
1273 Iop_Mull32Ux2, Iop_Mull32Sx2,
1274 /* Vector Saturating Doubling Multiply Returning High Half and
1275 Vector Saturating Rounding Doubling Multiply Returning High Half */
1276 /* These IROp's multiply corresponding elements in two vectors, double
1277 the results, and place the most significant half of the final results
1278 in the destination vector. The results are truncated or rounded. If
1279 any of the results overflow, they are saturated. */
1280 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4,
1281 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4,
1282 /* Doubling saturating multiplication (long) (I64, I64) -> V128 */
1283 Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2,
1284 /* Plynomial multiplication treats it's arguments as coefficients of
1285 polynoms over {0, 1}. */
1286 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1287 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */
1288
1289 /* PAIRWISE operations */
1290 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1291 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1292 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1293 Iop_PwAdd32Fx2,
1294 /* Longening variant is unary. The resulting vector contains two times
1295 less elements than operand, but they are two times wider.
1296 Example:
1297 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1298 where a+b and c+d are unsigned 32-bit values. */
1299 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1300 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1301
1302 /* ABSOLUTE VALUE */
1303 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4,
cerion1ac656a2005-11-04 19:44:48 +00001304
sewardj5ce5fd62005-04-19 23:06:11 +00001305 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
cerionf887b3e2005-09-13 16:34:28 +00001306 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1307 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
sewardj164f9272004-12-09 00:39:32 +00001308
1309 /* MIN/MAX */
cerionf887b3e2005-09-13 16:34:28 +00001310 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
1311 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
1312 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
1313 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001314
1315 /* COMPARISON */
sewardjd8815622011-10-19 15:24:01 +00001316 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2,
sewardj69d98e32010-06-18 08:17:41 +00001317 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
cerionf887b3e2005-09-13 16:34:28 +00001318 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001319
sewardj2fdd4162010-08-22 12:59:02 +00001320 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1321 bit) */
1322 Iop_Cnt8x16,
1323 Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4,
1324 Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4,
1325
sewardj164f9272004-12-09 00:39:32 +00001326 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
cerion2a4b8452005-09-15 16:28:36 +00001327 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1328 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001329 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
sewardj164f9272004-12-09 00:39:32 +00001330
cerionf887b3e2005-09-13 16:34:28 +00001331 /* VECTOR x VECTOR SHIFT / ROTATE */
sewardj2fdd4162010-08-22 12:59:02 +00001332 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1333 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1334 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1335 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
sewardj1bee5612005-11-10 18:10:58 +00001336 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
cerionf887b3e2005-09-13 16:34:28 +00001337
sewardj2fdd4162010-08-22 12:59:02 +00001338 /* VECTOR x VECTOR SATURATING SHIFT */
1339 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1340 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1341 /* VECTOR x INTEGER SATURATING SHIFT */
1342 Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2,
1343 Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2,
1344 Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2,
1345
sewardj5f438dd2011-06-16 11:36:23 +00001346 /* NARROWING (binary)
1347 -- narrow 2xV128 into 1xV128, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +00001348 /* See comments above w.r.t. U vs S issues in saturated narrowing. */
sewardj5f438dd2011-06-16 11:36:23 +00001349 Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1350 Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1351 Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1352 Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
sewardj164f9272004-12-09 00:39:32 +00001353
sewardj5f438dd2011-06-16 11:36:23 +00001354 /* NARROWING (unary) -- narrow V128 into I64 */
1355 Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1356 /* Saturating narrowing from signed source to signed/unsigned destination */
1357 Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1358 Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1359 /* Saturating narrowing from unsigned source to unsigned destination */
1360 Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1361
1362 /* WIDENING -- sign or zero extend each element of the argument
1363 vector to the twice original size. The resulting vector consists of
sewardj2fdd4162010-08-22 12:59:02 +00001364 the same number of elements but each element and the vector itself
sewardj5f438dd2011-06-16 11:36:23 +00001365 are twice as wide.
sewardj2fdd4162010-08-22 12:59:02 +00001366 All operations are I64->V128.
1367 Example
sewardj5f438dd2011-06-16 11:36:23 +00001368 Iop_Widen32Sto64x2( [a, b] ) = [c, d]
sewardj2fdd4162010-08-22 12:59:02 +00001369 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
sewardj5f438dd2011-06-16 11:36:23 +00001370 Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1371 Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001372
1373 /* INTERLEAVING */
1374 /* Interleave lanes from low or high halves of
sewardj164f9272004-12-09 00:39:32 +00001375 operands. Most-significant result lane is from the left
1376 arg. */
1377 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1378 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001379 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
cerionf887b3e2005-09-13 16:34:28 +00001380 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001381 /* Interleave odd/even lanes of operands. Most-significant result lane
1382 is from the left arg. */
1383 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1384 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1385 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1386
1387 /* CONCATENATION -- build a new value by concatenating either
1388 the even or odd lanes of both operands. */
1389 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1390 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1391
1392 /* GET elements of VECTOR
1393 GET is binop (V128, I8) -> I<elem_size> */
1394 /* Note: the arm back-end handles only constant second argument. */
1395 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
cerionf887b3e2005-09-13 16:34:28 +00001396
1397 /* DUPLICATING -- copy value to all lanes */
sewardj2fdd4162010-08-22 12:59:02 +00001398 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
1399
1400 /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes
1401 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
1402 result.
1403 It is a triop: (V128, V128, I8) -> V128 */
1404 /* Note: the ARM back end handles only constant arg3 in this operation. */
1405 Iop_ExtractV128,
1406
1407 /* REVERSE the order of elements in each Half-words, Words,
1408 Double-words */
1409 /* Examples:
1410 Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1411 Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */
1412 Iop_Reverse16_8x16,
1413 Iop_Reverse32_8x16, Iop_Reverse32_16x8,
1414 Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4,
cerionf887b3e2005-09-13 16:34:28 +00001415
1416 /* PERMUTING -- copy src bytes to dst,
sewardjdc1f9132005-10-22 12:49:49 +00001417 as indexed by control vector bytes:
1418 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1419 argR[i] values may only be in the range 0 .. 15, else behaviour
1420 is undefined. */
sewardj2fdd4162010-08-22 12:59:02 +00001421 Iop_Perm8x16,
sewardjd8bca7e2012-06-20 11:46:19 +00001422 Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
sewardj2fdd4162010-08-22 12:59:02 +00001423
1424 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1425 See floating-point equiwalents for details. */
sewardjc4530ae2012-05-21 10:18:49 +00001426 Iop_Recip32x4, Iop_Rsqrte32x4,
1427
1428 /* ------------------ 256-bit SIMD Integer. ------------------ */
1429
1430 /* Pack/unpack */
sewardj4b1cc832012-06-13 11:10:20 +00001431 Iop_V256to64_0, // V256 -> I64, extract least significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001432 Iop_V256to64_1,
1433 Iop_V256to64_2,
sewardj4b1cc832012-06-13 11:10:20 +00001434 Iop_V256to64_3, // V256 -> I64, extract most significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001435
sewardj56c30312012-06-12 08:45:39 +00001436 Iop_64x4toV256, // (I64,I64,I64,I64)->V256
sewardjc4530ae2012-05-21 10:18:49 +00001437 // first arg is most significant lane
sewardj56c30312012-06-12 08:45:39 +00001438
sewardj4b1cc832012-06-13 11:10:20 +00001439 Iop_V256toV128_0, // V256 -> V128, less significant lane
1440 Iop_V256toV128_1, // V256 -> V128, more significant lane
1441 Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1442
1443 Iop_AndV256,
sewardj2a2bda92012-06-14 23:32:02 +00001444 Iop_OrV256,
sewardj4b1cc832012-06-13 11:10:20 +00001445 Iop_XorV256,
sewardj2a2bda92012-06-14 23:32:02 +00001446 Iop_NotV256,
sewardj4b1cc832012-06-13 11:10:20 +00001447
sewardj23db8a02012-06-25 07:46:18 +00001448 /* MISC (vector integer cmp != 0) */
1449 Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1450
sewardj56c30312012-06-12 08:45:39 +00001451 /* ------------------ 256-bit SIMD FP. ------------------ */
1452 Iop_Add64Fx4,
1453 Iop_Sub64Fx4,
1454 Iop_Mul64Fx4,
1455 Iop_Div64Fx4,
1456 Iop_Add32Fx8,
1457 Iop_Sub32Fx8,
1458 Iop_Mul32Fx8,
sewardjf0ad4f82012-06-19 06:57:59 +00001459 Iop_Div32Fx8,
1460
1461 Iop_Sqrt32Fx8,
1462 Iop_Sqrt64Fx4,
sewardj8eb7ae82012-06-24 14:00:27 +00001463 Iop_RSqrt32Fx8,
sewardj82096922012-06-24 14:57:59 +00001464 Iop_Recip32Fx8,
sewardj8eb7ae82012-06-24 14:00:27 +00001465
1466 Iop_Max32Fx8, Iop_Min32Fx8,
1467 Iop_Max64Fx4, Iop_Min64Fx4
sewardjac6b7122004-06-27 01:03:57 +00001468 }
1469 IROp;
sewardjec6ad592004-06-20 12:26:53 +00001470
sewardj57c10c82006-11-15 02:57:05 +00001471/* Pretty-print an op. */
sewardj35421a32004-07-05 13:12:34 +00001472extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +00001473
sewardje3d0d2e2004-06-27 10:42:44 +00001474
sewardjb183b852006-02-03 16:08:03 +00001475/* Encoding of IEEE754-specified rounding modes. This is the same as
sewardjf1b5b1a2006-02-03 22:54:17 +00001476 the encoding used by Intel IA32 to indicate x87 rounding mode.
1477 Note, various front and back ends rely on the actual numerical
1478 values of these, so do not change them. */
sewardjc9868d72004-09-12 19:19:17 +00001479typedef
sewardjf1b5b1a2006-02-03 22:54:17 +00001480 enum {
1481 Irrm_NEAREST = 0,
1482 Irrm_NegINF = 1,
1483 Irrm_PosINF = 2,
1484 Irrm_ZERO = 3
1485 }
sewardjc9868d72004-09-12 19:19:17 +00001486 IRRoundingMode;
1487
sewardjc6bbd472012-04-02 10:20:48 +00001488/* DFP encoding of IEEE754 2008 specified rounding modes extends the two bit
1489 * binary floating point rounding mode (IRRoundingMode) to three bits. The
1490 * DFP rounding modes are a super set of the binary rounding modes. The
1491 * encoding was chosen such that the mapping of the least significant two bits
1492 * of the IR to POWER encodings is same. The upper IR encoding bit is just
1493 * a logical OR of the upper rounding mode bit from the POWER encoding.
1494 */
1495typedef
1496 enum {
1497 Irrm_DFP_NEAREST = 0, // Round to nearest, ties to even
1498 Irrm_DFP_NegINF = 1, // Round to negative infinity
1499 Irrm_DFP_PosINF = 2, // Round to posative infinity
1500 Irrm_DFP_ZERO = 3, // Round toward zero
1501 Irrm_DFP_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0
1502 Irrm_DFP_PREPARE_SHORTER = 5, // Round to prepare for storter
1503 // precision
1504 Irrm_DFP_AWAY_FROM_ZERO = 6, // Round to away from 0
1505 Irrm_DFP_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0
1506 }
1507 IRRoundingModeDFP;
1508
sewardjc9868d72004-09-12 19:19:17 +00001509/* Floating point comparison result values, as created by Iop_CmpF64.
1510 This is also derived from what IA32 does. */
1511typedef
1512 enum {
1513 Ircr_UN = 0x45,
1514 Ircr_LT = 0x01,
1515 Ircr_GT = 0x00,
1516 Ircr_EQ = 0x40
1517 }
1518 IRCmpF64Result;
1519
sewardj2019a972011-03-07 16:04:07 +00001520typedef IRCmpF64Result IRCmpF32Result;
1521typedef IRCmpF64Result IRCmpF128Result;
sewardjc9868d72004-09-12 19:19:17 +00001522
sewardjc97096c2004-06-30 09:28:04 +00001523/* ------------------ Expressions ------------------ */
sewardjd1725d12004-08-12 20:46:53 +00001524
florianeadea2e2012-06-06 12:53:14 +00001525typedef struct _IRQop IRQop; /* forward declaration */
1526typedef struct _IRTriop IRTriop; /* forward declaration */
florian96d7cc32012-06-01 20:41:24 +00001527
1528
sewardj57c10c82006-11-15 02:57:05 +00001529/* The different kinds of expressions. Their meaning is explained below
1530 in the comments for IRExpr. */
sewardje3d0d2e2004-06-27 10:42:44 +00001531typedef
sewardjb3bce0e2004-09-14 23:20:10 +00001532 enum {
sewardjc4356f02007-11-09 21:15:04 +00001533 Iex_Binder=0x15000,
sewardj57c10c82006-11-15 02:57:05 +00001534 Iex_Get,
1535 Iex_GetI,
sewardjdd40fdf2006-12-24 02:20:24 +00001536 Iex_RdTmp,
sewardj57c10c82006-11-15 02:57:05 +00001537 Iex_Qop,
1538 Iex_Triop,
1539 Iex_Binop,
1540 Iex_Unop,
1541 Iex_Load,
1542 Iex_Const,
1543 Iex_Mux0X,
1544 Iex_CCall
sewardjb3bce0e2004-09-14 23:20:10 +00001545 }
sewardje3d0d2e2004-06-27 10:42:44 +00001546 IRExprTag;
1547
sewardj57c10c82006-11-15 02:57:05 +00001548/* An expression. Stored as a tagged union. 'tag' indicates what kind
1549 of expression this is. 'Iex' is the union that holds the fields. If
1550 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1551 expression, and the fields can be accessed with
1552 'e.Iex.Load.<fieldname>'.
1553
1554 For each kind of expression, we show what it looks like when
1555 pretty-printed with ppIRExpr().
1556*/
1557typedef
1558 struct _IRExpr
sewardje3d0d2e2004-06-27 10:42:44 +00001559 IRExpr;
1560
sewardj57c10c82006-11-15 02:57:05 +00001561struct _IRExpr {
1562 IRExprTag tag;
1563 union {
1564 /* Used only in pattern matching within Vex. Should not be seen
1565 outside of Vex. */
1566 struct {
1567 Int binder;
1568 } Binder;
1569
1570 /* Read a guest register, at a fixed offset in the guest state.
1571 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1572 */
1573 struct {
1574 Int offset; /* Offset into the guest state */
1575 IRType ty; /* Type of the value being read */
1576 } Get;
1577
1578 /* Read a guest register at a non-fixed offset in the guest
1579 state. This allows circular indexing into parts of the guest
1580 state, which is essential for modelling situations where the
1581 identity of guest registers is not known until run time. One
1582 example is the x87 FP register stack.
1583
1584 The part of the guest state to be treated as a circular array
sewardjdd40fdf2006-12-24 02:20:24 +00001585 is described in the IRRegArray 'descr' field. It holds the
sewardj57c10c82006-11-15 02:57:05 +00001586 offset of the first element in the array, the type of each
1587 element, and the number of elements.
1588
1589 The array index is indicated rather indirectly, in a way
1590 which makes optimisation easy: as the sum of variable part
1591 (the 'ix' field) and a constant offset (the 'bias' field).
1592
1593 Since the indexing is circular, the actual array index to use
1594 is computed as (ix + bias) % num-of-elems-in-the-array.
1595
1596 Here's an example. The description
1597
1598 (96:8xF64)[t39,-7]
1599
1600 describes an array of 8 F64-typed values, the
1601 guest-state-offset of the first being 96. This array is
1602 being indexed at (t39 - 7) % 8.
1603
1604 It is important to get the array size/type exactly correct
1605 since IR optimisation looks closely at such info in order to
1606 establish aliasing/non-aliasing between seperate GetI and
1607 PutI events, which is used to establish when they can be
1608 reordered, etc. Putting incorrect info in will lead to
1609 obscure IR optimisation bugs.
1610
1611 ppIRExpr output: GETI<descr>[<ix>,<bias]
1612 eg. GETI(128:8xI8)[t1,0]
1613 */
1614 struct {
sewardjdd40fdf2006-12-24 02:20:24 +00001615 IRRegArray* descr; /* Part of guest state treated as circular */
1616 IRExpr* ix; /* Variable part of index into array */
1617 Int bias; /* Constant offset part of index into array */
sewardj57c10c82006-11-15 02:57:05 +00001618 } GetI;
1619
1620 /* The value held by a temporary.
1621 ppIRExpr output: t<tmp>, eg. t1
1622 */
1623 struct {
1624 IRTemp tmp; /* The temporary number */
sewardjdd40fdf2006-12-24 02:20:24 +00001625 } RdTmp;
sewardj57c10c82006-11-15 02:57:05 +00001626
1627 /* A quaternary operation.
1628 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1629 eg. MAddF64r32(t1, t2, t3, t4)
1630 */
1631 struct {
florian96d7cc32012-06-01 20:41:24 +00001632 IRQop* details;
sewardj57c10c82006-11-15 02:57:05 +00001633 } Qop;
1634
1635 /* A ternary operation.
1636 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1637 eg. MulF64(1, 2.0, 3.0)
1638 */
1639 struct {
florian420bfa92012-06-02 20:29:22 +00001640 IRTriop* details;
sewardj57c10c82006-11-15 02:57:05 +00001641 } Triop;
1642
1643 /* A binary operation.
1644 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1645 */
1646 struct {
1647 IROp op; /* op-code */
1648 IRExpr* arg1; /* operand 1 */
1649 IRExpr* arg2; /* operand 2 */
1650 } Binop;
1651
1652 /* A unary operation.
1653 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1654 */
1655 struct {
1656 IROp op; /* op-code */
1657 IRExpr* arg; /* operand */
1658 } Unop;
1659
sewardje768e922009-11-26 17:17:37 +00001660 /* A load from memory -- a normal load, not a load-linked.
1661 Load-Linkeds (and Store-Conditionals) are instead represented
1662 by IRStmt.LLSC since Load-Linkeds have side effects and so
1663 are not semantically valid IRExpr's.
sewardj57c10c82006-11-15 02:57:05 +00001664 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1665 */
1666 struct {
1667 IREndness end; /* Endian-ness of the load */
1668 IRType ty; /* Type of the loaded value */
1669 IRExpr* addr; /* Address being loaded from */
1670 } Load;
1671
1672 /* A constant-valued expression.
1673 ppIRExpr output: <con>, eg. 0x4:I32
1674 */
1675 struct {
1676 IRConst* con; /* The constant itself */
1677 } Const;
1678
1679 /* A call to a pure (no side-effects) helper C function.
1680
1681 With the 'cee' field, 'name' is the function's name. It is
1682 only used for pretty-printing purposes. The address to call
1683 (host address, of course) is stored in the 'addr' field
1684 inside 'cee'.
1685
1686 The 'args' field is a NULL-terminated array of arguments.
1687 The stated return IRType, and the implied argument types,
1688 must match that of the function being called well enough so
1689 that the back end can actually generate correct code for the
1690 call.
1691
1692 The called function **must** satisfy the following:
1693
1694 * no side effects -- must be a pure function, the result of
1695 which depends only on the passed parameters.
1696
1697 * it may not look at, nor modify, any of the guest state
1698 since that would hide guest state transitions from
1699 instrumenters
1700
1701 * it may not access guest memory, since that would hide
1702 guest memory transactions from the instrumenters
1703
florian52af7bc2012-05-12 03:44:49 +00001704 * it must not assume that arguments are being evaluated in a
1705 particular order. The oder of evaluation is unspecified.
1706
sewardj57c10c82006-11-15 02:57:05 +00001707 This is restrictive, but makes the semantics clean, and does
1708 not interfere with IR optimisation.
1709
1710 If you want to call a helper which can mess with guest state
1711 and/or memory, instead use Ist_Dirty. This is a lot more
1712 flexible, but you have to give a bunch of details about what
1713 the helper does (and you better be telling the truth,
1714 otherwise any derived instrumentation will be wrong). Also
1715 Ist_Dirty inhibits various IR optimisations and so can cause
1716 quite poor code to be generated. Try to avoid it.
1717
1718 ppIRExpr output: <cee>(<args>):<retty>
1719 eg. foo{0x80489304}(t1, t2):I32
1720 */
1721 struct {
1722 IRCallee* cee; /* Function to call. */
1723 IRType retty; /* Type of return value. */
1724 IRExpr** args; /* Vector of argument expressions. */
1725 } CCall;
1726
1727 /* A ternary if-then-else operator. It returns expr0 if cond is
1728 zero, exprX otherwise. Note that it is STRICT, ie. both
1729 expr0 and exprX are evaluated in all cases.
1730
1731 ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1732 eg. Mux0X(t6,t7,t8)
1733 */
1734 struct {
1735 IRExpr* cond; /* Condition */
1736 IRExpr* expr0; /* True expression */
1737 IRExpr* exprX; /* False expression */
1738 } Mux0X;
1739 } Iex;
1740};
1741
florian420bfa92012-06-02 20:29:22 +00001742/* ------------------ A ternary expression ---------------------- */
1743struct _IRTriop {
1744 IROp op; /* op-code */
1745 IRExpr* arg1; /* operand 1 */
1746 IRExpr* arg2; /* operand 2 */
1747 IRExpr* arg3; /* operand 3 */
1748};
1749
florian96d7cc32012-06-01 20:41:24 +00001750/* ------------------ A quarternary expression ------------------ */
1751struct _IRQop {
1752 IROp op; /* op-code */
1753 IRExpr* arg1; /* operand 1 */
1754 IRExpr* arg2; /* operand 2 */
1755 IRExpr* arg3; /* operand 3 */
1756 IRExpr* arg4; /* operand 4 */
1757};
1758
sewardj57c10c82006-11-15 02:57:05 +00001759/* Expression constructors. */
sewardj443cd9d2004-07-18 23:06:45 +00001760extern IRExpr* IRExpr_Binder ( Int binder );
1761extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjdd40fdf2006-12-24 02:20:24 +00001762extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
1763extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
sewardj40c80262006-02-08 19:30:46 +00001764extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1765 IRExpr* arg3, IRExpr* arg4 );
sewardjb183b852006-02-03 16:08:03 +00001766extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1767 IRExpr* arg2, IRExpr* arg3 );
sewardj443cd9d2004-07-18 23:06:45 +00001768extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1769extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
sewardje768e922009-11-26 17:17:37 +00001770extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
sewardj443cd9d2004-07-18 23:06:45 +00001771extern IRExpr* IRExpr_Const ( IRConst* con );
sewardj8ea867b2004-10-30 19:03:02 +00001772extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
sewardj443cd9d2004-07-18 23:06:45 +00001773extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
sewardje3d0d2e2004-06-27 10:42:44 +00001774
sewardj57c10c82006-11-15 02:57:05 +00001775/* Deep-copy an IRExpr. */
sewardjdd40fdf2006-12-24 02:20:24 +00001776extern IRExpr* deepCopyIRExpr ( IRExpr* );
sewardj695cff92004-10-13 14:50:14 +00001777
sewardj57c10c82006-11-15 02:57:05 +00001778/* Pretty-print an IRExpr. */
sewardj35421a32004-07-05 13:12:34 +00001779extern void ppIRExpr ( IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00001780
sewardj57c10c82006-11-15 02:57:05 +00001781/* NULL-terminated IRExpr vector constructors, suitable for
1782 use as arg lists in clean/dirty helper calls. */
sewardjc5fc7aa2004-10-27 23:00:55 +00001783extern IRExpr** mkIRExprVec_0 ( void );
sewardjf9655262004-10-31 20:02:16 +00001784extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1785extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1786extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1787extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
sewardj78ec32b2007-01-08 05:09:55 +00001788extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1789 IRExpr* );
1790extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1791 IRExpr*, IRExpr* );
1792extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
sewardjf32c67d2004-11-08 13:10:44 +00001793 IRExpr*, IRExpr*, IRExpr* );
sewardj2fdd4162010-08-22 12:59:02 +00001794extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1795 IRExpr*, IRExpr*, IRExpr*, IRExpr*);
sewardjc5fc7aa2004-10-27 23:00:55 +00001796
sewardj57c10c82006-11-15 02:57:05 +00001797/* IRExpr copiers:
sewardjdd40fdf2006-12-24 02:20:24 +00001798 - shallowCopy: shallow-copy (ie. create a new vector that shares the
sewardj57c10c82006-11-15 02:57:05 +00001799 elements with the original).
sewardjdd40fdf2006-12-24 02:20:24 +00001800 - deepCopy: deep-copy (ie. create a completely new vector). */
1801extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1802extern IRExpr** deepCopyIRExprVec ( IRExpr** );
sewardjc5fc7aa2004-10-27 23:00:55 +00001803
sewardjf9655262004-10-31 20:02:16 +00001804/* Make a constant expression from the given host word taking into
sewardj57c10c82006-11-15 02:57:05 +00001805 account (of course) the host word size. */
sewardj49651f42004-10-28 22:11:04 +00001806extern IRExpr* mkIRExpr_HWord ( HWord );
1807
sewardjf9655262004-10-31 20:02:16 +00001808/* Convenience function for constructing clean helper calls. */
1809extern
1810IRExpr* mkIRExprCCall ( IRType retty,
sewardj2d49b432005-02-01 00:37:06 +00001811 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00001812 IRExpr** args );
1813
sewardj49651f42004-10-28 22:11:04 +00001814
sewardj57c10c82006-11-15 02:57:05 +00001815/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1816 * Iex_Const). */
sewardj496a58d2005-03-20 18:44:44 +00001817static inline Bool isIRAtom ( IRExpr* e ) {
sewardjdd40fdf2006-12-24 02:20:24 +00001818 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
sewardj49651f42004-10-28 22:11:04 +00001819}
1820
sewardj496a58d2005-03-20 18:44:44 +00001821/* Are these two IR atoms identical? Causes an assertion
1822 failure if they are passed non-atoms. */
1823extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1824
sewardje87b4842004-07-10 12:23:30 +00001825
sewardj893aada2004-11-29 19:57:54 +00001826/* ------------------ Jump kinds ------------------ */
1827
1828/* This describes hints which can be passed to the dispatcher at guest
1829 control-flow transfer points.
sewardj7ce9d152005-03-15 16:54:13 +00001830
sewardj57c10c82006-11-15 02:57:05 +00001831 Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1832 guest_TISTART and guest_TILEN, which specify the start and length
1833 of the region to be invalidated. These are both the size of a
1834 guest word. It is the responsibility of the relevant toIR.c to
1835 ensure that these are filled in with suitable values before issuing
1836 a jump of kind Ijk_TInval.
sewardj9dd9cf12006-01-20 14:13:55 +00001837
1838 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
sewardj57c10c82006-11-15 02:57:05 +00001839 pseudo-register guest_EMWARN, which is 32-bits regardless of the
1840 host or guest word size. That register should be made to hold an
1841 EmWarn_* value to indicate the reason for the exit.
sewardj9dd9cf12006-01-20 14:13:55 +00001842
1843 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1844 cannot continue) and so the jump destination can be anything.
sewardje86310f2009-03-19 22:21:40 +00001845
1846 Re Ijk_Sys_ (syscall jumps): the guest state must have a
1847 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1848 word. Front ends should set this to be the IP at the most recently
1849 executed kernel-entering (system call) instruction. This makes it
1850 very much easier (viz, actually possible at all) to back up the
1851 guest to restart a syscall that has been interrupted by a signal.
sewardj893aada2004-11-29 19:57:54 +00001852*/
1853typedef
sewardjc6f970f2012-04-02 21:54:49 +00001854 enum {
1855 Ijk_INVALID=0x16000,
1856 Ijk_Boring, /* not interesting; just goto next */
sewardj893aada2004-11-29 19:57:54 +00001857 Ijk_Call, /* guest is doing a call */
1858 Ijk_Ret, /* guest is doing a return */
1859 Ijk_ClientReq, /* do guest client req before continuing */
sewardj893aada2004-11-29 19:57:54 +00001860 Ijk_Yield, /* client is yielding to thread scheduler */
sewardj52444cb2004-12-13 14:09:01 +00001861 Ijk_EmWarn, /* report emulation warning before continuing */
sewardj9dd9cf12006-01-20 14:13:55 +00001862 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
sewardj52444cb2004-12-13 14:09:01 +00001863 Ijk_NoDecode, /* next instruction cannot be decoded */
sewardj7ce9d152005-03-15 16:54:13 +00001864 Ijk_MapFail, /* Vex-provided address translation failed */
sewardjf07ed032005-08-07 14:48:03 +00001865 Ijk_TInval, /* Invalidate translations before continuing. */
sewardjce02aa72006-01-12 12:27:58 +00001866 Ijk_NoRedir, /* Jump to un-redirected guest addr */
sewardj0f500042007-08-29 09:09:17 +00001867 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
1868 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
sewardje9d8a262009-07-01 08:06:34 +00001869 Ijk_SigBUS, /* current instruction synths SIGBUS */
sewardj4fa325a2005-11-03 13:27:24 +00001870 /* Unfortunately, various guest-dependent syscall kinds. They
1871 all mean: do a syscall before continuing. */
sewardj6c299f32009-12-31 18:00:12 +00001872 Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
sewardj4fa325a2005-11-03 13:27:24 +00001873 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
1874 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
sewardjd660d412008-12-03 21:29:59 +00001875 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
1876 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
sewardj4fa325a2005-11-03 13:27:24 +00001877 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes
1878 invalid at the point this happens. */
sewardj893aada2004-11-29 19:57:54 +00001879 }
1880 IRJumpKind;
1881
1882extern void ppIRJumpKind ( IRJumpKind );
1883
1884
sewardjb3bce0e2004-09-14 23:20:10 +00001885/* ------------------ Dirty helper calls ------------------ */
sewardje87b4842004-07-10 12:23:30 +00001886
sewardj57c10c82006-11-15 02:57:05 +00001887/* A dirty call is a flexible mechanism for calling (possibly
1888 conditionally) a helper function or procedure. The helper function
1889 may read, write or modify client memory, and may read, write or
1890 modify client state. It can take arguments and optionally return a
1891 value. It may return different results and/or do different things
1892 when called repeatedly with the same arguments, by means of storing
1893 private state.
sewardje87b4842004-07-10 12:23:30 +00001894
sewardjc5fc7aa2004-10-27 23:00:55 +00001895 If a value is returned, it is assigned to the nominated return
1896 temporary.
sewardjb3bce0e2004-09-14 23:20:10 +00001897
1898 Dirty calls are statements rather than expressions for obvious
sewardj57c10c82006-11-15 02:57:05 +00001899 reasons. If a dirty call is marked as writing guest state, any
sewardjc5fc7aa2004-10-27 23:00:55 +00001900 values derived from the written parts of the guest state are
1901 invalid. Similarly, if the dirty call is stated as writing
1902 memory, any loaded values are invalidated by it.
sewardjb3bce0e2004-09-14 23:20:10 +00001903
1904 In order that instrumentation is possible, the call must state, and
sewardj57c10c82006-11-15 02:57:05 +00001905 state correctly:
sewardjb3bce0e2004-09-14 23:20:10 +00001906
1907 * whether it reads, writes or modifies memory, and if so where
1908 (only one chunk can be stated)
1909
1910 * whether it reads, writes or modifies guest state, and if so which
1911 pieces (several pieces may be stated, and currently their extents
1912 must be known at translation-time).
sewardjc5fc7aa2004-10-27 23:00:55 +00001913
1914 Normally, code is generated to pass just the args to the helper.
1915 However, if .needsBBP is set, then an extra first argument is
1916 passed, which is the baseblock pointer, so that the callee can
1917 access the guest state. It is invalid for .nFxState to be zero
1918 but .needsBBP to be True, since .nFxState==0 is a claim that the
1919 call does not access guest state.
sewardjb8385d82004-11-02 01:34:15 +00001920
1921 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
florian52af7bc2012-05-12 03:44:49 +00001922 arguments are evaluated REGARDLESS of the guard value. The order of
1923 argument evaluation is unspecified. The guard expression is evaluated
1924 AFTER the arguments have been evaluated.
sewardje87b4842004-07-10 12:23:30 +00001925*/
sewardjc97096c2004-06-30 09:28:04 +00001926
sewardja0e83b02005-01-06 12:36:38 +00001927#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
sewardjb3bce0e2004-09-14 23:20:10 +00001928
sewardj57c10c82006-11-15 02:57:05 +00001929/* Effects on resources (eg. registers, memory locations) */
sewardjb3bce0e2004-09-14 23:20:10 +00001930typedef
1931 enum {
sewardjc9069f22012-06-01 16:09:50 +00001932 Ifx_None = 0x1700, /* no effect */
sewardj17442fe2004-09-20 14:54:28 +00001933 Ifx_Read, /* reads the resource */
1934 Ifx_Write, /* writes the resource */
1935 Ifx_Modify, /* modifies the resource */
sewardjb3bce0e2004-09-14 23:20:10 +00001936 }
1937 IREffect;
1938
sewardj57c10c82006-11-15 02:57:05 +00001939/* Pretty-print an IREffect */
sewardjb3bce0e2004-09-14 23:20:10 +00001940extern void ppIREffect ( IREffect );
1941
1942
1943typedef
sewardjc9069f22012-06-01 16:09:50 +00001944 struct _IRDirty {
sewardjb3bce0e2004-09-14 23:20:10 +00001945 /* What to call, and details of args/results */
sewardj8ea867b2004-10-30 19:03:02 +00001946 IRCallee* cee; /* where to call */
sewardjb8385d82004-11-02 01:34:15 +00001947 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
sewardj8ea867b2004-10-30 19:03:02 +00001948 IRExpr** args; /* arg list, ends in NULL */
sewardj92d168d2004-11-15 14:22:12 +00001949 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
sewardjb3bce0e2004-09-14 23:20:10 +00001950
1951 /* Mem effects; we allow only one R/W/M region to be stated */
sewardj8ea867b2004-10-30 19:03:02 +00001952 IREffect mFx; /* indicates memory effects, if any */
1953 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
1954 Int mSize; /* of access, or zero if mFx==Ifx_None */
sewardjb3bce0e2004-09-14 23:20:10 +00001955
1956 /* Guest state effects; up to N allowed */
sewardjc5fc7aa2004-10-27 23:00:55 +00001957 Bool needsBBP; /* True => also pass guest state ptr to callee */
1958 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
sewardjb3bce0e2004-09-14 23:20:10 +00001959 struct {
sewardjc9069f22012-06-01 16:09:50 +00001960 IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
1961 UShort offset;
1962 UShort size;
1963 UChar nRepeats;
1964 UChar repeatLen;
sewardjb3bce0e2004-09-14 23:20:10 +00001965 } fxState[VEX_N_FXSTATE];
sewardjc9069f22012-06-01 16:09:50 +00001966 /* The access can be repeated, as specified by nRepeats and
1967 repeatLen. To describe only a single access, nRepeats and
1968 repeatLen should be zero. Otherwise, repeatLen must be a
1969 multiple of size and greater than size. */
1970 /* Overall, the parts of the guest state denoted by (offset,
1971 size, nRepeats, repeatLen) is
1972 [offset, +size)
1973 and, if nRepeats > 0,
1974 for (i = 1; i <= nRepeats; i++)
1975 [offset + i * repeatLen, +size)
1976 A convenient way to enumerate all segments is therefore
1977 for (i = 0; i < 1 + nRepeats; i++)
1978 [offset + i * repeatLen, +size)
1979 */
sewardjb3bce0e2004-09-14 23:20:10 +00001980 }
1981 IRDirty;
1982
sewardj57c10c82006-11-15 02:57:05 +00001983/* Pretty-print a dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00001984extern void ppIRDirty ( IRDirty* );
sewardj57c10c82006-11-15 02:57:05 +00001985
1986/* Allocate an uninitialised dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00001987extern IRDirty* emptyIRDirty ( void );
1988
sewardj57c10c82006-11-15 02:57:05 +00001989/* Deep-copy a dirty call */
sewardjdd40fdf2006-12-24 02:20:24 +00001990extern IRDirty* deepCopyIRDirty ( IRDirty* );
sewardj695cff92004-10-13 14:50:14 +00001991
sewardjc5fc7aa2004-10-27 23:00:55 +00001992/* A handy function which takes some of the tedium out of constructing
1993 dirty helper calls. The called function impliedly does not return
sewardjb8385d82004-11-02 01:34:15 +00001994 any value and has a constant-True guard. The call is marked as
1995 accessing neither guest state nor memory (hence the "unsafe"
sewardj57c10c82006-11-15 02:57:05 +00001996 designation) -- you can change this marking later if need be. A
sewardjb8385d82004-11-02 01:34:15 +00001997 suitable IRCallee is constructed from the supplied bits. */
sewardjf9655262004-10-31 20:02:16 +00001998extern
sewardj2d49b432005-02-01 00:37:06 +00001999IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002000 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002001
2002/* Similarly, make a zero-annotation dirty call which returns a value,
2003 and assign that to the given temp. */
sewardjf9655262004-10-31 20:02:16 +00002004extern
2005IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
sewardj2d49b432005-02-01 00:37:06 +00002006 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002007 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002008
sewardjb3bce0e2004-09-14 23:20:10 +00002009
sewardjc4356f02007-11-09 21:15:04 +00002010/* --------------- Memory Bus Events --------------- */
2011
2012typedef
2013 enum {
2014 Imbe_Fence=0x18000,
sewardj6d615ba2011-09-26 16:19:43 +00002015 /* Needed only on ARM. It cancels a reservation made by a
2016 preceding Linked-Load, and needs to be handed through to the
2017 back end, just as LL and SC themselves are. */
2018 Imbe_CancelReservation
sewardjc4356f02007-11-09 21:15:04 +00002019 }
2020 IRMBusEvent;
2021
2022extern void ppIRMBusEvent ( IRMBusEvent );
2023
2024
sewardje9d8a262009-07-01 08:06:34 +00002025/* --------------- Compare and Swap --------------- */
2026
2027/* This denotes an atomic compare and swap operation, either
2028 a single-element one or a double-element one.
2029
2030 In the single-element case:
2031
2032 .addr is the memory address.
2033 .end is the endianness with which memory is accessed
2034
2035 If .addr contains the same value as .expdLo, then .dataLo is
2036 written there, else there is no write. In both cases, the
2037 original value at .addr is copied into .oldLo.
2038
2039 Types: .expdLo, .dataLo and .oldLo must all have the same type.
2040 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2041 guests, I64.
2042
2043 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2044 be NULL.
2045
2046 In the double-element case:
2047
2048 .addr is the memory address.
2049 .end is the endianness with which memory is accessed
2050
2051 The operation is the same:
2052
2053 If .addr contains the same value as .expdHi:.expdLo, then
2054 .dataHi:.dataLo is written there, else there is no write. In
2055 both cases the original value at .addr is copied into
2056 .oldHi:.oldLo.
2057
2058 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2059 all have the same type, which may be any integral type, viz: I8,
2060 I16, I32 or, for 64-bit guests, I64.
2061
2062 The double-element case is complicated by the issue of
2063 endianness. In all cases, the two elements are understood to be
2064 located adjacently in memory, starting at the address .addr.
2065
2066 If .end is Iend_LE, then the .xxxLo component is at the lower
2067 address and the .xxxHi component is at the higher address, and
2068 each component is itself stored little-endianly.
2069
2070 If .end is Iend_BE, then the .xxxHi component is at the lower
2071 address and the .xxxLo component is at the higher address, and
2072 each component is itself stored big-endianly.
2073
2074 This allows representing more cases than most architectures can
2075 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
2076
2077 How to know if the CAS succeeded?
2078
2079 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2080 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2081 stored at .addr, and the original value there was .oldLo (resp
2082 .oldHi:.oldLo).
2083
2084 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2085 then the CAS failed, and the original value at .addr was .oldLo
2086 (resp. .oldHi:.oldLo).
2087
2088 Hence it is easy to know whether or not the CAS succeeded.
2089*/
2090typedef
2091 struct {
2092 IRTemp oldHi; /* old value of *addr is written here */
2093 IRTemp oldLo;
2094 IREndness end; /* endianness of the data in memory */
2095 IRExpr* addr; /* store address */
2096 IRExpr* expdHi; /* expected old value at *addr */
2097 IRExpr* expdLo;
2098 IRExpr* dataHi; /* new value for *addr */
2099 IRExpr* dataLo;
2100 }
2101 IRCAS;
2102
2103extern void ppIRCAS ( IRCAS* cas );
2104
2105extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2106 IREndness end, IRExpr* addr,
2107 IRExpr* expdHi, IRExpr* expdLo,
2108 IRExpr* dataHi, IRExpr* dataLo );
2109
2110extern IRCAS* deepCopyIRCAS ( IRCAS* );
2111
floriand6f38b32012-05-31 15:46:18 +00002112
2113/* ------------------ Circular Array Put ------------------ */
2114typedef
2115 struct {
2116 IRRegArray* descr; /* Part of guest state treated as circular */
2117 IRExpr* ix; /* Variable part of index into array */
2118 Int bias; /* Constant offset part of index into array */
2119 IRExpr* data; /* The value to write */
2120 } IRPutI;
2121
2122extern void ppIRPutI ( IRPutI* puti );
2123
2124extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2125 Int bias, IRExpr* data );
2126
2127extern IRPutI* deepCopyIRPutI ( IRPutI* );
2128
sewardjc9069f22012-06-01 16:09:50 +00002129
sewardjc97096c2004-06-30 09:28:04 +00002130/* ------------------ Statements ------------------ */
sewardjb3bce0e2004-09-14 23:20:10 +00002131
sewardj57c10c82006-11-15 02:57:05 +00002132/* The different kinds of statements. Their meaning is explained
2133 below in the comments for IRStmt.
sewardj5a9ffab2005-05-12 17:55:01 +00002134
sewardj57c10c82006-11-15 02:57:05 +00002135 Those marked META do not represent code, but rather extra
2136 information about the code. These statements can be removed
2137 without affecting the functional behaviour of the code, however
2138 they are required by some IR consumers such as tools that
2139 instrument the code.
sewardj5a9ffab2005-05-12 17:55:01 +00002140*/
sewardjc4356f02007-11-09 21:15:04 +00002141
sewardjac6b7122004-06-27 01:03:57 +00002142typedef
sewardjd2445f62005-03-21 00:15:53 +00002143 enum {
sewardjc4356f02007-11-09 21:15:04 +00002144 Ist_NoOp=0x19000,
sewardj57c10c82006-11-15 02:57:05 +00002145 Ist_IMark, /* META */
2146 Ist_AbiHint, /* META */
2147 Ist_Put,
2148 Ist_PutI,
sewardjdd40fdf2006-12-24 02:20:24 +00002149 Ist_WrTmp,
sewardj57c10c82006-11-15 02:57:05 +00002150 Ist_Store,
sewardje9d8a262009-07-01 08:06:34 +00002151 Ist_CAS,
sewardje768e922009-11-26 17:17:37 +00002152 Ist_LLSC,
sewardj57c10c82006-11-15 02:57:05 +00002153 Ist_Dirty,
sewardjc4356f02007-11-09 21:15:04 +00002154 Ist_MBE, /* META (maybe) */
sewardj57c10c82006-11-15 02:57:05 +00002155 Ist_Exit
sewardjb3bce0e2004-09-14 23:20:10 +00002156 }
sewardjac6b7122004-06-27 01:03:57 +00002157 IRStmtTag;
2158
sewardj57c10c82006-11-15 02:57:05 +00002159/* A statement. Stored as a tagged union. 'tag' indicates what kind
2160 of expression this is. 'Ist' is the union that holds the fields.
2161 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2162 statement, and the fields can be accessed with
2163 'st.Ist.Store.<fieldname>'.
2164
2165 For each kind of statement, we show what it looks like when
sewardje9d8a262009-07-01 08:06:34 +00002166 pretty-printed with ppIRStmt().
sewardj57c10c82006-11-15 02:57:05 +00002167*/
sewardjac6b7122004-06-27 01:03:57 +00002168typedef
2169 struct _IRStmt {
2170 IRStmtTag tag;
2171 union {
sewardj57c10c82006-11-15 02:57:05 +00002172 /* A no-op (usually resulting from IR optimisation). Can be
2173 omitted without any effect.
2174
sewardje9d8a262009-07-01 08:06:34 +00002175 ppIRStmt output: IR-NoOp
sewardj57c10c82006-11-15 02:57:05 +00002176 */
sewardjac6b7122004-06-27 01:03:57 +00002177 struct {
sewardjd2445f62005-03-21 00:15:53 +00002178 } NoOp;
sewardj57c10c82006-11-15 02:57:05 +00002179
2180 /* META: instruction mark. Marks the start of the statements
2181 that represent a single machine instruction (the end of
2182 those statements is marked by the next IMark or the end of
sewardjdd40fdf2006-12-24 02:20:24 +00002183 the IRSB). Contains the address and length of the
sewardj57c10c82006-11-15 02:57:05 +00002184 instruction.
2185
sewardj2f10aa62011-05-27 13:20:56 +00002186 It also contains a delta value. The delta must be
2187 subtracted from a guest program counter value before
2188 attempting to establish, by comparison with the address
2189 and length values, whether or not that program counter
2190 value refers to this instruction. For x86, amd64, ppc32,
2191 ppc64 and arm, the delta value is zero. For Thumb
2192 instructions, the delta value is one. This is because, on
2193 Thumb, guest PC values (guest_R15T) are encoded using the
2194 top 31 bits of the instruction address and a 1 in the lsb;
2195 hence they appear to be (numerically) 1 past the start of
2196 the instruction they refer to. IOW, guest_R15T on ARM
2197 holds a standard ARM interworking address.
2198
2199 ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2200 eg. ------ IMark(0x4000792, 5, 0) ------,
sewardj57c10c82006-11-15 02:57:05 +00002201 */
sewardjd2445f62005-03-21 00:15:53 +00002202 struct {
sewardj57c10c82006-11-15 02:57:05 +00002203 Addr64 addr; /* instruction address */
2204 Int len; /* instruction length */
sewardj2f10aa62011-05-27 13:20:56 +00002205 UChar delta; /* addr = program counter as encoded in guest state
2206 - delta */
sewardjf1689312005-03-16 18:19:10 +00002207 } IMark;
sewardj57c10c82006-11-15 02:57:05 +00002208
2209 /* META: An ABI hint, which says something about this
2210 platform's ABI.
2211
2212 At the moment, the only AbiHint is one which indicates
2213 that a given chunk of address space, [base .. base+len-1],
2214 has become undefined. This is used on amd64-linux and
2215 some ppc variants to pass stack-redzoning hints to whoever
sewardj478646f2008-05-01 20:13:04 +00002216 wants to see them. It also indicates the address of the
2217 next (dynamic) instruction that will be executed. This is
2218 to help Memcheck to origin tracking.
sewardj57c10c82006-11-15 02:57:05 +00002219
sewardje9d8a262009-07-01 08:06:34 +00002220 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
sewardj478646f2008-05-01 20:13:04 +00002221 eg. ====== AbiHint(t1, 16, t2) ======
sewardj57c10c82006-11-15 02:57:05 +00002222 */
sewardjf1689312005-03-16 18:19:10 +00002223 struct {
sewardj57c10c82006-11-15 02:57:05 +00002224 IRExpr* base; /* Start of undefined chunk */
2225 Int len; /* Length of undefined chunk */
sewardj478646f2008-05-01 20:13:04 +00002226 IRExpr* nia; /* Address of next (guest) insn */
sewardj5a9ffab2005-05-12 17:55:01 +00002227 } AbiHint;
sewardj57c10c82006-11-15 02:57:05 +00002228
2229 /* Write a guest register, at a fixed offset in the guest state.
sewardje9d8a262009-07-01 08:06:34 +00002230 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
sewardj57c10c82006-11-15 02:57:05 +00002231 */
sewardj5a9ffab2005-05-12 17:55:01 +00002232 struct {
sewardj57c10c82006-11-15 02:57:05 +00002233 Int offset; /* Offset into the guest state */
2234 IRExpr* data; /* The value to write */
sewardjac6b7122004-06-27 01:03:57 +00002235 } Put;
sewardj57c10c82006-11-15 02:57:05 +00002236
2237 /* Write a guest register, at a non-fixed offset in the guest
2238 state. See the comment for GetI expressions for more
2239 information.
2240
sewardje9d8a262009-07-01 08:06:34 +00002241 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
sewardj57c10c82006-11-15 02:57:05 +00002242 eg. PUTI(64:8xF64)[t5,0] = t1
2243 */
sewardjac6b7122004-06-27 01:03:57 +00002244 struct {
floriand6f38b32012-05-31 15:46:18 +00002245 IRPutI* details;
sewardjd1725d12004-08-12 20:46:53 +00002246 } PutI;
sewardj57c10c82006-11-15 02:57:05 +00002247
sewardjdd40fdf2006-12-24 02:20:24 +00002248 /* Assign a value to a temporary. Note that SSA rules require
2249 each tmp is only assigned to once. IR sanity checking will
2250 reject any block containing a temporary which is not assigned
2251 to exactly once.
sewardj57c10c82006-11-15 02:57:05 +00002252
sewardje9d8a262009-07-01 08:06:34 +00002253 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
sewardj57c10c82006-11-15 02:57:05 +00002254 */
sewardjd1725d12004-08-12 20:46:53 +00002255 struct {
sewardj57c10c82006-11-15 02:57:05 +00002256 IRTemp tmp; /* Temporary (LHS of assignment) */
2257 IRExpr* data; /* Expression (RHS of assignment) */
sewardjdd40fdf2006-12-24 02:20:24 +00002258 } WrTmp;
sewardj57c10c82006-11-15 02:57:05 +00002259
sewardje768e922009-11-26 17:17:37 +00002260 /* Write a value to memory. This is a normal store, not a
2261 Store-Conditional. To represent a Store-Conditional,
2262 instead use IRStmt.LLSC.
sewardje9d8a262009-07-01 08:06:34 +00002263 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
sewardj57c10c82006-11-15 02:57:05 +00002264 */
sewardjac6b7122004-06-27 01:03:57 +00002265 struct {
sewardj57c10c82006-11-15 02:57:05 +00002266 IREndness end; /* Endianness of the store */
2267 IRExpr* addr; /* store address */
2268 IRExpr* data; /* value to write */
sewardjaf1ceca2005-06-30 23:31:27 +00002269 } Store;
sewardj57c10c82006-11-15 02:57:05 +00002270
sewardje9d8a262009-07-01 08:06:34 +00002271 /* Do an atomic compare-and-swap operation. Semantics are
2272 described above on a comment at the definition of IRCAS.
2273
2274 ppIRStmt output:
2275 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2276 eg
2277 t1 = CASle(t2 :: t3->Add32(t3,1))
2278 which denotes a 32-bit atomic increment
2279 of a value at address t2
2280
2281 A double-element CAS may also be denoted, in which case <tmp>,
2282 <expected> and <new> are all pairs of items, separated by
2283 commas.
2284 */
2285 struct {
2286 IRCAS* details;
2287 } CAS;
2288
sewardje768e922009-11-26 17:17:37 +00002289 /* Either Load-Linked or Store-Conditional, depending on
2290 STOREDATA.
2291
2292 If STOREDATA is NULL then this is a Load-Linked, meaning
2293 that data is loaded from memory as normal, but a
2294 'reservation' for the address is also lodged in the
2295 hardware.
2296
2297 result = Load-Linked(addr, end)
2298
2299 The data transfer type is the type of RESULT (I32, I64,
2300 etc). ppIRStmt output:
2301
2302 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2303
2304 If STOREDATA is not NULL then this is a Store-Conditional,
2305 hence:
2306
2307 result = Store-Conditional(addr, storedata, end)
2308
2309 The data transfer type is the type of STOREDATA and RESULT
2310 has type Ity_I1. The store may fail or succeed depending
2311 on the state of a previously lodged reservation on this
2312 address. RESULT is written 1 if the store succeeds and 0
2313 if it fails. eg ppIRStmt output:
2314
2315 result = ( ST<end>-Cond(<addr>) = <storedata> )
2316 eg t3 = ( STbe-Cond(t1, t2) )
2317
2318 In all cases, the address must be naturally aligned for
2319 the transfer type -- any misaligned addresses should be
2320 caught by a dominating IR check and side exit. This
2321 alignment restriction exists because on at least some
2322 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2323 misaligned addresses, and we have to actually generate
2324 stwcx. on the host, and we don't want it trapping on the
2325 host.
2326
2327 Summary of rules for transfer type:
2328 STOREDATA == NULL (LL):
2329 transfer type = type of RESULT
2330 STOREDATA != NULL (SC):
2331 transfer type = type of STOREDATA, and RESULT :: Ity_I1
2332 */
2333 struct {
2334 IREndness end;
2335 IRTemp result;
2336 IRExpr* addr;
2337 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
2338 } LLSC;
2339
sewardj57c10c82006-11-15 02:57:05 +00002340 /* Call (possibly conditionally) a C function that has side
2341 effects (ie. is "dirty"). See the comments above the
2342 IRDirty type declaration for more information.
2343
sewardje9d8a262009-07-01 08:06:34 +00002344 ppIRStmt output:
sewardj57c10c82006-11-15 02:57:05 +00002345 t<tmp> = DIRTY <guard> <effects>
2346 ::: <callee>(<args>)
2347 eg.
2348 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
2349 ::: foo{0x380035f4}(t2)
2350 */
sewardj64e1d652004-07-12 14:00:46 +00002351 struct {
sewardjb3bce0e2004-09-14 23:20:10 +00002352 IRDirty* details;
2353 } Dirty;
sewardj57c10c82006-11-15 02:57:05 +00002354
sewardjc4356f02007-11-09 21:15:04 +00002355 /* A memory bus event - a fence, or acquisition/release of the
2356 hardware bus lock. IR optimisation treats all these as fences
2357 across which no memory references may be moved.
sewardje9d8a262009-07-01 08:06:34 +00002358 ppIRStmt output: MBusEvent-Fence,
sewardjc4356f02007-11-09 21:15:04 +00002359 MBusEvent-BusLock, MBusEvent-BusUnlock.
sewardj57c10c82006-11-15 02:57:05 +00002360 */
sewardjb3bce0e2004-09-14 23:20:10 +00002361 struct {
sewardjc4356f02007-11-09 21:15:04 +00002362 IRMBusEvent event;
2363 } MBE;
sewardj57c10c82006-11-15 02:57:05 +00002364
sewardjdd40fdf2006-12-24 02:20:24 +00002365 /* Conditional exit from the middle of an IRSB.
sewardje9d8a262009-07-01 08:06:34 +00002366 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
sewardj57c10c82006-11-15 02:57:05 +00002367 eg. if (t69) goto {Boring} 0x4000AAA:I32
sewardjc6f970f2012-04-02 21:54:49 +00002368 If <guard> is true, the guest state is also updated by
2369 PUT-ing <dst> at <offsIP>. This is done because a
2370 taken exit must update the guest program counter.
sewardj57c10c82006-11-15 02:57:05 +00002371 */
sewardj3e838932005-01-07 12:09:15 +00002372 struct {
sewardj57c10c82006-11-15 02:57:05 +00002373 IRExpr* guard; /* Conditional expression */
sewardj57c10c82006-11-15 02:57:05 +00002374 IRConst* dst; /* Jump target (constant only) */
floriand6f38b32012-05-31 15:46:18 +00002375 IRJumpKind jk; /* Jump kind */
sewardjc6f970f2012-04-02 21:54:49 +00002376 Int offsIP; /* Guest state offset for IP */
sewardj64e1d652004-07-12 14:00:46 +00002377 } Exit;
sewardjac6b7122004-06-27 01:03:57 +00002378 } Ist;
sewardjac6b7122004-06-27 01:03:57 +00002379 }
2380 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +00002381
sewardj57c10c82006-11-15 02:57:05 +00002382/* Statement constructors. */
sewardj5a9ffab2005-05-12 17:55:01 +00002383extern IRStmt* IRStmt_NoOp ( void );
sewardj2f10aa62011-05-27 13:20:56 +00002384extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len, UChar delta );
sewardj478646f2008-05-01 20:13:04 +00002385extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
sewardj5a9ffab2005-05-12 17:55:01 +00002386extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
floriand6f38b32012-05-31 15:46:18 +00002387extern IRStmt* IRStmt_PutI ( IRPutI* details );
sewardjdd40fdf2006-12-24 02:20:24 +00002388extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
sewardje768e922009-11-26 17:17:37 +00002389extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
sewardje9d8a262009-07-01 08:06:34 +00002390extern IRStmt* IRStmt_CAS ( IRCAS* details );
sewardje768e922009-11-26 17:17:37 +00002391extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
2392 IRExpr* addr, IRExpr* storedata );
sewardj5a9ffab2005-05-12 17:55:01 +00002393extern IRStmt* IRStmt_Dirty ( IRDirty* details );
sewardjc4356f02007-11-09 21:15:04 +00002394extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
sewardjc6f970f2012-04-02 21:54:49 +00002395extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2396 Int offsIP );
sewardjec6ad592004-06-20 12:26:53 +00002397
sewardj57c10c82006-11-15 02:57:05 +00002398/* Deep-copy an IRStmt. */
sewardjdd40fdf2006-12-24 02:20:24 +00002399extern IRStmt* deepCopyIRStmt ( IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002400
sewardj57c10c82006-11-15 02:57:05 +00002401/* Pretty-print an IRStmt. */
sewardj35421a32004-07-05 13:12:34 +00002402extern void ppIRStmt ( IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +00002403
2404
sewardje539a402004-07-14 18:24:17 +00002405/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +00002406
sewardj57c10c82006-11-15 02:57:05 +00002407/* Type environments: a bunch of statements, expressions, etc, are
2408 incomplete without an environment indicating the type of each
2409 IRTemp. So this provides one. IR temporaries are really just
2410 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2411 them.
sewardjc97096c2004-06-30 09:28:04 +00002412*/
2413typedef
sewardjc97096c2004-06-30 09:28:04 +00002414 struct {
sewardje539a402004-07-14 18:24:17 +00002415 IRType* types;
2416 Int types_size;
2417 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +00002418 }
2419 IRTypeEnv;
2420
sewardj57c10c82006-11-15 02:57:05 +00002421/* Obtain a new IRTemp */
2422extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2423
2424/* Deep-copy a type environment */
sewardjdd40fdf2006-12-24 02:20:24 +00002425extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
sewardj695cff92004-10-13 14:50:14 +00002426
sewardj57c10c82006-11-15 02:57:05 +00002427/* Pretty-print a type environment */
sewardj35421a32004-07-05 13:12:34 +00002428extern void ppIRTypeEnv ( IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +00002429
sewardjec6ad592004-06-20 12:26:53 +00002430
sewardjdd40fdf2006-12-24 02:20:24 +00002431/* Code blocks, which in proper compiler terminology are superblocks
2432 (single entry, multiple exit code sequences) contain:
2433
sewardj57c10c82006-11-15 02:57:05 +00002434 - A table giving a type for each temp (the "type environment")
sewardjd7cb8532004-08-17 23:59:23 +00002435 - An expandable array of statements
sewardje539a402004-07-14 18:24:17 +00002436 - An expression of type 32 or 64 bits, depending on the
sewardjdd40fdf2006-12-24 02:20:24 +00002437 guest's word size, indicating the next destination if the block
2438 executes all the way to the end, without a side exit
sewardjd7cb8532004-08-17 23:59:23 +00002439 - An indication of any special actions (JumpKind) needed
2440 for this final jump.
sewardjc6f970f2012-04-02 21:54:49 +00002441 - Offset of the IP field in the guest state. This will be
2442 updated before the final jump is done.
sewardj57c10c82006-11-15 02:57:05 +00002443
sewardjdd40fdf2006-12-24 02:20:24 +00002444 "IRSB" stands for "IR Super Block".
sewardjec6ad592004-06-20 12:26:53 +00002445*/
sewardjac6b7122004-06-27 01:03:57 +00002446typedef
sewardj57c10c82006-11-15 02:57:05 +00002447 struct {
sewardjc97096c2004-06-30 09:28:04 +00002448 IRTypeEnv* tyenv;
sewardjd7cb8532004-08-17 23:59:23 +00002449 IRStmt** stmts;
2450 Int stmts_size;
2451 Int stmts_used;
sewardje539a402004-07-14 18:24:17 +00002452 IRExpr* next;
2453 IRJumpKind jumpkind;
sewardjc6f970f2012-04-02 21:54:49 +00002454 Int offsIP;
sewardjac6b7122004-06-27 01:03:57 +00002455 }
sewardjdd40fdf2006-12-24 02:20:24 +00002456 IRSB;
sewardjec6ad592004-06-20 12:26:53 +00002457
sewardjdd40fdf2006-12-24 02:20:24 +00002458/* Allocate a new, uninitialised IRSB */
2459extern IRSB* emptyIRSB ( void );
sewardj695cff92004-10-13 14:50:14 +00002460
sewardjdd40fdf2006-12-24 02:20:24 +00002461/* Deep-copy an IRSB */
2462extern IRSB* deepCopyIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002463
sewardjdd40fdf2006-12-24 02:20:24 +00002464/* Deep-copy an IRSB, except for the statements list, which set to be
sewardj6f2f2832006-11-24 23:32:55 +00002465 a new, empty, list of statements. */
sewardjdd40fdf2006-12-24 02:20:24 +00002466extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
sewardj57c10c82006-11-15 02:57:05 +00002467
sewardjdd40fdf2006-12-24 02:20:24 +00002468/* Pretty-print an IRSB */
2469extern void ppIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002470
sewardjdd40fdf2006-12-24 02:20:24 +00002471/* Append an IRStmt to an IRSB */
2472extern void addStmtToIRSB ( IRSB*, IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002473
2474
sewardjec6ad592004-06-20 12:26:53 +00002475/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +00002476/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +00002477/*---------------------------------------------------------------*/
2478
sewardjc97096c2004-06-30 09:28:04 +00002479/* For messing with IR type environments */
sewardjd7cb8532004-08-17 23:59:23 +00002480extern IRTypeEnv* emptyIRTypeEnv ( void );
sewardjec6ad592004-06-20 12:26:53 +00002481
sewardjc97096c2004-06-30 09:28:04 +00002482/* What is the type of this expression? */
sewardj6efd4a12004-07-15 03:54:23 +00002483extern IRType typeOfIRConst ( IRConst* );
sewardj17442fe2004-09-20 14:54:28 +00002484extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp );
sewardj6efd4a12004-07-15 03:54:23 +00002485extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00002486
sewardj35439212004-07-14 22:36:10 +00002487/* Sanity check a BB of IR */
sewardjdd40fdf2006-12-24 02:20:24 +00002488extern void sanityCheckIRSB ( IRSB* bb,
sewardjb9230752004-12-29 19:25:06 +00002489 HChar* caller,
2490 Bool require_flatness,
2491 IRType guest_word_size );
sewardjcf787902004-11-03 09:08:33 +00002492extern Bool isFlatIRStmt ( IRStmt* );
sewardjec6ad592004-06-20 12:26:53 +00002493
sewardj6d2638e2004-07-15 09:38:27 +00002494/* Is this any value actually in the enumeration 'IRType' ? */
sewardj496a58d2005-03-20 18:44:44 +00002495extern Bool isPlausibleIRType ( IRType ty );
sewardj6d2638e2004-07-15 09:38:27 +00002496
sewardj887a11a2004-07-05 17:26:47 +00002497#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +00002498
2499
2500/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +00002501/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +00002502/*---------------------------------------------------------------*/