blob: f0af9f06de8c02791ae821ef31fc2a60fe94a5c9 [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
sewardj44ce46d2012-07-11 13:19:10 +0000749 /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
750 Iop_QAdd32S,
751 Iop_QSub32S,
752
sewardje2ea1762010-09-22 00:56:37 +0000753 /* 16x2 add/sub, also signed/unsigned saturating variants */
754 Iop_Add16x2, Iop_Sub16x2,
755 Iop_QAdd16Sx2, Iop_QAdd16Ux2,
756 Iop_QSub16Sx2, Iop_QSub16Ux2,
757
758 /* 16x2 signed/unsigned halving add/sub. For each lane, these
759 compute bits 16:1 of (eg) sx(argL) + sx(argR),
760 or zx(argL) - zx(argR) etc. */
761 Iop_HAdd16Ux2, Iop_HAdd16Sx2,
762 Iop_HSub16Ux2, Iop_HSub16Sx2,
763
764 /* 8x4 add/sub, also signed/unsigned saturating variants */
765 Iop_Add8x4, Iop_Sub8x4,
766 Iop_QAdd8Sx4, Iop_QAdd8Ux4,
767 Iop_QSub8Sx4, Iop_QSub8Ux4,
768
769 /* 8x4 signed/unsigned halving add/sub. For each lane, these
770 compute bits 8:1 of (eg) sx(argL) + sx(argR),
771 or zx(argL) - zx(argR) etc. */
772 Iop_HAdd8Ux4, Iop_HAdd8Sx4,
773 Iop_HSub8Ux4, Iop_HSub8Sx4,
774
sewardj310d6b22010-10-18 16:29:40 +0000775 /* 8x4 sum of absolute unsigned differences. */
776 Iop_Sad8Ux4,
777
sewardje2ea1762010-09-22 00:56:37 +0000778 /* MISC (vector integer cmp != 0) */
779 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
780
sewardj2fdd4162010-08-22 12:59:02 +0000781 /* ------------------ 64-bit SIMD FP ------------------------ */
782
783 /* Convertion to/from int */
784 Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */
785 Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */
786 /* Fixed32 format is floating-point number with fixed number of fraction
787 bits. The number of fraction bits is passed as a second argument of
788 type I8. */
789 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
790 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
791
792 /* Binary operations */
793 Iop_Max32Fx2, Iop_Min32Fx2,
794 /* Pairwise Min and Max. See integer pairwise operations for more
795 details. */
796 Iop_PwMax32Fx2, Iop_PwMin32Fx2,
797 /* Note: For the following compares, the arm front-end assumes a
798 nan in a lane of either argument returns zero for that lane. */
799 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
800
801 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
802 element in the operand vector, and places the results in the destination
803 vector. */
804 Iop_Recip32Fx2,
805
806 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
807 Note, that if one of the arguments is zero and another one is infinity
808 of arbitrary sign the result of the operation is 2.0. */
809 Iop_Recps32Fx2,
810
811 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
812 square root of each element in the operand vector. */
813 Iop_Rsqrte32Fx2,
814
815 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
816 Note, that of one of the arguments is zero and another one is infiinty
817 of arbitrary sign the result of the operation is 1.5. */
818 Iop_Rsqrts32Fx2,
819
820 /* Unary */
821 Iop_Neg32Fx2, Iop_Abs32Fx2,
822
sewardj38a3f862005-01-13 15:06:51 +0000823 /* ------------------ 64-bit SIMD Integer. ------------------ */
824
825 /* MISC (vector integer cmp != 0) */
sewardj18069182005-01-13 19:16:04 +0000826 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
sewardj38a3f862005-01-13 15:06:51 +0000827
828 /* ADDITION (normal / unsigned sat / signed sat) */
829 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000830 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
831 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
832
833 /* PAIRWISE operations */
834 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
835 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
836 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2,
837 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
838 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
839 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
840 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
841 /* Longening variant is unary. The resulting vector contains two times
842 less elements than operand, but they are two times wider.
843 Example:
844 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
845 where a+b and c+d are unsigned 32-bit values. */
846 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
847 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000848
849 /* SUBTRACTION (normal / unsigned sat / signed sat) */
850 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000851 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
852 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
sewardj38a3f862005-01-13 15:06:51 +0000853
sewardj2fdd4162010-08-22 12:59:02 +0000854 /* ABSOLUTE VALUE */
855 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
856
857 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
858 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
859 Iop_Mul32Fx2,
sewardj38a3f862005-01-13 15:06:51 +0000860 Iop_MulHi16Ux4,
861 Iop_MulHi16Sx4,
sewardj2fdd4162010-08-22 12:59:02 +0000862 /* Plynomial multiplication treats it's arguments as coefficients of
863 polynoms over {0, 1}. */
864 Iop_PolynomialMul8x8,
865
866 /* Vector Saturating Doubling Multiply Returning High Half and
867 Vector Saturating Rounding Doubling Multiply Returning High Half */
868 /* These IROp's multiply corresponding elements in two vectors, double
869 the results, and place the most significant half of the final results
870 in the destination vector. The results are truncated or rounded. If
871 any of the results overflow, they are saturated. */
872 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
873 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000874
sewardj5ce5fd62005-04-19 23:06:11 +0000875 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
sewardj38a3f862005-01-13 15:06:51 +0000876 Iop_Avg8Ux8,
877 Iop_Avg16Ux4,
878
879 /* MIN/MAX */
sewardj2fdd4162010-08-22 12:59:02 +0000880 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
881 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
882 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
883 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000884
885 /* COMPARISON */
886 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000887 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000888 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
889
sewardj2fdd4162010-08-22 12:59:02 +0000890 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
891 bit) */
892 Iop_Cnt8x8,
893 Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2,
894 Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2,
895
896 /* VECTOR x VECTOR SHIFT / ROTATE */
897 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
898 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
899 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
900 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
901
sewardj38a3f862005-01-13 15:06:51 +0000902 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
sewardjd166e282008-02-06 11:42:45 +0000903 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000904 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
sewardjd71ba832006-12-27 01:15:29 +0000905 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
sewardj38a3f862005-01-13 15:06:51 +0000906
sewardj2fdd4162010-08-22 12:59:02 +0000907 /* VECTOR x VECTOR SATURATING SHIFT */
908 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
909 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
910 /* VECTOR x INTEGER SATURATING SHIFT */
911 Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1,
912 Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1,
913 Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1,
914
sewardj5f438dd2011-06-16 11:36:23 +0000915 /* NARROWING (binary)
916 -- narrow 2xI64 into 1xI64, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +0000917 /* For saturated narrowing, I believe there are 4 variants of
918 the basic arithmetic operation, depending on the signedness
919 of argument and result. Here are examples that exemplify
920 what I mean:
921
922 QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255;
923 return x[7:0];
924
925 QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128;
926 if (x >s 127) x = 127;
927 return x[7:0];
928
929 QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127;
930 return x[7:0];
931
932 QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0;
933 if (x >s 255) x = 255;
934 return x[7:0];
935 */
sewardj5f438dd2011-06-16 11:36:23 +0000936 Iop_QNarrowBin16Sto8Ux8,
937 Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
sewardjad2c9ea2011-10-22 09:32:16 +0000938 Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4,
sewardj38a3f862005-01-13 15:06:51 +0000939
sewardj2fdd4162010-08-22 12:59:02 +0000940 /* INTERLEAVING */
941 /* Interleave lanes from low or high halves of
sewardj38a3f862005-01-13 15:06:51 +0000942 operands. Most-significant result lane is from the left
943 arg. */
944 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
945 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000946 /* Interleave odd/even lanes of operands. Most-significant result lane
947 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are
948 identical to Interleave{HI,LO}32x2 and so are omitted.*/
949 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
950 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
951
sewardj38a3f862005-01-13 15:06:51 +0000952
sewardjd166e282008-02-06 11:42:45 +0000953 /* CONCATENATION -- build a new value by concatenating either
954 the even or odd lanes of both operands. Note that
955 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
956 and so are omitted. */
sewardj2fdd4162010-08-22 12:59:02 +0000957 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
958 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
959
960 /* GET / SET elements of VECTOR
961 GET is binop (I64, I8) -> I<elem_size>
962 SET is triop (I64, I8, I<elem_size>) -> I64 */
963 /* Note: the arm back-end handles only constant second argument */
964 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
965 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
966
967 /* DUPLICATING -- copy value to all lanes */
968 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2,
969
970 /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes
971 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
972 result.
973 It is a triop: (I64, I64, I8) -> I64 */
974 /* Note: the arm back-end handles only constant third argumnet. */
975 Iop_Extract64,
976
977 /* REVERSE the order of elements in each Half-words, Words,
978 Double-words */
979 /* Examples:
980 Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
981 Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
982 Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
983 Iop_Reverse16_8x8,
984 Iop_Reverse32_8x8, Iop_Reverse32_16x4,
985 Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2,
sewardjd166e282008-02-06 11:42:45 +0000986
987 /* PERMUTING -- copy src bytes to dst,
988 as indexed by control vector bytes:
989 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
990 argR[i] values may only be in the range 0 .. 7, else behaviour
991 is undefined. */
992 Iop_Perm8x8,
993
sewardj2fdd4162010-08-22 12:59:02 +0000994 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
995 See floating-point equiwalents for details. */
996 Iop_Recip32x2, Iop_Rsqrte32x2,
997
sewardjc6bbd472012-04-02 10:20:48 +0000998 /* ------------------ Decimal Floating Point ------------------ */
999
1000 /* ARITHMETIC INSTRUCTIONS 64-bit
1001 ----------------------------------
1002 IRRoundingModeDFP(I32) X D64 X D64 -> D64
sewardjc6bbd472012-04-02 10:20:48 +00001003 */
1004 Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1005
1006 /* ARITHMETIC INSTRUCTIONS 128-bit
1007 ----------------------------------
1008 IRRoundingModeDFP(I32) X D128 X D128 -> D128
sewardjc6bbd472012-04-02 10:20:48 +00001009 */
1010 Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1011
sewardj26217b02012-04-12 17:19:48 +00001012 /* SHIFT SIGNIFICAND INSTRUCTIONS
1013 * The DFP significand is shifted by the number of digits specified
1014 * by the U8 operand. Digits shifted out of the leftmost digit are
1015 * lost. Zeros are supplied to the vacated positions on the right.
1016 * The sign of the result is the same as the sign of the original
1017 * operand.
sewardjcdc376d2012-04-23 11:21:12 +00001018 *
1019 * D64 x U8 -> D64 left shift and right shift respectively */
sewardj26217b02012-04-12 17:19:48 +00001020 Iop_ShlD64, Iop_ShrD64,
1021
1022 /* D128 x U8 -> D128 left shift and right shift respectively */
1023 Iop_ShlD128, Iop_ShrD128,
1024
1025
1026 /* FORMAT CONVERSION INSTRUCTIONS
1027 * D32 -> D64
1028 */
1029 Iop_D32toD64,
1030
1031 /* D64 -> D128 */
1032 Iop_D64toD128,
1033
1034 /* I64S -> D128 */
1035 Iop_I64StoD128,
1036
1037 /* IRRoundingModeDFP(I32) x D64 -> D32 */
1038 Iop_D64toD32,
1039
1040 /* IRRoundingModeDFP(I32) x D128 -> D64 */
1041 Iop_D128toD64,
1042
1043 /* IRRoundingModeDFP(I32) x I64 -> D64 */
1044 Iop_I64StoD64,
1045
1046 /* IRRoundingModeDFP(I32) x D64 -> I64 */
1047 Iop_D64toI64S,
1048
1049 /* IRRoundingModeDFP(I32) x D128 -> I64 */
1050 Iop_D128toI64S,
1051
sewardjcdc376d2012-04-23 11:21:12 +00001052 /* ROUNDING INSTRUCTIONS
1053 * IRRoundingMode(I32) x D64 -> D64
1054 * The D64 operand, if a finite number, is rounded to an integer value.
1055 */
1056 Iop_RoundD64toInt,
1057
1058 /* IRRoundingMode(I32) x D128 -> D128 */
1059 Iop_RoundD128toInt,
1060
1061 /* COMPARE INSTRUCTIONS
1062 * D64 x D64 -> IRCmpD64Result(I32) */
1063 Iop_CmpD64,
1064
1065 /* D128 x D128 -> IRCmpD64Result(I32) */
1066 Iop_CmpD128,
1067
1068 /* QUANTIZE AND ROUND INSTRUCTIONS
1069 * The source operand is converted and rounded to the form with the
1070 * immediate exponent specified by the rounding and exponent parameter.
1071 *
1072 * The second operand is converted and rounded to the form
1073 * of the first operand's exponent and the rounded based on the specified
1074 * rounding mode parameter.
1075 *
1076 * IRRoundingModeDFP(I32) x D64 x D64-> D64 */
1077 Iop_QuantizeD64,
1078
1079 /* IRRoundingModeDFP(I32) x D128 x D128 -> D128 */
1080 Iop_QuantizeD128,
1081
1082 /* IRRoundingModeDFP(I32) x I8 x D64 -> D64
1083 * The Decimal Floating point operand is rounded to the requested
1084 * significance given by the I8 operand as specified by the rounding
1085 * mode.
1086 */
1087 Iop_SignificanceRoundD64,
1088
1089 /* IRRoundingModeDFP(I32) x I8 x D128 -> D128 */
1090 Iop_SignificanceRoundD128,
1091
1092 /* EXTRACT AND INSERT INSTRUCTIONS
1093 * D64 -> I64
1094 * The exponent of the D32 or D64 operand is extracted. The
1095 * extracted exponent is converted to a 64-bit signed binary integer.
1096 */
1097 Iop_ExtractExpD64,
1098
1099 /* D128 -> I64 */
1100 Iop_ExtractExpD128,
1101
1102 /* I64 x I64 -> D64
1103 * The exponent is specified by the first I64 operand the signed
1104 * significand is given by the second I64 value. The result is a D64
1105 * value consisting of the specified significand and exponent whose
1106 * sign is that of the specified significand.
1107 */
1108 Iop_InsertExpD64,
1109
1110 /* I64 x I128 -> D128 */
1111 Iop_InsertExpD128,
1112
sewardjc6bbd472012-04-02 10:20:48 +00001113 /* Support for 128-bit DFP type */
1114 Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1115
sewardj4c96e612012-06-02 23:47:02 +00001116 /* I64 -> I64
1117 * Convert 50-bit densely packed BCD string to 60 bit BCD string
1118 */
1119 Iop_DPBtoBCD,
1120
1121 /* I64 -> I64
1122 * Convert 60 bit BCD string to 50-bit densely packed BCD string
1123 */
1124 Iop_BCDtoDPB,
1125
sewardjcdc376d2012-04-23 11:21:12 +00001126 /* Conversion I64 -> D64 */
1127 Iop_ReinterpI64asD64,
1128
sewardj5eff1c52012-04-29 20:19:17 +00001129 /* Conversion D64 -> I64 */
1130 Iop_ReinterpD64asI64,
1131
sewardj164f9272004-12-09 00:39:32 +00001132 /* ------------------ 128-bit SIMD FP. ------------------ */
sewardjc9a43662004-11-30 18:51:59 +00001133
1134 /* --- 32x4 vector FP --- */
1135
1136 /* binary */
1137 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
1138 Iop_Max32Fx4, Iop_Min32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001139 Iop_Add32Fx2, Iop_Sub32Fx2,
1140 /* Note: For the following compares, the ppc and arm front-ends assume a
cerionf294eb32005-11-16 17:21:10 +00001141 nan in a lane of either argument returns zero for that lane. */
sewardj2fdd4162010-08-22 12:59:02 +00001142 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
cerion206c3642005-11-14 00:35:59 +00001143 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
sewardjc9a43662004-11-30 18:51:59 +00001144
sewardj2fdd4162010-08-22 12:59:02 +00001145 /* Vector Absolute */
1146 Iop_Abs32Fx4,
1147
1148 /* Pairwise Max and Min. See integer pairwise operations for details. */
1149 Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1150
sewardjc9a43662004-11-30 18:51:59 +00001151 /* unary */
sewardj2fdd4162010-08-22 12:59:02 +00001152 Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
1153 Iop_Neg32Fx4,
1154
1155 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1156 element in the operand vector, and places the results in the destination
1157 vector. */
1158 Iop_Recip32Fx4,
1159
1160 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1161 Note, that if one of the arguments is zero and another one is infinity
1162 of arbitrary sign the result of the operation is 2.0. */
1163 Iop_Recps32Fx4,
1164
1165 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1166 square root of each element in the operand vector. */
1167 Iop_Rsqrte32Fx4,
1168
1169 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1170 Note, that of one of the arguments is zero and another one is infiinty
1171 of arbitrary sign the result of the operation is 1.5. */
1172 Iop_Rsqrts32Fx4,
1173
sewardjc9a43662004-11-30 18:51:59 +00001174
cerionf294eb32005-11-16 17:21:10 +00001175 /* --- Int to/from FP conversion --- */
1176 /* Unlike the standard fp conversions, these irops take no
1177 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1178 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
sewardj2fdd4162010-08-22 12:59:02 +00001179 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */
1180 Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */
1181 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (with saturation) */
cerionf294eb32005-11-16 17:21:10 +00001182 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
1183 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
sewardj2fdd4162010-08-22 12:59:02 +00001184 /* Fixed32 format is floating-point number with fixed number of fraction
1185 bits. The number of fraction bits is passed as a second argument of
1186 type I8. */
1187 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1188 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1189
1190 /* --- Single to/from half conversion --- */
sewardj5f438dd2011-06-16 11:36:23 +00001191 /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
sewardj2fdd4162010-08-22 12:59:02 +00001192 Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */
cerionf294eb32005-11-16 17:21:10 +00001193
sewardjc9a43662004-11-30 18:51:59 +00001194 /* --- 32x4 lowest-lane-only scalar FP --- */
1195
1196 /* In binary cases, upper 3/4 is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001197 unary cases, upper 3/4 is copied from the operand. */
sewardjc9a43662004-11-30 18:51:59 +00001198
1199 /* binary */
1200 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1201 Iop_Max32F0x4, Iop_Min32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001202 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
sewardjc9a43662004-11-30 18:51:59 +00001203
1204 /* unary */
1205 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001206
1207 /* --- 64x2 vector FP --- */
1208
1209 /* binary */
1210 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
1211 Iop_Max64Fx2, Iop_Min64Fx2,
1212 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1213
1214 /* unary */
1215 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
1216
1217 /* --- 64x2 lowest-lane-only scalar FP --- */
1218
1219 /* In binary cases, upper half is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001220 unary cases, upper half is copied from the operand. */
sewardj636ad762004-12-07 11:16:04 +00001221
1222 /* binary */
1223 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1224 Iop_Max64F0x2, Iop_Min64F0x2,
1225 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1226
1227 /* unary */
1228 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
sewardjc9a43662004-11-30 18:51:59 +00001229
1230 /* --- pack / unpack --- */
1231
sewardjf0c1c582005-02-07 23:47:38 +00001232 /* 64 <-> 128 bit vector */
1233 Iop_V128to64, // :: V128 -> I64, low half
1234 Iop_V128HIto64, // :: V128 -> I64, high half
1235 Iop_64HLtoV128, // :: (I64,I64) -> V128
sewardjc9a43662004-11-30 18:51:59 +00001236
sewardjf0c1c582005-02-07 23:47:38 +00001237 Iop_64UtoV128,
1238 Iop_SetV128lo64,
sewardj164f9272004-12-09 00:39:32 +00001239
sewardjf0c1c582005-02-07 23:47:38 +00001240 /* 32 <-> 128 bit vector */
1241 Iop_32UtoV128,
1242 Iop_V128to32, // :: V128 -> I32, lowest lane
1243 Iop_SetV128lo32, // :: (V128,I32) -> V128
sewardj70f676d2004-12-10 14:59:57 +00001244
sewardj164f9272004-12-09 00:39:32 +00001245 /* ------------------ 128-bit SIMD Integer. ------------------ */
1246
1247 /* BITWISE OPS */
sewardjf0c1c582005-02-07 23:47:38 +00001248 Iop_NotV128,
1249 Iop_AndV128, Iop_OrV128, Iop_XorV128,
sewardj164f9272004-12-09 00:39:32 +00001250
cerionf887b3e2005-09-13 16:34:28 +00001251 /* VECTOR SHIFT (shift amt :: Ity_I8) */
1252 Iop_ShlV128, Iop_ShrV128,
1253
sewardj2e383862004-12-12 16:46:47 +00001254 /* MISC (vector integer cmp != 0) */
1255 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
sewardj70f676d2004-12-10 14:59:57 +00001256
sewardj164f9272004-12-09 00:39:32 +00001257 /* ADDITION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001258 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2,
1259 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1260 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001261
1262 /* SUBTRACTION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001263 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2,
1264 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1265 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001266
1267 /* MULTIPLICATION (normal / high half of signed/unsigned) */
sewardj2fdd4162010-08-22 12:59:02 +00001268 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4,
1269 Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1270 Iop_MulHi16Sx8, Iop_MulHi32Sx4,
cerion24d06f12005-11-09 21:34:20 +00001271 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
cerion1ac656a2005-11-04 19:44:48 +00001272 Iop_MullEven8Ux16, Iop_MullEven16Ux8,
1273 Iop_MullEven8Sx16, Iop_MullEven16Sx8,
sewardj2fdd4162010-08-22 12:59:02 +00001274 /* FIXME: document these */
1275 Iop_Mull8Ux8, Iop_Mull8Sx8,
1276 Iop_Mull16Ux4, Iop_Mull16Sx4,
1277 Iop_Mull32Ux2, Iop_Mull32Sx2,
1278 /* Vector Saturating Doubling Multiply Returning High Half and
1279 Vector Saturating Rounding Doubling Multiply Returning High Half */
1280 /* These IROp's multiply corresponding elements in two vectors, double
1281 the results, and place the most significant half of the final results
1282 in the destination vector. The results are truncated or rounded. If
1283 any of the results overflow, they are saturated. */
1284 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4,
1285 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4,
1286 /* Doubling saturating multiplication (long) (I64, I64) -> V128 */
1287 Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2,
1288 /* Plynomial multiplication treats it's arguments as coefficients of
1289 polynoms over {0, 1}. */
1290 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1291 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */
1292
1293 /* PAIRWISE operations */
1294 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1295 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1296 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1297 Iop_PwAdd32Fx2,
1298 /* Longening variant is unary. The resulting vector contains two times
1299 less elements than operand, but they are two times wider.
1300 Example:
1301 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1302 where a+b and c+d are unsigned 32-bit values. */
1303 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1304 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1305
1306 /* ABSOLUTE VALUE */
1307 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4,
cerion1ac656a2005-11-04 19:44:48 +00001308
sewardj5ce5fd62005-04-19 23:06:11 +00001309 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
cerionf887b3e2005-09-13 16:34:28 +00001310 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1311 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
sewardj164f9272004-12-09 00:39:32 +00001312
1313 /* MIN/MAX */
cerionf887b3e2005-09-13 16:34:28 +00001314 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
1315 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
1316 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
1317 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001318
1319 /* COMPARISON */
sewardjd8815622011-10-19 15:24:01 +00001320 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2,
sewardj69d98e32010-06-18 08:17:41 +00001321 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
cerionf887b3e2005-09-13 16:34:28 +00001322 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001323
sewardj2fdd4162010-08-22 12:59:02 +00001324 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1325 bit) */
1326 Iop_Cnt8x16,
1327 Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4,
1328 Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4,
1329
sewardj164f9272004-12-09 00:39:32 +00001330 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
cerion2a4b8452005-09-15 16:28:36 +00001331 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1332 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001333 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
sewardj164f9272004-12-09 00:39:32 +00001334
cerionf887b3e2005-09-13 16:34:28 +00001335 /* VECTOR x VECTOR SHIFT / ROTATE */
sewardj2fdd4162010-08-22 12:59:02 +00001336 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1337 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1338 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1339 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
sewardj1bee5612005-11-10 18:10:58 +00001340 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
cerionf887b3e2005-09-13 16:34:28 +00001341
sewardj2fdd4162010-08-22 12:59:02 +00001342 /* VECTOR x VECTOR SATURATING SHIFT */
1343 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1344 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1345 /* VECTOR x INTEGER SATURATING SHIFT */
1346 Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2,
1347 Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2,
1348 Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2,
1349
sewardj5f438dd2011-06-16 11:36:23 +00001350 /* NARROWING (binary)
1351 -- narrow 2xV128 into 1xV128, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +00001352 /* See comments above w.r.t. U vs S issues in saturated narrowing. */
sewardj5f438dd2011-06-16 11:36:23 +00001353 Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1354 Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1355 Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1356 Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
sewardj164f9272004-12-09 00:39:32 +00001357
sewardj5f438dd2011-06-16 11:36:23 +00001358 /* NARROWING (unary) -- narrow V128 into I64 */
1359 Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1360 /* Saturating narrowing from signed source to signed/unsigned destination */
1361 Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1362 Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1363 /* Saturating narrowing from unsigned source to unsigned destination */
1364 Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1365
1366 /* WIDENING -- sign or zero extend each element of the argument
1367 vector to the twice original size. The resulting vector consists of
sewardj2fdd4162010-08-22 12:59:02 +00001368 the same number of elements but each element and the vector itself
sewardj5f438dd2011-06-16 11:36:23 +00001369 are twice as wide.
sewardj2fdd4162010-08-22 12:59:02 +00001370 All operations are I64->V128.
1371 Example
sewardj5f438dd2011-06-16 11:36:23 +00001372 Iop_Widen32Sto64x2( [a, b] ) = [c, d]
sewardj2fdd4162010-08-22 12:59:02 +00001373 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
sewardj5f438dd2011-06-16 11:36:23 +00001374 Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1375 Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001376
1377 /* INTERLEAVING */
1378 /* Interleave lanes from low or high halves of
sewardj164f9272004-12-09 00:39:32 +00001379 operands. Most-significant result lane is from the left
1380 arg. */
1381 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1382 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001383 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
cerionf887b3e2005-09-13 16:34:28 +00001384 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001385 /* Interleave odd/even lanes of operands. Most-significant result lane
1386 is from the left arg. */
1387 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1388 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1389 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1390
1391 /* CONCATENATION -- build a new value by concatenating either
1392 the even or odd lanes of both operands. */
1393 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1394 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1395
1396 /* GET elements of VECTOR
1397 GET is binop (V128, I8) -> I<elem_size> */
1398 /* Note: the arm back-end handles only constant second argument. */
1399 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
cerionf887b3e2005-09-13 16:34:28 +00001400
1401 /* DUPLICATING -- copy value to all lanes */
sewardj2fdd4162010-08-22 12:59:02 +00001402 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
1403
1404 /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes
1405 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
1406 result.
1407 It is a triop: (V128, V128, I8) -> V128 */
1408 /* Note: the ARM back end handles only constant arg3 in this operation. */
1409 Iop_ExtractV128,
1410
1411 /* REVERSE the order of elements in each Half-words, Words,
1412 Double-words */
1413 /* Examples:
1414 Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1415 Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */
1416 Iop_Reverse16_8x16,
1417 Iop_Reverse32_8x16, Iop_Reverse32_16x8,
1418 Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4,
cerionf887b3e2005-09-13 16:34:28 +00001419
1420 /* PERMUTING -- copy src bytes to dst,
sewardjdc1f9132005-10-22 12:49:49 +00001421 as indexed by control vector bytes:
1422 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1423 argR[i] values may only be in the range 0 .. 15, else behaviour
1424 is undefined. */
sewardj2fdd4162010-08-22 12:59:02 +00001425 Iop_Perm8x16,
sewardjd8bca7e2012-06-20 11:46:19 +00001426 Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
sewardj2fdd4162010-08-22 12:59:02 +00001427
1428 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1429 See floating-point equiwalents for details. */
sewardjc4530ae2012-05-21 10:18:49 +00001430 Iop_Recip32x4, Iop_Rsqrte32x4,
1431
1432 /* ------------------ 256-bit SIMD Integer. ------------------ */
1433
1434 /* Pack/unpack */
sewardj4b1cc832012-06-13 11:10:20 +00001435 Iop_V256to64_0, // V256 -> I64, extract least significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001436 Iop_V256to64_1,
1437 Iop_V256to64_2,
sewardj4b1cc832012-06-13 11:10:20 +00001438 Iop_V256to64_3, // V256 -> I64, extract most significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001439
sewardj56c30312012-06-12 08:45:39 +00001440 Iop_64x4toV256, // (I64,I64,I64,I64)->V256
sewardjc4530ae2012-05-21 10:18:49 +00001441 // first arg is most significant lane
sewardj56c30312012-06-12 08:45:39 +00001442
sewardj4b1cc832012-06-13 11:10:20 +00001443 Iop_V256toV128_0, // V256 -> V128, less significant lane
1444 Iop_V256toV128_1, // V256 -> V128, more significant lane
1445 Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1446
1447 Iop_AndV256,
sewardj2a2bda92012-06-14 23:32:02 +00001448 Iop_OrV256,
sewardj4b1cc832012-06-13 11:10:20 +00001449 Iop_XorV256,
sewardj2a2bda92012-06-14 23:32:02 +00001450 Iop_NotV256,
sewardj4b1cc832012-06-13 11:10:20 +00001451
sewardj23db8a02012-06-25 07:46:18 +00001452 /* MISC (vector integer cmp != 0) */
1453 Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1454
sewardj56c30312012-06-12 08:45:39 +00001455 /* ------------------ 256-bit SIMD FP. ------------------ */
1456 Iop_Add64Fx4,
1457 Iop_Sub64Fx4,
1458 Iop_Mul64Fx4,
1459 Iop_Div64Fx4,
1460 Iop_Add32Fx8,
1461 Iop_Sub32Fx8,
1462 Iop_Mul32Fx8,
sewardjf0ad4f82012-06-19 06:57:59 +00001463 Iop_Div32Fx8,
1464
1465 Iop_Sqrt32Fx8,
1466 Iop_Sqrt64Fx4,
sewardj8eb7ae82012-06-24 14:00:27 +00001467 Iop_RSqrt32Fx8,
sewardj82096922012-06-24 14:57:59 +00001468 Iop_Recip32Fx8,
sewardj8eb7ae82012-06-24 14:00:27 +00001469
1470 Iop_Max32Fx8, Iop_Min32Fx8,
1471 Iop_Max64Fx4, Iop_Min64Fx4
sewardjac6b7122004-06-27 01:03:57 +00001472 }
1473 IROp;
sewardjec6ad592004-06-20 12:26:53 +00001474
sewardj57c10c82006-11-15 02:57:05 +00001475/* Pretty-print an op. */
sewardj35421a32004-07-05 13:12:34 +00001476extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +00001477
sewardje3d0d2e2004-06-27 10:42:44 +00001478
sewardjb183b852006-02-03 16:08:03 +00001479/* Encoding of IEEE754-specified rounding modes. This is the same as
sewardjf1b5b1a2006-02-03 22:54:17 +00001480 the encoding used by Intel IA32 to indicate x87 rounding mode.
1481 Note, various front and back ends rely on the actual numerical
1482 values of these, so do not change them. */
sewardjc9868d72004-09-12 19:19:17 +00001483typedef
sewardjf1b5b1a2006-02-03 22:54:17 +00001484 enum {
1485 Irrm_NEAREST = 0,
1486 Irrm_NegINF = 1,
1487 Irrm_PosINF = 2,
1488 Irrm_ZERO = 3
1489 }
sewardjc9868d72004-09-12 19:19:17 +00001490 IRRoundingMode;
1491
sewardjc6bbd472012-04-02 10:20:48 +00001492/* DFP encoding of IEEE754 2008 specified rounding modes extends the two bit
1493 * binary floating point rounding mode (IRRoundingMode) to three bits. The
1494 * DFP rounding modes are a super set of the binary rounding modes. The
1495 * encoding was chosen such that the mapping of the least significant two bits
1496 * of the IR to POWER encodings is same. The upper IR encoding bit is just
1497 * a logical OR of the upper rounding mode bit from the POWER encoding.
1498 */
1499typedef
1500 enum {
1501 Irrm_DFP_NEAREST = 0, // Round to nearest, ties to even
1502 Irrm_DFP_NegINF = 1, // Round to negative infinity
1503 Irrm_DFP_PosINF = 2, // Round to posative infinity
1504 Irrm_DFP_ZERO = 3, // Round toward zero
1505 Irrm_DFP_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0
1506 Irrm_DFP_PREPARE_SHORTER = 5, // Round to prepare for storter
1507 // precision
1508 Irrm_DFP_AWAY_FROM_ZERO = 6, // Round to away from 0
1509 Irrm_DFP_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0
1510 }
1511 IRRoundingModeDFP;
1512
sewardjc9868d72004-09-12 19:19:17 +00001513/* Floating point comparison result values, as created by Iop_CmpF64.
1514 This is also derived from what IA32 does. */
1515typedef
1516 enum {
1517 Ircr_UN = 0x45,
1518 Ircr_LT = 0x01,
1519 Ircr_GT = 0x00,
1520 Ircr_EQ = 0x40
1521 }
1522 IRCmpF64Result;
1523
sewardj2019a972011-03-07 16:04:07 +00001524typedef IRCmpF64Result IRCmpF32Result;
1525typedef IRCmpF64Result IRCmpF128Result;
sewardjc9868d72004-09-12 19:19:17 +00001526
sewardjc97096c2004-06-30 09:28:04 +00001527/* ------------------ Expressions ------------------ */
sewardjd1725d12004-08-12 20:46:53 +00001528
florianeadea2e2012-06-06 12:53:14 +00001529typedef struct _IRQop IRQop; /* forward declaration */
1530typedef struct _IRTriop IRTriop; /* forward declaration */
florian96d7cc32012-06-01 20:41:24 +00001531
1532
sewardj57c10c82006-11-15 02:57:05 +00001533/* The different kinds of expressions. Their meaning is explained below
1534 in the comments for IRExpr. */
sewardje3d0d2e2004-06-27 10:42:44 +00001535typedef
sewardjb3bce0e2004-09-14 23:20:10 +00001536 enum {
sewardjc4356f02007-11-09 21:15:04 +00001537 Iex_Binder=0x15000,
sewardj57c10c82006-11-15 02:57:05 +00001538 Iex_Get,
1539 Iex_GetI,
sewardjdd40fdf2006-12-24 02:20:24 +00001540 Iex_RdTmp,
sewardj57c10c82006-11-15 02:57:05 +00001541 Iex_Qop,
1542 Iex_Triop,
1543 Iex_Binop,
1544 Iex_Unop,
1545 Iex_Load,
1546 Iex_Const,
1547 Iex_Mux0X,
1548 Iex_CCall
sewardjb3bce0e2004-09-14 23:20:10 +00001549 }
sewardje3d0d2e2004-06-27 10:42:44 +00001550 IRExprTag;
1551
sewardj57c10c82006-11-15 02:57:05 +00001552/* An expression. Stored as a tagged union. 'tag' indicates what kind
1553 of expression this is. 'Iex' is the union that holds the fields. If
1554 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1555 expression, and the fields can be accessed with
1556 'e.Iex.Load.<fieldname>'.
1557
1558 For each kind of expression, we show what it looks like when
1559 pretty-printed with ppIRExpr().
1560*/
1561typedef
1562 struct _IRExpr
sewardje3d0d2e2004-06-27 10:42:44 +00001563 IRExpr;
1564
sewardj57c10c82006-11-15 02:57:05 +00001565struct _IRExpr {
1566 IRExprTag tag;
1567 union {
1568 /* Used only in pattern matching within Vex. Should not be seen
1569 outside of Vex. */
1570 struct {
1571 Int binder;
1572 } Binder;
1573
1574 /* Read a guest register, at a fixed offset in the guest state.
1575 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1576 */
1577 struct {
1578 Int offset; /* Offset into the guest state */
1579 IRType ty; /* Type of the value being read */
1580 } Get;
1581
1582 /* Read a guest register at a non-fixed offset in the guest
1583 state. This allows circular indexing into parts of the guest
1584 state, which is essential for modelling situations where the
1585 identity of guest registers is not known until run time. One
1586 example is the x87 FP register stack.
1587
1588 The part of the guest state to be treated as a circular array
sewardjdd40fdf2006-12-24 02:20:24 +00001589 is described in the IRRegArray 'descr' field. It holds the
sewardj57c10c82006-11-15 02:57:05 +00001590 offset of the first element in the array, the type of each
1591 element, and the number of elements.
1592
1593 The array index is indicated rather indirectly, in a way
1594 which makes optimisation easy: as the sum of variable part
1595 (the 'ix' field) and a constant offset (the 'bias' field).
1596
1597 Since the indexing is circular, the actual array index to use
1598 is computed as (ix + bias) % num-of-elems-in-the-array.
1599
1600 Here's an example. The description
1601
1602 (96:8xF64)[t39,-7]
1603
1604 describes an array of 8 F64-typed values, the
1605 guest-state-offset of the first being 96. This array is
1606 being indexed at (t39 - 7) % 8.
1607
1608 It is important to get the array size/type exactly correct
1609 since IR optimisation looks closely at such info in order to
1610 establish aliasing/non-aliasing between seperate GetI and
1611 PutI events, which is used to establish when they can be
1612 reordered, etc. Putting incorrect info in will lead to
1613 obscure IR optimisation bugs.
1614
1615 ppIRExpr output: GETI<descr>[<ix>,<bias]
1616 eg. GETI(128:8xI8)[t1,0]
1617 */
1618 struct {
sewardjdd40fdf2006-12-24 02:20:24 +00001619 IRRegArray* descr; /* Part of guest state treated as circular */
1620 IRExpr* ix; /* Variable part of index into array */
1621 Int bias; /* Constant offset part of index into array */
sewardj57c10c82006-11-15 02:57:05 +00001622 } GetI;
1623
1624 /* The value held by a temporary.
1625 ppIRExpr output: t<tmp>, eg. t1
1626 */
1627 struct {
1628 IRTemp tmp; /* The temporary number */
sewardjdd40fdf2006-12-24 02:20:24 +00001629 } RdTmp;
sewardj57c10c82006-11-15 02:57:05 +00001630
1631 /* A quaternary operation.
1632 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1633 eg. MAddF64r32(t1, t2, t3, t4)
1634 */
1635 struct {
florian96d7cc32012-06-01 20:41:24 +00001636 IRQop* details;
sewardj57c10c82006-11-15 02:57:05 +00001637 } Qop;
1638
1639 /* A ternary operation.
1640 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1641 eg. MulF64(1, 2.0, 3.0)
1642 */
1643 struct {
florian420bfa92012-06-02 20:29:22 +00001644 IRTriop* details;
sewardj57c10c82006-11-15 02:57:05 +00001645 } Triop;
1646
1647 /* A binary operation.
1648 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1649 */
1650 struct {
1651 IROp op; /* op-code */
1652 IRExpr* arg1; /* operand 1 */
1653 IRExpr* arg2; /* operand 2 */
1654 } Binop;
1655
1656 /* A unary operation.
1657 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1658 */
1659 struct {
1660 IROp op; /* op-code */
1661 IRExpr* arg; /* operand */
1662 } Unop;
1663
sewardje768e922009-11-26 17:17:37 +00001664 /* A load from memory -- a normal load, not a load-linked.
1665 Load-Linkeds (and Store-Conditionals) are instead represented
1666 by IRStmt.LLSC since Load-Linkeds have side effects and so
1667 are not semantically valid IRExpr's.
sewardj57c10c82006-11-15 02:57:05 +00001668 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1669 */
1670 struct {
1671 IREndness end; /* Endian-ness of the load */
1672 IRType ty; /* Type of the loaded value */
1673 IRExpr* addr; /* Address being loaded from */
1674 } Load;
1675
1676 /* A constant-valued expression.
1677 ppIRExpr output: <con>, eg. 0x4:I32
1678 */
1679 struct {
1680 IRConst* con; /* The constant itself */
1681 } Const;
1682
1683 /* A call to a pure (no side-effects) helper C function.
1684
1685 With the 'cee' field, 'name' is the function's name. It is
1686 only used for pretty-printing purposes. The address to call
1687 (host address, of course) is stored in the 'addr' field
1688 inside 'cee'.
1689
1690 The 'args' field is a NULL-terminated array of arguments.
1691 The stated return IRType, and the implied argument types,
1692 must match that of the function being called well enough so
1693 that the back end can actually generate correct code for the
1694 call.
1695
1696 The called function **must** satisfy the following:
1697
1698 * no side effects -- must be a pure function, the result of
1699 which depends only on the passed parameters.
1700
1701 * it may not look at, nor modify, any of the guest state
1702 since that would hide guest state transitions from
1703 instrumenters
1704
1705 * it may not access guest memory, since that would hide
1706 guest memory transactions from the instrumenters
1707
florian52af7bc2012-05-12 03:44:49 +00001708 * it must not assume that arguments are being evaluated in a
1709 particular order. The oder of evaluation is unspecified.
1710
sewardj57c10c82006-11-15 02:57:05 +00001711 This is restrictive, but makes the semantics clean, and does
1712 not interfere with IR optimisation.
1713
1714 If you want to call a helper which can mess with guest state
1715 and/or memory, instead use Ist_Dirty. This is a lot more
1716 flexible, but you have to give a bunch of details about what
1717 the helper does (and you better be telling the truth,
1718 otherwise any derived instrumentation will be wrong). Also
1719 Ist_Dirty inhibits various IR optimisations and so can cause
1720 quite poor code to be generated. Try to avoid it.
1721
1722 ppIRExpr output: <cee>(<args>):<retty>
1723 eg. foo{0x80489304}(t1, t2):I32
1724 */
1725 struct {
1726 IRCallee* cee; /* Function to call. */
1727 IRType retty; /* Type of return value. */
1728 IRExpr** args; /* Vector of argument expressions. */
1729 } CCall;
1730
1731 /* A ternary if-then-else operator. It returns expr0 if cond is
1732 zero, exprX otherwise. Note that it is STRICT, ie. both
1733 expr0 and exprX are evaluated in all cases.
1734
1735 ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1736 eg. Mux0X(t6,t7,t8)
1737 */
1738 struct {
1739 IRExpr* cond; /* Condition */
1740 IRExpr* expr0; /* True expression */
1741 IRExpr* exprX; /* False expression */
1742 } Mux0X;
1743 } Iex;
1744};
1745
florian420bfa92012-06-02 20:29:22 +00001746/* ------------------ A ternary expression ---------------------- */
1747struct _IRTriop {
1748 IROp op; /* op-code */
1749 IRExpr* arg1; /* operand 1 */
1750 IRExpr* arg2; /* operand 2 */
1751 IRExpr* arg3; /* operand 3 */
1752};
1753
florian96d7cc32012-06-01 20:41:24 +00001754/* ------------------ A quarternary expression ------------------ */
1755struct _IRQop {
1756 IROp op; /* op-code */
1757 IRExpr* arg1; /* operand 1 */
1758 IRExpr* arg2; /* operand 2 */
1759 IRExpr* arg3; /* operand 3 */
1760 IRExpr* arg4; /* operand 4 */
1761};
1762
sewardj57c10c82006-11-15 02:57:05 +00001763/* Expression constructors. */
sewardj443cd9d2004-07-18 23:06:45 +00001764extern IRExpr* IRExpr_Binder ( Int binder );
1765extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjdd40fdf2006-12-24 02:20:24 +00001766extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
1767extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
sewardj40c80262006-02-08 19:30:46 +00001768extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1769 IRExpr* arg3, IRExpr* arg4 );
sewardjb183b852006-02-03 16:08:03 +00001770extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1771 IRExpr* arg2, IRExpr* arg3 );
sewardj443cd9d2004-07-18 23:06:45 +00001772extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1773extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
sewardje768e922009-11-26 17:17:37 +00001774extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
sewardj443cd9d2004-07-18 23:06:45 +00001775extern IRExpr* IRExpr_Const ( IRConst* con );
sewardj8ea867b2004-10-30 19:03:02 +00001776extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
sewardj443cd9d2004-07-18 23:06:45 +00001777extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
sewardje3d0d2e2004-06-27 10:42:44 +00001778
sewardj57c10c82006-11-15 02:57:05 +00001779/* Deep-copy an IRExpr. */
sewardjdd40fdf2006-12-24 02:20:24 +00001780extern IRExpr* deepCopyIRExpr ( IRExpr* );
sewardj695cff92004-10-13 14:50:14 +00001781
sewardj57c10c82006-11-15 02:57:05 +00001782/* Pretty-print an IRExpr. */
sewardj35421a32004-07-05 13:12:34 +00001783extern void ppIRExpr ( IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00001784
sewardj57c10c82006-11-15 02:57:05 +00001785/* NULL-terminated IRExpr vector constructors, suitable for
1786 use as arg lists in clean/dirty helper calls. */
sewardjc5fc7aa2004-10-27 23:00:55 +00001787extern IRExpr** mkIRExprVec_0 ( void );
sewardjf9655262004-10-31 20:02:16 +00001788extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1789extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1790extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1791extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
sewardj78ec32b2007-01-08 05:09:55 +00001792extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1793 IRExpr* );
1794extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1795 IRExpr*, IRExpr* );
1796extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
sewardjf32c67d2004-11-08 13:10:44 +00001797 IRExpr*, IRExpr*, IRExpr* );
sewardj2fdd4162010-08-22 12:59:02 +00001798extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1799 IRExpr*, IRExpr*, IRExpr*, IRExpr*);
sewardjc5fc7aa2004-10-27 23:00:55 +00001800
sewardj57c10c82006-11-15 02:57:05 +00001801/* IRExpr copiers:
sewardjdd40fdf2006-12-24 02:20:24 +00001802 - shallowCopy: shallow-copy (ie. create a new vector that shares the
sewardj57c10c82006-11-15 02:57:05 +00001803 elements with the original).
sewardjdd40fdf2006-12-24 02:20:24 +00001804 - deepCopy: deep-copy (ie. create a completely new vector). */
1805extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1806extern IRExpr** deepCopyIRExprVec ( IRExpr** );
sewardjc5fc7aa2004-10-27 23:00:55 +00001807
sewardjf9655262004-10-31 20:02:16 +00001808/* Make a constant expression from the given host word taking into
sewardj57c10c82006-11-15 02:57:05 +00001809 account (of course) the host word size. */
sewardj49651f42004-10-28 22:11:04 +00001810extern IRExpr* mkIRExpr_HWord ( HWord );
1811
sewardjf9655262004-10-31 20:02:16 +00001812/* Convenience function for constructing clean helper calls. */
1813extern
1814IRExpr* mkIRExprCCall ( IRType retty,
sewardj2d49b432005-02-01 00:37:06 +00001815 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00001816 IRExpr** args );
1817
sewardj49651f42004-10-28 22:11:04 +00001818
sewardj57c10c82006-11-15 02:57:05 +00001819/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1820 * Iex_Const). */
sewardj496a58d2005-03-20 18:44:44 +00001821static inline Bool isIRAtom ( IRExpr* e ) {
sewardjdd40fdf2006-12-24 02:20:24 +00001822 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
sewardj49651f42004-10-28 22:11:04 +00001823}
1824
sewardj496a58d2005-03-20 18:44:44 +00001825/* Are these two IR atoms identical? Causes an assertion
1826 failure if they are passed non-atoms. */
1827extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1828
sewardje87b4842004-07-10 12:23:30 +00001829
sewardj893aada2004-11-29 19:57:54 +00001830/* ------------------ Jump kinds ------------------ */
1831
1832/* This describes hints which can be passed to the dispatcher at guest
1833 control-flow transfer points.
sewardj7ce9d152005-03-15 16:54:13 +00001834
sewardj57c10c82006-11-15 02:57:05 +00001835 Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1836 guest_TISTART and guest_TILEN, which specify the start and length
1837 of the region to be invalidated. These are both the size of a
1838 guest word. It is the responsibility of the relevant toIR.c to
1839 ensure that these are filled in with suitable values before issuing
1840 a jump of kind Ijk_TInval.
sewardj9dd9cf12006-01-20 14:13:55 +00001841
1842 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
sewardj57c10c82006-11-15 02:57:05 +00001843 pseudo-register guest_EMWARN, which is 32-bits regardless of the
1844 host or guest word size. That register should be made to hold an
1845 EmWarn_* value to indicate the reason for the exit.
sewardj9dd9cf12006-01-20 14:13:55 +00001846
1847 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1848 cannot continue) and so the jump destination can be anything.
sewardje86310f2009-03-19 22:21:40 +00001849
1850 Re Ijk_Sys_ (syscall jumps): the guest state must have a
1851 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1852 word. Front ends should set this to be the IP at the most recently
1853 executed kernel-entering (system call) instruction. This makes it
1854 very much easier (viz, actually possible at all) to back up the
1855 guest to restart a syscall that has been interrupted by a signal.
sewardj893aada2004-11-29 19:57:54 +00001856*/
1857typedef
sewardjc6f970f2012-04-02 21:54:49 +00001858 enum {
1859 Ijk_INVALID=0x16000,
1860 Ijk_Boring, /* not interesting; just goto next */
sewardj893aada2004-11-29 19:57:54 +00001861 Ijk_Call, /* guest is doing a call */
1862 Ijk_Ret, /* guest is doing a return */
1863 Ijk_ClientReq, /* do guest client req before continuing */
sewardj893aada2004-11-29 19:57:54 +00001864 Ijk_Yield, /* client is yielding to thread scheduler */
sewardj52444cb2004-12-13 14:09:01 +00001865 Ijk_EmWarn, /* report emulation warning before continuing */
sewardj9dd9cf12006-01-20 14:13:55 +00001866 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
sewardj52444cb2004-12-13 14:09:01 +00001867 Ijk_NoDecode, /* next instruction cannot be decoded */
sewardj7ce9d152005-03-15 16:54:13 +00001868 Ijk_MapFail, /* Vex-provided address translation failed */
sewardjf07ed032005-08-07 14:48:03 +00001869 Ijk_TInval, /* Invalidate translations before continuing. */
sewardjce02aa72006-01-12 12:27:58 +00001870 Ijk_NoRedir, /* Jump to un-redirected guest addr */
sewardj0f500042007-08-29 09:09:17 +00001871 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
1872 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
sewardje9d8a262009-07-01 08:06:34 +00001873 Ijk_SigBUS, /* current instruction synths SIGBUS */
sewardj4fa325a2005-11-03 13:27:24 +00001874 /* Unfortunately, various guest-dependent syscall kinds. They
1875 all mean: do a syscall before continuing. */
sewardj6c299f32009-12-31 18:00:12 +00001876 Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
sewardj4fa325a2005-11-03 13:27:24 +00001877 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
1878 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
sewardjd660d412008-12-03 21:29:59 +00001879 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
1880 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
sewardj4fa325a2005-11-03 13:27:24 +00001881 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes
1882 invalid at the point this happens. */
sewardj893aada2004-11-29 19:57:54 +00001883 }
1884 IRJumpKind;
1885
1886extern void ppIRJumpKind ( IRJumpKind );
1887
1888
sewardjb3bce0e2004-09-14 23:20:10 +00001889/* ------------------ Dirty helper calls ------------------ */
sewardje87b4842004-07-10 12:23:30 +00001890
sewardj57c10c82006-11-15 02:57:05 +00001891/* A dirty call is a flexible mechanism for calling (possibly
1892 conditionally) a helper function or procedure. The helper function
1893 may read, write or modify client memory, and may read, write or
1894 modify client state. It can take arguments and optionally return a
1895 value. It may return different results and/or do different things
1896 when called repeatedly with the same arguments, by means of storing
1897 private state.
sewardje87b4842004-07-10 12:23:30 +00001898
sewardjc5fc7aa2004-10-27 23:00:55 +00001899 If a value is returned, it is assigned to the nominated return
1900 temporary.
sewardjb3bce0e2004-09-14 23:20:10 +00001901
1902 Dirty calls are statements rather than expressions for obvious
sewardj57c10c82006-11-15 02:57:05 +00001903 reasons. If a dirty call is marked as writing guest state, any
sewardjc5fc7aa2004-10-27 23:00:55 +00001904 values derived from the written parts of the guest state are
1905 invalid. Similarly, if the dirty call is stated as writing
1906 memory, any loaded values are invalidated by it.
sewardjb3bce0e2004-09-14 23:20:10 +00001907
1908 In order that instrumentation is possible, the call must state, and
sewardj57c10c82006-11-15 02:57:05 +00001909 state correctly:
sewardjb3bce0e2004-09-14 23:20:10 +00001910
1911 * whether it reads, writes or modifies memory, and if so where
1912 (only one chunk can be stated)
1913
1914 * whether it reads, writes or modifies guest state, and if so which
1915 pieces (several pieces may be stated, and currently their extents
1916 must be known at translation-time).
sewardjc5fc7aa2004-10-27 23:00:55 +00001917
1918 Normally, code is generated to pass just the args to the helper.
1919 However, if .needsBBP is set, then an extra first argument is
1920 passed, which is the baseblock pointer, so that the callee can
1921 access the guest state. It is invalid for .nFxState to be zero
1922 but .needsBBP to be True, since .nFxState==0 is a claim that the
1923 call does not access guest state.
sewardjb8385d82004-11-02 01:34:15 +00001924
1925 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
florian52af7bc2012-05-12 03:44:49 +00001926 arguments are evaluated REGARDLESS of the guard value. The order of
1927 argument evaluation is unspecified. The guard expression is evaluated
1928 AFTER the arguments have been evaluated.
sewardje87b4842004-07-10 12:23:30 +00001929*/
sewardjc97096c2004-06-30 09:28:04 +00001930
sewardja0e83b02005-01-06 12:36:38 +00001931#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
sewardjb3bce0e2004-09-14 23:20:10 +00001932
sewardj57c10c82006-11-15 02:57:05 +00001933/* Effects on resources (eg. registers, memory locations) */
sewardjb3bce0e2004-09-14 23:20:10 +00001934typedef
1935 enum {
sewardjc9069f22012-06-01 16:09:50 +00001936 Ifx_None = 0x1700, /* no effect */
sewardj17442fe2004-09-20 14:54:28 +00001937 Ifx_Read, /* reads the resource */
1938 Ifx_Write, /* writes the resource */
1939 Ifx_Modify, /* modifies the resource */
sewardjb3bce0e2004-09-14 23:20:10 +00001940 }
1941 IREffect;
1942
sewardj57c10c82006-11-15 02:57:05 +00001943/* Pretty-print an IREffect */
sewardjb3bce0e2004-09-14 23:20:10 +00001944extern void ppIREffect ( IREffect );
1945
1946
1947typedef
sewardjc9069f22012-06-01 16:09:50 +00001948 struct _IRDirty {
sewardjf5dfa3b2012-07-10 16:41:46 +00001949 /* What to call, and details of args/results. .guard must be
1950 non-NULL. If .tmp is not IRTemp_INVALID (that is, the call
1951 returns a result) then .guard must be demonstrably (at
1952 JIT-time) always true, that is, the call must be
1953 unconditional. Conditional calls that assign .tmp are not
1954 allowed. */
sewardj8ea867b2004-10-30 19:03:02 +00001955 IRCallee* cee; /* where to call */
sewardjb8385d82004-11-02 01:34:15 +00001956 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
sewardj8ea867b2004-10-30 19:03:02 +00001957 IRExpr** args; /* arg list, ends in NULL */
sewardj92d168d2004-11-15 14:22:12 +00001958 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
sewardjb3bce0e2004-09-14 23:20:10 +00001959
1960 /* Mem effects; we allow only one R/W/M region to be stated */
sewardj8ea867b2004-10-30 19:03:02 +00001961 IREffect mFx; /* indicates memory effects, if any */
1962 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
1963 Int mSize; /* of access, or zero if mFx==Ifx_None */
sewardjb3bce0e2004-09-14 23:20:10 +00001964
1965 /* Guest state effects; up to N allowed */
sewardjc5fc7aa2004-10-27 23:00:55 +00001966 Bool needsBBP; /* True => also pass guest state ptr to callee */
1967 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
sewardjb3bce0e2004-09-14 23:20:10 +00001968 struct {
sewardjc9069f22012-06-01 16:09:50 +00001969 IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
1970 UShort offset;
1971 UShort size;
1972 UChar nRepeats;
1973 UChar repeatLen;
sewardjb3bce0e2004-09-14 23:20:10 +00001974 } fxState[VEX_N_FXSTATE];
sewardjc9069f22012-06-01 16:09:50 +00001975 /* The access can be repeated, as specified by nRepeats and
1976 repeatLen. To describe only a single access, nRepeats and
1977 repeatLen should be zero. Otherwise, repeatLen must be a
1978 multiple of size and greater than size. */
1979 /* Overall, the parts of the guest state denoted by (offset,
1980 size, nRepeats, repeatLen) is
1981 [offset, +size)
1982 and, if nRepeats > 0,
1983 for (i = 1; i <= nRepeats; i++)
1984 [offset + i * repeatLen, +size)
1985 A convenient way to enumerate all segments is therefore
1986 for (i = 0; i < 1 + nRepeats; i++)
1987 [offset + i * repeatLen, +size)
1988 */
sewardjb3bce0e2004-09-14 23:20:10 +00001989 }
1990 IRDirty;
1991
sewardj57c10c82006-11-15 02:57:05 +00001992/* Pretty-print a dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00001993extern void ppIRDirty ( IRDirty* );
sewardj57c10c82006-11-15 02:57:05 +00001994
1995/* Allocate an uninitialised dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00001996extern IRDirty* emptyIRDirty ( void );
1997
sewardj57c10c82006-11-15 02:57:05 +00001998/* Deep-copy a dirty call */
sewardjdd40fdf2006-12-24 02:20:24 +00001999extern IRDirty* deepCopyIRDirty ( IRDirty* );
sewardj695cff92004-10-13 14:50:14 +00002000
sewardjc5fc7aa2004-10-27 23:00:55 +00002001/* A handy function which takes some of the tedium out of constructing
2002 dirty helper calls. The called function impliedly does not return
sewardjb8385d82004-11-02 01:34:15 +00002003 any value and has a constant-True guard. The call is marked as
2004 accessing neither guest state nor memory (hence the "unsafe"
sewardj57c10c82006-11-15 02:57:05 +00002005 designation) -- you can change this marking later if need be. A
sewardjb8385d82004-11-02 01:34:15 +00002006 suitable IRCallee is constructed from the supplied bits. */
sewardjf9655262004-10-31 20:02:16 +00002007extern
sewardj2d49b432005-02-01 00:37:06 +00002008IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002009 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002010
2011/* Similarly, make a zero-annotation dirty call which returns a value,
2012 and assign that to the given temp. */
sewardjf9655262004-10-31 20:02:16 +00002013extern
2014IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
sewardj2d49b432005-02-01 00:37:06 +00002015 Int regparms, HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002016 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002017
sewardjb3bce0e2004-09-14 23:20:10 +00002018
sewardjc4356f02007-11-09 21:15:04 +00002019/* --------------- Memory Bus Events --------------- */
2020
2021typedef
2022 enum {
2023 Imbe_Fence=0x18000,
sewardj6d615ba2011-09-26 16:19:43 +00002024 /* Needed only on ARM. It cancels a reservation made by a
2025 preceding Linked-Load, and needs to be handed through to the
2026 back end, just as LL and SC themselves are. */
2027 Imbe_CancelReservation
sewardjc4356f02007-11-09 21:15:04 +00002028 }
2029 IRMBusEvent;
2030
2031extern void ppIRMBusEvent ( IRMBusEvent );
2032
2033
sewardje9d8a262009-07-01 08:06:34 +00002034/* --------------- Compare and Swap --------------- */
2035
2036/* This denotes an atomic compare and swap operation, either
2037 a single-element one or a double-element one.
2038
2039 In the single-element case:
2040
2041 .addr is the memory address.
2042 .end is the endianness with which memory is accessed
2043
2044 If .addr contains the same value as .expdLo, then .dataLo is
2045 written there, else there is no write. In both cases, the
2046 original value at .addr is copied into .oldLo.
2047
2048 Types: .expdLo, .dataLo and .oldLo must all have the same type.
2049 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2050 guests, I64.
2051
2052 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2053 be NULL.
2054
2055 In the double-element case:
2056
2057 .addr is the memory address.
2058 .end is the endianness with which memory is accessed
2059
2060 The operation is the same:
2061
2062 If .addr contains the same value as .expdHi:.expdLo, then
2063 .dataHi:.dataLo is written there, else there is no write. In
2064 both cases the original value at .addr is copied into
2065 .oldHi:.oldLo.
2066
2067 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2068 all have the same type, which may be any integral type, viz: I8,
2069 I16, I32 or, for 64-bit guests, I64.
2070
2071 The double-element case is complicated by the issue of
2072 endianness. In all cases, the two elements are understood to be
2073 located adjacently in memory, starting at the address .addr.
2074
2075 If .end is Iend_LE, then the .xxxLo component is at the lower
2076 address and the .xxxHi component is at the higher address, and
2077 each component is itself stored little-endianly.
2078
2079 If .end is Iend_BE, then the .xxxHi component is at the lower
2080 address and the .xxxLo component is at the higher address, and
2081 each component is itself stored big-endianly.
2082
2083 This allows representing more cases than most architectures can
2084 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
2085
2086 How to know if the CAS succeeded?
2087
2088 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2089 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2090 stored at .addr, and the original value there was .oldLo (resp
2091 .oldHi:.oldLo).
2092
2093 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2094 then the CAS failed, and the original value at .addr was .oldLo
2095 (resp. .oldHi:.oldLo).
2096
2097 Hence it is easy to know whether or not the CAS succeeded.
2098*/
2099typedef
2100 struct {
2101 IRTemp oldHi; /* old value of *addr is written here */
2102 IRTemp oldLo;
2103 IREndness end; /* endianness of the data in memory */
2104 IRExpr* addr; /* store address */
2105 IRExpr* expdHi; /* expected old value at *addr */
2106 IRExpr* expdLo;
2107 IRExpr* dataHi; /* new value for *addr */
2108 IRExpr* dataLo;
2109 }
2110 IRCAS;
2111
2112extern void ppIRCAS ( IRCAS* cas );
2113
2114extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2115 IREndness end, IRExpr* addr,
2116 IRExpr* expdHi, IRExpr* expdLo,
2117 IRExpr* dataHi, IRExpr* dataLo );
2118
2119extern IRCAS* deepCopyIRCAS ( IRCAS* );
2120
floriand6f38b32012-05-31 15:46:18 +00002121
2122/* ------------------ Circular Array Put ------------------ */
2123typedef
2124 struct {
2125 IRRegArray* descr; /* Part of guest state treated as circular */
2126 IRExpr* ix; /* Variable part of index into array */
2127 Int bias; /* Constant offset part of index into array */
2128 IRExpr* data; /* The value to write */
2129 } IRPutI;
2130
2131extern void ppIRPutI ( IRPutI* puti );
2132
2133extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2134 Int bias, IRExpr* data );
2135
2136extern IRPutI* deepCopyIRPutI ( IRPutI* );
2137
sewardjc9069f22012-06-01 16:09:50 +00002138
sewardjc97096c2004-06-30 09:28:04 +00002139/* ------------------ Statements ------------------ */
sewardjb3bce0e2004-09-14 23:20:10 +00002140
sewardj57c10c82006-11-15 02:57:05 +00002141/* The different kinds of statements. Their meaning is explained
2142 below in the comments for IRStmt.
sewardj5a9ffab2005-05-12 17:55:01 +00002143
sewardj57c10c82006-11-15 02:57:05 +00002144 Those marked META do not represent code, but rather extra
2145 information about the code. These statements can be removed
2146 without affecting the functional behaviour of the code, however
2147 they are required by some IR consumers such as tools that
2148 instrument the code.
sewardj5a9ffab2005-05-12 17:55:01 +00002149*/
sewardjc4356f02007-11-09 21:15:04 +00002150
sewardjac6b7122004-06-27 01:03:57 +00002151typedef
sewardjd2445f62005-03-21 00:15:53 +00002152 enum {
sewardjc4356f02007-11-09 21:15:04 +00002153 Ist_NoOp=0x19000,
sewardj57c10c82006-11-15 02:57:05 +00002154 Ist_IMark, /* META */
2155 Ist_AbiHint, /* META */
2156 Ist_Put,
2157 Ist_PutI,
sewardjdd40fdf2006-12-24 02:20:24 +00002158 Ist_WrTmp,
sewardj57c10c82006-11-15 02:57:05 +00002159 Ist_Store,
sewardje9d8a262009-07-01 08:06:34 +00002160 Ist_CAS,
sewardje768e922009-11-26 17:17:37 +00002161 Ist_LLSC,
sewardj57c10c82006-11-15 02:57:05 +00002162 Ist_Dirty,
sewardjc4356f02007-11-09 21:15:04 +00002163 Ist_MBE, /* META (maybe) */
sewardj57c10c82006-11-15 02:57:05 +00002164 Ist_Exit
sewardjb3bce0e2004-09-14 23:20:10 +00002165 }
sewardjac6b7122004-06-27 01:03:57 +00002166 IRStmtTag;
2167
sewardj57c10c82006-11-15 02:57:05 +00002168/* A statement. Stored as a tagged union. 'tag' indicates what kind
2169 of expression this is. 'Ist' is the union that holds the fields.
2170 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2171 statement, and the fields can be accessed with
2172 'st.Ist.Store.<fieldname>'.
2173
2174 For each kind of statement, we show what it looks like when
sewardje9d8a262009-07-01 08:06:34 +00002175 pretty-printed with ppIRStmt().
sewardj57c10c82006-11-15 02:57:05 +00002176*/
sewardjac6b7122004-06-27 01:03:57 +00002177typedef
2178 struct _IRStmt {
2179 IRStmtTag tag;
2180 union {
sewardj57c10c82006-11-15 02:57:05 +00002181 /* A no-op (usually resulting from IR optimisation). Can be
2182 omitted without any effect.
2183
sewardje9d8a262009-07-01 08:06:34 +00002184 ppIRStmt output: IR-NoOp
sewardj57c10c82006-11-15 02:57:05 +00002185 */
sewardjac6b7122004-06-27 01:03:57 +00002186 struct {
sewardjd2445f62005-03-21 00:15:53 +00002187 } NoOp;
sewardj57c10c82006-11-15 02:57:05 +00002188
2189 /* META: instruction mark. Marks the start of the statements
2190 that represent a single machine instruction (the end of
2191 those statements is marked by the next IMark or the end of
sewardjdd40fdf2006-12-24 02:20:24 +00002192 the IRSB). Contains the address and length of the
sewardj57c10c82006-11-15 02:57:05 +00002193 instruction.
2194
sewardj2f10aa62011-05-27 13:20:56 +00002195 It also contains a delta value. The delta must be
2196 subtracted from a guest program counter value before
2197 attempting to establish, by comparison with the address
2198 and length values, whether or not that program counter
2199 value refers to this instruction. For x86, amd64, ppc32,
2200 ppc64 and arm, the delta value is zero. For Thumb
2201 instructions, the delta value is one. This is because, on
2202 Thumb, guest PC values (guest_R15T) are encoded using the
2203 top 31 bits of the instruction address and a 1 in the lsb;
2204 hence they appear to be (numerically) 1 past the start of
2205 the instruction they refer to. IOW, guest_R15T on ARM
2206 holds a standard ARM interworking address.
2207
2208 ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2209 eg. ------ IMark(0x4000792, 5, 0) ------,
sewardj57c10c82006-11-15 02:57:05 +00002210 */
sewardjd2445f62005-03-21 00:15:53 +00002211 struct {
sewardj57c10c82006-11-15 02:57:05 +00002212 Addr64 addr; /* instruction address */
2213 Int len; /* instruction length */
sewardj2f10aa62011-05-27 13:20:56 +00002214 UChar delta; /* addr = program counter as encoded in guest state
2215 - delta */
sewardjf1689312005-03-16 18:19:10 +00002216 } IMark;
sewardj57c10c82006-11-15 02:57:05 +00002217
2218 /* META: An ABI hint, which says something about this
2219 platform's ABI.
2220
2221 At the moment, the only AbiHint is one which indicates
2222 that a given chunk of address space, [base .. base+len-1],
2223 has become undefined. This is used on amd64-linux and
2224 some ppc variants to pass stack-redzoning hints to whoever
sewardj478646f2008-05-01 20:13:04 +00002225 wants to see them. It also indicates the address of the
2226 next (dynamic) instruction that will be executed. This is
2227 to help Memcheck to origin tracking.
sewardj57c10c82006-11-15 02:57:05 +00002228
sewardje9d8a262009-07-01 08:06:34 +00002229 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
sewardj478646f2008-05-01 20:13:04 +00002230 eg. ====== AbiHint(t1, 16, t2) ======
sewardj57c10c82006-11-15 02:57:05 +00002231 */
sewardjf1689312005-03-16 18:19:10 +00002232 struct {
sewardj57c10c82006-11-15 02:57:05 +00002233 IRExpr* base; /* Start of undefined chunk */
2234 Int len; /* Length of undefined chunk */
sewardj478646f2008-05-01 20:13:04 +00002235 IRExpr* nia; /* Address of next (guest) insn */
sewardj5a9ffab2005-05-12 17:55:01 +00002236 } AbiHint;
sewardj57c10c82006-11-15 02:57:05 +00002237
2238 /* Write a guest register, at a fixed offset in the guest state.
sewardje9d8a262009-07-01 08:06:34 +00002239 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
sewardj57c10c82006-11-15 02:57:05 +00002240 */
sewardj5a9ffab2005-05-12 17:55:01 +00002241 struct {
sewardj57c10c82006-11-15 02:57:05 +00002242 Int offset; /* Offset into the guest state */
2243 IRExpr* data; /* The value to write */
sewardjac6b7122004-06-27 01:03:57 +00002244 } Put;
sewardj57c10c82006-11-15 02:57:05 +00002245
2246 /* Write a guest register, at a non-fixed offset in the guest
2247 state. See the comment for GetI expressions for more
2248 information.
2249
sewardje9d8a262009-07-01 08:06:34 +00002250 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
sewardj57c10c82006-11-15 02:57:05 +00002251 eg. PUTI(64:8xF64)[t5,0] = t1
2252 */
sewardjac6b7122004-06-27 01:03:57 +00002253 struct {
floriand6f38b32012-05-31 15:46:18 +00002254 IRPutI* details;
sewardjd1725d12004-08-12 20:46:53 +00002255 } PutI;
sewardj57c10c82006-11-15 02:57:05 +00002256
sewardjdd40fdf2006-12-24 02:20:24 +00002257 /* Assign a value to a temporary. Note that SSA rules require
2258 each tmp is only assigned to once. IR sanity checking will
2259 reject any block containing a temporary which is not assigned
2260 to exactly once.
sewardj57c10c82006-11-15 02:57:05 +00002261
sewardje9d8a262009-07-01 08:06:34 +00002262 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
sewardj57c10c82006-11-15 02:57:05 +00002263 */
sewardjd1725d12004-08-12 20:46:53 +00002264 struct {
sewardj57c10c82006-11-15 02:57:05 +00002265 IRTemp tmp; /* Temporary (LHS of assignment) */
2266 IRExpr* data; /* Expression (RHS of assignment) */
sewardjdd40fdf2006-12-24 02:20:24 +00002267 } WrTmp;
sewardj57c10c82006-11-15 02:57:05 +00002268
sewardje768e922009-11-26 17:17:37 +00002269 /* Write a value to memory. This is a normal store, not a
2270 Store-Conditional. To represent a Store-Conditional,
2271 instead use IRStmt.LLSC.
sewardje9d8a262009-07-01 08:06:34 +00002272 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
sewardj57c10c82006-11-15 02:57:05 +00002273 */
sewardjac6b7122004-06-27 01:03:57 +00002274 struct {
sewardj57c10c82006-11-15 02:57:05 +00002275 IREndness end; /* Endianness of the store */
2276 IRExpr* addr; /* store address */
2277 IRExpr* data; /* value to write */
sewardjaf1ceca2005-06-30 23:31:27 +00002278 } Store;
sewardj57c10c82006-11-15 02:57:05 +00002279
sewardje9d8a262009-07-01 08:06:34 +00002280 /* Do an atomic compare-and-swap operation. Semantics are
2281 described above on a comment at the definition of IRCAS.
2282
2283 ppIRStmt output:
2284 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2285 eg
2286 t1 = CASle(t2 :: t3->Add32(t3,1))
2287 which denotes a 32-bit atomic increment
2288 of a value at address t2
2289
2290 A double-element CAS may also be denoted, in which case <tmp>,
2291 <expected> and <new> are all pairs of items, separated by
2292 commas.
2293 */
2294 struct {
2295 IRCAS* details;
2296 } CAS;
2297
sewardje768e922009-11-26 17:17:37 +00002298 /* Either Load-Linked or Store-Conditional, depending on
2299 STOREDATA.
2300
2301 If STOREDATA is NULL then this is a Load-Linked, meaning
2302 that data is loaded from memory as normal, but a
2303 'reservation' for the address is also lodged in the
2304 hardware.
2305
2306 result = Load-Linked(addr, end)
2307
2308 The data transfer type is the type of RESULT (I32, I64,
2309 etc). ppIRStmt output:
2310
2311 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2312
2313 If STOREDATA is not NULL then this is a Store-Conditional,
2314 hence:
2315
2316 result = Store-Conditional(addr, storedata, end)
2317
2318 The data transfer type is the type of STOREDATA and RESULT
2319 has type Ity_I1. The store may fail or succeed depending
2320 on the state of a previously lodged reservation on this
2321 address. RESULT is written 1 if the store succeeds and 0
2322 if it fails. eg ppIRStmt output:
2323
2324 result = ( ST<end>-Cond(<addr>) = <storedata> )
2325 eg t3 = ( STbe-Cond(t1, t2) )
2326
2327 In all cases, the address must be naturally aligned for
2328 the transfer type -- any misaligned addresses should be
2329 caught by a dominating IR check and side exit. This
2330 alignment restriction exists because on at least some
2331 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2332 misaligned addresses, and we have to actually generate
2333 stwcx. on the host, and we don't want it trapping on the
2334 host.
2335
2336 Summary of rules for transfer type:
2337 STOREDATA == NULL (LL):
2338 transfer type = type of RESULT
2339 STOREDATA != NULL (SC):
2340 transfer type = type of STOREDATA, and RESULT :: Ity_I1
2341 */
2342 struct {
2343 IREndness end;
2344 IRTemp result;
2345 IRExpr* addr;
2346 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
2347 } LLSC;
2348
sewardj57c10c82006-11-15 02:57:05 +00002349 /* Call (possibly conditionally) a C function that has side
2350 effects (ie. is "dirty"). See the comments above the
2351 IRDirty type declaration for more information.
2352
sewardje9d8a262009-07-01 08:06:34 +00002353 ppIRStmt output:
sewardj57c10c82006-11-15 02:57:05 +00002354 t<tmp> = DIRTY <guard> <effects>
2355 ::: <callee>(<args>)
2356 eg.
2357 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
2358 ::: foo{0x380035f4}(t2)
2359 */
sewardj64e1d652004-07-12 14:00:46 +00002360 struct {
sewardjb3bce0e2004-09-14 23:20:10 +00002361 IRDirty* details;
2362 } Dirty;
sewardj57c10c82006-11-15 02:57:05 +00002363
sewardjc4356f02007-11-09 21:15:04 +00002364 /* A memory bus event - a fence, or acquisition/release of the
2365 hardware bus lock. IR optimisation treats all these as fences
2366 across which no memory references may be moved.
sewardje9d8a262009-07-01 08:06:34 +00002367 ppIRStmt output: MBusEvent-Fence,
sewardjc4356f02007-11-09 21:15:04 +00002368 MBusEvent-BusLock, MBusEvent-BusUnlock.
sewardj57c10c82006-11-15 02:57:05 +00002369 */
sewardjb3bce0e2004-09-14 23:20:10 +00002370 struct {
sewardjc4356f02007-11-09 21:15:04 +00002371 IRMBusEvent event;
2372 } MBE;
sewardj57c10c82006-11-15 02:57:05 +00002373
sewardjdd40fdf2006-12-24 02:20:24 +00002374 /* Conditional exit from the middle of an IRSB.
sewardje9d8a262009-07-01 08:06:34 +00002375 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
sewardj57c10c82006-11-15 02:57:05 +00002376 eg. if (t69) goto {Boring} 0x4000AAA:I32
sewardjc6f970f2012-04-02 21:54:49 +00002377 If <guard> is true, the guest state is also updated by
2378 PUT-ing <dst> at <offsIP>. This is done because a
2379 taken exit must update the guest program counter.
sewardj57c10c82006-11-15 02:57:05 +00002380 */
sewardj3e838932005-01-07 12:09:15 +00002381 struct {
sewardj57c10c82006-11-15 02:57:05 +00002382 IRExpr* guard; /* Conditional expression */
sewardj57c10c82006-11-15 02:57:05 +00002383 IRConst* dst; /* Jump target (constant only) */
floriand6f38b32012-05-31 15:46:18 +00002384 IRJumpKind jk; /* Jump kind */
sewardjc6f970f2012-04-02 21:54:49 +00002385 Int offsIP; /* Guest state offset for IP */
sewardj64e1d652004-07-12 14:00:46 +00002386 } Exit;
sewardjac6b7122004-06-27 01:03:57 +00002387 } Ist;
sewardjac6b7122004-06-27 01:03:57 +00002388 }
2389 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +00002390
sewardj57c10c82006-11-15 02:57:05 +00002391/* Statement constructors. */
sewardj5a9ffab2005-05-12 17:55:01 +00002392extern IRStmt* IRStmt_NoOp ( void );
sewardj2f10aa62011-05-27 13:20:56 +00002393extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len, UChar delta );
sewardj478646f2008-05-01 20:13:04 +00002394extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
sewardj5a9ffab2005-05-12 17:55:01 +00002395extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
floriand6f38b32012-05-31 15:46:18 +00002396extern IRStmt* IRStmt_PutI ( IRPutI* details );
sewardjdd40fdf2006-12-24 02:20:24 +00002397extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
sewardje768e922009-11-26 17:17:37 +00002398extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
sewardje9d8a262009-07-01 08:06:34 +00002399extern IRStmt* IRStmt_CAS ( IRCAS* details );
sewardje768e922009-11-26 17:17:37 +00002400extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
2401 IRExpr* addr, IRExpr* storedata );
sewardj5a9ffab2005-05-12 17:55:01 +00002402extern IRStmt* IRStmt_Dirty ( IRDirty* details );
sewardjc4356f02007-11-09 21:15:04 +00002403extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
sewardjc6f970f2012-04-02 21:54:49 +00002404extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2405 Int offsIP );
sewardjec6ad592004-06-20 12:26:53 +00002406
sewardj57c10c82006-11-15 02:57:05 +00002407/* Deep-copy an IRStmt. */
sewardjdd40fdf2006-12-24 02:20:24 +00002408extern IRStmt* deepCopyIRStmt ( IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002409
sewardj57c10c82006-11-15 02:57:05 +00002410/* Pretty-print an IRStmt. */
sewardj35421a32004-07-05 13:12:34 +00002411extern void ppIRStmt ( IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +00002412
2413
sewardje539a402004-07-14 18:24:17 +00002414/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +00002415
sewardj57c10c82006-11-15 02:57:05 +00002416/* Type environments: a bunch of statements, expressions, etc, are
2417 incomplete without an environment indicating the type of each
2418 IRTemp. So this provides one. IR temporaries are really just
2419 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2420 them.
sewardjc97096c2004-06-30 09:28:04 +00002421*/
2422typedef
sewardjc97096c2004-06-30 09:28:04 +00002423 struct {
sewardje539a402004-07-14 18:24:17 +00002424 IRType* types;
2425 Int types_size;
2426 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +00002427 }
2428 IRTypeEnv;
2429
sewardj57c10c82006-11-15 02:57:05 +00002430/* Obtain a new IRTemp */
2431extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2432
2433/* Deep-copy a type environment */
sewardjdd40fdf2006-12-24 02:20:24 +00002434extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
sewardj695cff92004-10-13 14:50:14 +00002435
sewardj57c10c82006-11-15 02:57:05 +00002436/* Pretty-print a type environment */
sewardj35421a32004-07-05 13:12:34 +00002437extern void ppIRTypeEnv ( IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +00002438
sewardjec6ad592004-06-20 12:26:53 +00002439
sewardjdd40fdf2006-12-24 02:20:24 +00002440/* Code blocks, which in proper compiler terminology are superblocks
2441 (single entry, multiple exit code sequences) contain:
2442
sewardj57c10c82006-11-15 02:57:05 +00002443 - A table giving a type for each temp (the "type environment")
sewardjd7cb8532004-08-17 23:59:23 +00002444 - An expandable array of statements
sewardje539a402004-07-14 18:24:17 +00002445 - An expression of type 32 or 64 bits, depending on the
sewardjdd40fdf2006-12-24 02:20:24 +00002446 guest's word size, indicating the next destination if the block
2447 executes all the way to the end, without a side exit
sewardjd7cb8532004-08-17 23:59:23 +00002448 - An indication of any special actions (JumpKind) needed
2449 for this final jump.
sewardjc6f970f2012-04-02 21:54:49 +00002450 - Offset of the IP field in the guest state. This will be
2451 updated before the final jump is done.
sewardj57c10c82006-11-15 02:57:05 +00002452
sewardjdd40fdf2006-12-24 02:20:24 +00002453 "IRSB" stands for "IR Super Block".
sewardjec6ad592004-06-20 12:26:53 +00002454*/
sewardjac6b7122004-06-27 01:03:57 +00002455typedef
sewardj57c10c82006-11-15 02:57:05 +00002456 struct {
sewardjc97096c2004-06-30 09:28:04 +00002457 IRTypeEnv* tyenv;
sewardjd7cb8532004-08-17 23:59:23 +00002458 IRStmt** stmts;
2459 Int stmts_size;
2460 Int stmts_used;
sewardje539a402004-07-14 18:24:17 +00002461 IRExpr* next;
2462 IRJumpKind jumpkind;
sewardjc6f970f2012-04-02 21:54:49 +00002463 Int offsIP;
sewardjac6b7122004-06-27 01:03:57 +00002464 }
sewardjdd40fdf2006-12-24 02:20:24 +00002465 IRSB;
sewardjec6ad592004-06-20 12:26:53 +00002466
sewardjdd40fdf2006-12-24 02:20:24 +00002467/* Allocate a new, uninitialised IRSB */
2468extern IRSB* emptyIRSB ( void );
sewardj695cff92004-10-13 14:50:14 +00002469
sewardjdd40fdf2006-12-24 02:20:24 +00002470/* Deep-copy an IRSB */
2471extern IRSB* deepCopyIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002472
sewardjdd40fdf2006-12-24 02:20:24 +00002473/* Deep-copy an IRSB, except for the statements list, which set to be
sewardj6f2f2832006-11-24 23:32:55 +00002474 a new, empty, list of statements. */
sewardjdd40fdf2006-12-24 02:20:24 +00002475extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
sewardj57c10c82006-11-15 02:57:05 +00002476
sewardjdd40fdf2006-12-24 02:20:24 +00002477/* Pretty-print an IRSB */
2478extern void ppIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002479
sewardjdd40fdf2006-12-24 02:20:24 +00002480/* Append an IRStmt to an IRSB */
2481extern void addStmtToIRSB ( IRSB*, IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002482
2483
sewardjec6ad592004-06-20 12:26:53 +00002484/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +00002485/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +00002486/*---------------------------------------------------------------*/
2487
sewardjc97096c2004-06-30 09:28:04 +00002488/* For messing with IR type environments */
sewardjd7cb8532004-08-17 23:59:23 +00002489extern IRTypeEnv* emptyIRTypeEnv ( void );
sewardjec6ad592004-06-20 12:26:53 +00002490
sewardjc97096c2004-06-30 09:28:04 +00002491/* What is the type of this expression? */
sewardj6efd4a12004-07-15 03:54:23 +00002492extern IRType typeOfIRConst ( IRConst* );
sewardj17442fe2004-09-20 14:54:28 +00002493extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp );
sewardj6efd4a12004-07-15 03:54:23 +00002494extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00002495
sewardj35439212004-07-14 22:36:10 +00002496/* Sanity check a BB of IR */
sewardjdd40fdf2006-12-24 02:20:24 +00002497extern void sanityCheckIRSB ( IRSB* bb,
sewardjb9230752004-12-29 19:25:06 +00002498 HChar* caller,
2499 Bool require_flatness,
2500 IRType guest_word_size );
sewardjcf787902004-11-03 09:08:33 +00002501extern Bool isFlatIRStmt ( IRStmt* );
sewardjec6ad592004-06-20 12:26:53 +00002502
sewardj6d2638e2004-07-15 09:38:27 +00002503/* Is this any value actually in the enumeration 'IRType' ? */
sewardj496a58d2005-03-20 18:44:44 +00002504extern Bool isPlausibleIRType ( IRType ty );
sewardj6d2638e2004-07-15 09:38:27 +00002505
sewardj887a11a2004-07-05 17:26:47 +00002506#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +00002507
2508
2509/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +00002510/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +00002511/*---------------------------------------------------------------*/