blob: fcac0430a92f4de45344b300dfceab1bb0edd63b [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
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2004-2017 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 {
sewardjcfe046e2013-01-17 14:23:53 +0000221 Ity_INVALID=0x1100,
sewardjc4356f02007-11-09 21:15:04 +0000222 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 */
sewardj3738bfc2015-03-30 08:50:27 +0000228 Ity_F16, /* 16 bit float */
sewardjc9a43662004-11-30 18:51:59 +0000229 Ity_F32, /* IEEE 754 float */
230 Ity_F64, /* IEEE 754 double */
sewardjc6bbd472012-04-02 10:20:48 +0000231 Ity_D32, /* 32-bit Decimal floating point */
232 Ity_D64, /* 64-bit Decimal floating point */
233 Ity_D128, /* 128-bit Decimal floating point */
sewardj2019a972011-03-07 16:04:07 +0000234 Ity_F128, /* 128-bit floating point; implementation defined */
sewardjc4530ae2012-05-21 10:18:49 +0000235 Ity_V128, /* 128-bit SIMD */
236 Ity_V256 /* 256-bit SIMD */
sewardjd1725d12004-08-12 20:46:53 +0000237 }
sewardje3d0d2e2004-06-27 10:42:44 +0000238 IRType;
239
sewardj57c10c82006-11-15 02:57:05 +0000240/* Pretty-print an IRType */
sewardj35421a32004-07-05 13:12:34 +0000241extern void ppIRType ( IRType );
sewardj57c10c82006-11-15 02:57:05 +0000242
243/* Get the size (in bytes) of an IRType */
244extern Int sizeofIRType ( IRType );
sewardje3d0d2e2004-06-27 10:42:44 +0000245
sewardj7d009132014-02-20 17:43:38 +0000246/* Translate 1/2/4/8 into Ity_I{8,16,32,64} respectively. Asserts on
247 any other input. */
248extern IRType integerIRTypeOfSize ( Int szB );
249
sewardjc97096c2004-06-30 09:28:04 +0000250
sewardjaf1ceca2005-06-30 23:31:27 +0000251/* ------------------ Endianness ------------------ */
252
sewardj57c10c82006-11-15 02:57:05 +0000253/* IREndness is used in load IRExprs and store IRStmts. */
sewardjaf1ceca2005-06-30 23:31:27 +0000254typedef
255 enum {
sewardjcfe046e2013-01-17 14:23:53 +0000256 Iend_LE=0x1200, /* little endian */
sewardjc4356f02007-11-09 21:15:04 +0000257 Iend_BE /* big endian */
sewardjaf1ceca2005-06-30 23:31:27 +0000258 }
259 IREndness;
260
261
sewardjc97096c2004-06-30 09:28:04 +0000262/* ------------------ Constants ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000263
sewardj57c10c82006-11-15 02:57:05 +0000264/* IRConsts are used within 'Const' and 'Exit' IRExprs. */
265
266/* The various kinds of constant. */
sewardjac6b7122004-06-27 01:03:57 +0000267typedef
sewardjc9a43662004-11-30 18:51:59 +0000268 enum {
sewardjcfe046e2013-01-17 14:23:53 +0000269 Ico_U1=0x1300,
sewardjc9a43662004-11-30 18:51:59 +0000270 Ico_U8,
271 Ico_U16,
272 Ico_U32,
273 Ico_U64,
sewardj2019a972011-03-07 16:04:07 +0000274 Ico_F32, /* 32-bit IEEE754 floating */
275 Ico_F32i, /* 32-bit unsigned int to be interpreted literally
276 as a IEEE754 single value. */
sewardj1e6ad742004-12-02 16:16:11 +0000277 Ico_F64, /* 64-bit IEEE754 floating */
278 Ico_F64i, /* 64-bit unsigned int to be interpreted literally
279 as a IEEE754 double value. */
sewardj37a505b2012-06-29 15:28:24 +0000280 Ico_V128, /* 128-bit restricted vector constant, with 1 bit
sewardj57c10c82006-11-15 02:57:05 +0000281 (repeated 8 times) for each of the 16 x 1-byte lanes */
sewardj37a505b2012-06-29 15:28:24 +0000282 Ico_V256 /* 256-bit restricted vector constant, with 1 bit
283 (repeated 8 times) for each of the 32 x 1-byte lanes */
sewardj207557a2004-08-27 12:00:18 +0000284 }
sewardjac6b7122004-06-27 01:03:57 +0000285 IRConstTag;
286
sewardj57c10c82006-11-15 02:57:05 +0000287/* A constant. Stored as a tagged union. 'tag' indicates what kind of
288 constant this is. 'Ico' is the union that holds the fields. If an
289 IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
290 and its value can be accessed with 'c.Ico.U32'. */
sewardjac6b7122004-06-27 01:03:57 +0000291typedef
sewardje3d0d2e2004-06-27 10:42:44 +0000292 struct _IRConst {
sewardjac6b7122004-06-27 01:03:57 +0000293 IRConstTag tag;
294 union {
sewardjba999312004-11-15 15:21:17 +0000295 Bool U1;
sewardjc97096c2004-06-30 09:28:04 +0000296 UChar U8;
297 UShort U16;
298 UInt U32;
299 ULong U64;
sewardj2019a972011-03-07 16:04:07 +0000300 Float F32;
301 UInt F32i;
sewardja58ea662004-08-15 03:12:41 +0000302 Double F64;
sewardj17442fe2004-09-20 14:54:28 +0000303 ULong F64i;
sewardj57c10c82006-11-15 02:57:05 +0000304 UShort V128; /* 16-bit value; see Ico_V128 comment above */
sewardj37a505b2012-06-29 15:28:24 +0000305 UInt V256; /* 32-bit value; see Ico_V256 comment above */
sewardjac6b7122004-06-27 01:03:57 +0000306 } Ico;
307 }
308 IRConst;
sewardjec6ad592004-06-20 12:26:53 +0000309
sewardj57c10c82006-11-15 02:57:05 +0000310/* IRConst constructors */
sewardjba999312004-11-15 15:21:17 +0000311extern IRConst* IRConst_U1 ( Bool );
sewardj17442fe2004-09-20 14:54:28 +0000312extern IRConst* IRConst_U8 ( UChar );
313extern IRConst* IRConst_U16 ( UShort );
314extern IRConst* IRConst_U32 ( UInt );
315extern IRConst* IRConst_U64 ( ULong );
sewardj2019a972011-03-07 16:04:07 +0000316extern IRConst* IRConst_F32 ( Float );
317extern IRConst* IRConst_F32i ( UInt );
sewardj17442fe2004-09-20 14:54:28 +0000318extern IRConst* IRConst_F64 ( Double );
319extern IRConst* IRConst_F64i ( ULong );
sewardj1e6ad742004-12-02 16:16:11 +0000320extern IRConst* IRConst_V128 ( UShort );
sewardj37a505b2012-06-29 15:28:24 +0000321extern IRConst* IRConst_V256 ( UInt );
sewardjec6ad592004-06-20 12:26:53 +0000322
sewardj57c10c82006-11-15 02:57:05 +0000323/* Deep-copy an IRConst */
florian0b70efa2014-09-21 21:53:39 +0000324extern IRConst* deepCopyIRConst ( const IRConst* );
sewardj695cff92004-10-13 14:50:14 +0000325
sewardj57c10c82006-11-15 02:57:05 +0000326/* Pretty-print an IRConst */
florian0b70efa2014-09-21 21:53:39 +0000327extern void ppIRConst ( const IRConst* );
sewardj57c10c82006-11-15 02:57:05 +0000328
329/* Compare two IRConsts for equality */
florian0b70efa2014-09-21 21:53:39 +0000330extern Bool eqIRConst ( const IRConst*, const IRConst* );
sewardjc97096c2004-06-30 09:28:04 +0000331
332
sewardj8ea867b2004-10-30 19:03:02 +0000333/* ------------------ Call targets ------------------ */
334
335/* Describes a helper function to call. The name part is purely for
sewardj77352542004-10-30 20:39:01 +0000336 pretty printing and not actually used. regparms=n tells the back
sewardj8ea867b2004-10-30 19:03:02 +0000337 end that the callee has been declared
sewardj03d91142011-03-14 12:35:18 +0000338 "__attribute__((regparm(n)))", although indirectly using the
339 VEX_REGPARM(n) macro. On some targets (x86) the back end will need
340 to construct a non-standard sequence to call a function declared
341 like this.
sewardj43c56462004-11-06 12:17:57 +0000342
343 mcx_mask is a sop to Memcheck. It indicates which args should be
344 considered 'always defined' when lazily computing definedness of
345 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to
346 args[1], etc. If a bit is set, the corresponding arg is excluded
347 (hence "x" in "mcx") from definedness checking.
348*/
sewardj8ea867b2004-10-30 19:03:02 +0000349
350typedef
351 struct {
florian1ff47562012-10-21 02:09:51 +0000352 Int regparms;
353 const HChar* name;
354 void* addr;
355 UInt mcx_mask;
sewardj8ea867b2004-10-30 19:03:02 +0000356 }
357 IRCallee;
358
sewardj57c10c82006-11-15 02:57:05 +0000359/* Create an IRCallee. */
florian1ff47562012-10-21 02:09:51 +0000360extern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr );
sewardj8ea867b2004-10-30 19:03:02 +0000361
sewardj57c10c82006-11-15 02:57:05 +0000362/* Deep-copy an IRCallee. */
florian0b70efa2014-09-21 21:53:39 +0000363extern IRCallee* deepCopyIRCallee ( const IRCallee* );
sewardj8ea867b2004-10-30 19:03:02 +0000364
sewardj57c10c82006-11-15 02:57:05 +0000365/* Pretty-print an IRCallee. */
florian0b70efa2014-09-21 21:53:39 +0000366extern void ppIRCallee ( const IRCallee* );
sewardj8ea867b2004-10-30 19:03:02 +0000367
368
sewardj2d3f77c2004-09-22 23:49:09 +0000369/* ------------------ Guest state arrays ------------------ */
370
sewardj57c10c82006-11-15 02:57:05 +0000371/* This describes a section of the guest state that we want to
372 be able to index at run time, so as to be able to describe
373 indexed or rotating register files on the guest. */
sewardj2d3f77c2004-09-22 23:49:09 +0000374typedef
375 struct {
sewardj57c10c82006-11-15 02:57:05 +0000376 Int base; /* guest state offset of start of indexed area */
377 IRType elemTy; /* type of each element in the indexed area */
378 Int nElems; /* number of elements in the indexed area */
sewardj2d3f77c2004-09-22 23:49:09 +0000379 }
sewardjdd40fdf2006-12-24 02:20:24 +0000380 IRRegArray;
sewardj2d3f77c2004-09-22 23:49:09 +0000381
sewardjdd40fdf2006-12-24 02:20:24 +0000382extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
sewardj2d3f77c2004-09-22 23:49:09 +0000383
florian0b70efa2014-09-21 21:53:39 +0000384extern IRRegArray* deepCopyIRRegArray ( const IRRegArray* );
sewardj695cff92004-10-13 14:50:14 +0000385
florian0b70efa2014-09-21 21:53:39 +0000386extern void ppIRRegArray ( const IRRegArray* );
387extern Bool eqIRRegArray ( const IRRegArray*, const IRRegArray* );
sewardj2d3f77c2004-09-22 23:49:09 +0000388
389
sewardjc97096c2004-06-30 09:28:04 +0000390/* ------------------ Temporaries ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000391
sewardj57c10c82006-11-15 02:57:05 +0000392/* This represents a temporary, eg. t1. The IR optimiser relies on the
393 fact that IRTemps are 32-bit ints. Do not change them to be ints of
394 any other size. */
sewardjfbcaf332004-07-08 01:46:01 +0000395typedef UInt IRTemp;
sewardjec6ad592004-06-20 12:26:53 +0000396
sewardj57c10c82006-11-15 02:57:05 +0000397/* Pretty-print an IRTemp. */
sewardj35421a32004-07-05 13:12:34 +0000398extern void ppIRTemp ( IRTemp );
sewardjec6ad592004-06-20 12:26:53 +0000399
sewardj92d168d2004-11-15 14:22:12 +0000400#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
sewardjfbcaf332004-07-08 01:46:01 +0000401
sewardjc97096c2004-06-30 09:28:04 +0000402
sewardj40c80262006-02-08 19:30:46 +0000403/* --------------- Primops (arity 1,2,3 and 4) --------------- */
sewardjec6ad592004-06-20 12:26:53 +0000404
sewardj57c10c82006-11-15 02:57:05 +0000405/* Primitive operations that are used in Unop, Binop, Triop and Qop
406 IRExprs. Once we take into account integer, floating point and SIMD
407 operations of all the different sizes, there are quite a lot of them.
408 Most instructions supported by the architectures that Vex supports
409 (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid)
410 are not; they are instead handled with dirty helpers that emulate
411 their functionality. Such obscure ones are thus not directly visible
412 in the IR, but their effects on guest state (memory and registers)
413 are made visible via the annotations in IRDirty structures.
414*/
sewardjac6b7122004-06-27 01:03:57 +0000415typedef
sewardj41f43bc2004-07-08 14:23:22 +0000416 enum {
sewardj71a35e72005-05-03 12:20:15 +0000417 /* -- Do not change this ordering. The IR generators rely on
418 (eg) Iop_Add64 == IopAdd8 + 3. -- */
419
sewardjcfe046e2013-01-17 14:23:53 +0000420 Iop_INVALID=0x1400,
sewardj66de2272004-07-16 21:19:05 +0000421 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
sewardj41f43bc2004-07-08 14:23:22 +0000422 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
sewardj41f43bc2004-07-08 14:23:22 +0000423 /* Signless mul. MullS/MullU is elsewhere. */
424 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
425 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
426 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
427 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
428 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
429 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
430 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
sewardje90ad6a2004-07-10 19:02:10 +0000431 /* Integer comparisons. */
432 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
433 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
sewardj41f43bc2004-07-08 14:23:22 +0000434 /* Tags for unary ops */
435 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
sewardj71a35e72005-05-03 12:20:15 +0000436
sewardj1fb8c922009-07-12 12:56:53 +0000437 /* Exactly like CmpEQ8/16/32/64, but carrying the additional
438 hint that these compute the success/failure of a CAS
439 operation, and hence are almost certainly applied to two
440 copies of the same value, which in turn has implications for
441 Memcheck's instrumentation. */
442 Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
443 Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
444
sewardje13074c2012-11-08 10:57:08 +0000445 /* Exactly like CmpNE8/16/32/64, but carrying the additional
446 hint that these needs expensive definedness tracking. */
447 Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
448
sewardj71a35e72005-05-03 12:20:15 +0000449 /* -- Ordering not important after here. -- */
450
sewardj9690d922004-07-14 01:39:17 +0000451 /* Widening multiplies */
sewardj9b967672005-02-08 11:13:09 +0000452 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
453 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
sewardj8f3debf2004-09-08 23:42:23 +0000454
sewardjce646f22004-08-31 23:55:54 +0000455 /* Wierdo integer stuff */
sewardjf53b7352005-04-06 20:01:56 +0000456 Iop_Clz64, Iop_Clz32, /* count leading zeroes */
457 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
458 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
459 zero. You must ensure they are never given a zero argument.
sewardj8f3debf2004-09-08 23:42:23 +0000460 */
461
sewardjb51f0f42005-07-18 11:38:02 +0000462 /* Standard integer comparisons */
sewardj98540072005-04-26 01:52:01 +0000463 Iop_CmpLT32S, Iop_CmpLT64S,
464 Iop_CmpLE32S, Iop_CmpLE64S,
465 Iop_CmpLT32U, Iop_CmpLT64U,
466 Iop_CmpLE32U, Iop_CmpLE64U,
sewardj343b9d02005-01-31 18:08:45 +0000467
sewardj0033ddc2005-04-26 23:34:34 +0000468 /* As a sop to Valgrind-Memcheck, the following are useful. */
469 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
sewardjeb17e492007-08-25 23:07:44 +0000470 Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
471 Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
sewardj478646f2008-05-01 20:13:04 +0000472 Iop_Max32U, /* unsigned max */
sewardj0033ddc2005-04-26 23:34:34 +0000473
sewardj57c10c82006-11-15 02:57:05 +0000474 /* PowerPC-style 3-way integer comparisons. Without them it is
475 difficult to simulate PPC efficiently.
sewardjb51f0f42005-07-18 11:38:02 +0000476 op(x,y) | x < y = 0x8 else
477 | x > y = 0x4 else
478 | x == y = 0x2
479 */
cerion2831b002005-11-30 19:55:22 +0000480 Iop_CmpORD32U, Iop_CmpORD64U,
481 Iop_CmpORD32S, Iop_CmpORD64S,
sewardjb51f0f42005-07-18 11:38:02 +0000482
sewardj9690d922004-07-14 01:39:17 +0000483 /* Division */
sewardj8f3debf2004-09-08 23:42:23 +0000484 /* TODO: clarify semantics wrt rounding, negative values, whatever */
cerion5c8a0cb2005-02-03 13:59:46 +0000485 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod)
486 Iop_DivS32, // ditto, signed
cerionf0de28c2005-12-13 20:21:11 +0000487 Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod)
488 Iop_DivS64, // ditto, signed
sewardj8b1715b2014-01-21 16:33:51 +0000489 Iop_DivU64E, // :: I64,I64 -> I64 (dividend is 64-bit arg (hi)
490 // concat with 64 0's (low))
sewardje71e56a2011-09-05 12:11:06 +0000491 Iop_DivS64E, // ditto, signed
sewardj8b1715b2014-01-21 16:33:51 +0000492 Iop_DivU32E, // :: I32,I32 -> I32 (dividend is 32-bit arg (hi)
493 // concat with 32 0's (low))
sewardje71e56a2011-09-05 12:11:06 +0000494 Iop_DivS32E, // ditto, signed
cerion5c8a0cb2005-02-03 13:59:46 +0000495
sewardj9690d922004-07-14 01:39:17 +0000496 Iop_DivModU64to32, // :: I64,I32 -> I64
497 // of which lo half is div and hi half is mod
498 Iop_DivModS64to32, // ditto, signed
sewardj89d4e982004-09-12 19:14:46 +0000499
sewardj343b9d02005-01-31 18:08:45 +0000500 Iop_DivModU128to64, // :: V128,I64 -> V128
501 // of which lo half is div and hi half is mod
502 Iop_DivModS128to64, // ditto, signed
503
sewardj2019a972011-03-07 16:04:07 +0000504 Iop_DivModS64to64, // :: I64,I64 -> I128
505 // of which lo half is div and hi half is mod
506
sewardj0033ddc2005-04-26 23:34:34 +0000507 /* Integer conversions. Some of these are redundant (eg
508 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
509 having a complete set reduces the typical dynamic size of IR
510 and makes the instruction selectors easier to write. */
511
sewardj9690d922004-07-14 01:39:17 +0000512 /* Widening conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000513 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64,
514 Iop_16Uto32, Iop_16Uto64,
515 Iop_32Uto64,
516 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64,
517 Iop_16Sto32, Iop_16Sto64,
518 Iop_32Sto64,
519
sewardja2384712004-07-29 14:36:40 +0000520 /* Narrowing conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000521 Iop_64to8, Iop_32to8, Iop_64to16,
sewardjb81f8b32004-07-30 10:17:50 +0000522 /* 8 <-> 16 bit conversions */
523 Iop_16to8, // :: I16 -> I8, low half
524 Iop_16HIto8, // :: I16 -> I8, high half
525 Iop_8HLto16, // :: (I8,I8) -> I16
sewardj8c7f1ab2004-07-29 20:31:09 +0000526 /* 16 <-> 32 bit conversions */
527 Iop_32to16, // :: I32 -> I16, low half
528 Iop_32HIto16, // :: I32 -> I16, high half
529 Iop_16HLto32, // :: (I16,I16) -> I32
sewardj9690d922004-07-14 01:39:17 +0000530 /* 32 <-> 64 bit conversions */
sewardj8c7f1ab2004-07-29 20:31:09 +0000531 Iop_64to32, // :: I64 -> I32, low half
sewardj9690d922004-07-14 01:39:17 +0000532 Iop_64HIto32, // :: I64 -> I32, high half
533 Iop_32HLto64, // :: (I32,I32) -> I64
sewardj9b967672005-02-08 11:13:09 +0000534 /* 64 <-> 128 bit conversions */
535 Iop_128to64, // :: I128 -> I64, low half
536 Iop_128HIto64, // :: I128 -> I64, high half
537 Iop_64HLto128, // :: (I64,I64) -> I128
sewardjcf780b42004-07-13 18:42:17 +0000538 /* 1-bit stuff */
sewardj6e797c52004-10-13 15:20:17 +0000539 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */
sewardj84ff0652004-08-23 16:16:08 +0000540 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
sewardj291a7e82005-04-27 11:42:44 +0000541 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
542 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
sewardj84ff0652004-08-23 16:16:08 +0000543 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
sewardj291a7e82005-04-27 11:42:44 +0000544 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
sewardjfd332772004-11-09 16:01:40 +0000545 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */
sewardj8eda6302004-11-05 01:55:46 +0000546 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
sewardjcf787902004-11-03 09:08:33 +0000547 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
sewardjb5874aa2004-11-04 16:57:50 +0000548 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
sewardj8f3debf2004-09-08 23:42:23 +0000549
sewardjbaf971a2006-01-27 15:09:35 +0000550 /* ------ Floating point. We try to be IEEE754 compliant. ------ */
sewardj8f3debf2004-09-08 23:42:23 +0000551
sewardjb183b852006-02-03 16:08:03 +0000552 /* --- Simple stuff as mandated by 754. --- */
sewardjcfded9a2004-09-09 11:44:16 +0000553
sewardjb183b852006-02-03 16:08:03 +0000554 /* Binary operations, with rounding. */
555 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
556 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
sewardj52ace3e2004-09-11 17:10:08 +0000557
sewardj6c299f32009-12-31 18:00:12 +0000558 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
559 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
560
sewardjb183b852006-02-03 16:08:03 +0000561 /* Variants of the above which produce a 64-bit result but which
562 round their result to a IEEE float range first. */
563 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
564 Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
sewardj52ace3e2004-09-11 17:10:08 +0000565
sewardjb183b852006-02-03 16:08:03 +0000566 /* Unary operations, without rounding. */
567 /* :: F64 -> F64 */
568 Iop_NegF64, Iop_AbsF64,
sewardj8f3debf2004-09-08 23:42:23 +0000569
sewardj6c299f32009-12-31 18:00:12 +0000570 /* :: F32 -> F32 */
571 Iop_NegF32, Iop_AbsF32,
572
sewardjb183b852006-02-03 16:08:03 +0000573 /* Unary operations, with rounding. */
574 /* :: IRRoundingMode(I32) x F64 -> F64 */
florian6d522282012-08-21 22:15:19 +0000575 Iop_SqrtF64,
sewardjbaf971a2006-01-27 15:09:35 +0000576
sewardj6c299f32009-12-31 18:00:12 +0000577 /* :: IRRoundingMode(I32) x F32 -> F32 */
578 Iop_SqrtF32,
579
sewardj8f3debf2004-09-08 23:42:23 +0000580 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
sewardj883b00b2004-09-11 09:30:24 +0000581 0x45 Unordered
sewardj8f3debf2004-09-08 23:42:23 +0000582 0x01 LT
583 0x00 GT
sewardj883b00b2004-09-11 09:30:24 +0000584 0x40 EQ
sewardj8f3debf2004-09-08 23:42:23 +0000585 This just happens to be the Intel encoding. The values
586 are recorded in the type IRCmpF64Result.
587 */
sewardj6c299f32009-12-31 18:00:12 +0000588 /* :: F64 x F64 -> IRCmpF64Result(I32) */
sewardj8f3debf2004-09-08 23:42:23 +0000589 Iop_CmpF64,
sewardj2019a972011-03-07 16:04:07 +0000590 Iop_CmpF32,
591 Iop_CmpF128,
sewardj8f3debf2004-09-08 23:42:23 +0000592
sewardj3bca9062004-12-04 14:36:09 +0000593 /* --- Int to/from FP conversions. --- */
sewardjb183b852006-02-03 16:08:03 +0000594
sewardj6c299f32009-12-31 18:00:12 +0000595 /* For the most part, these take a first argument :: Ity_I32 (as
596 IRRoundingMode) which is an indication of the rounding mode
597 to use, as per the following encoding ("the standard
598 encoding"):
sewardj8f3debf2004-09-08 23:42:23 +0000599 00b to nearest (the default)
600 01b to -infinity
601 10b to +infinity
602 11b to zero
603 This just happens to be the Intel encoding. For reference only,
604 the PPC encoding is:
605 00b to nearest (the default)
606 01b to zero
607 10b to +infinity
608 11b to -infinity
609 Any PPC -> IR front end will have to translate these PPC
sewardj6c299f32009-12-31 18:00:12 +0000610 encodings, as encoded in the guest state, to the standard
611 encodings, to pass to the primops.
612 For reference only, the ARM VFP encoding is:
613 00b to nearest
614 01b to +infinity
615 10b to -infinity
616 11b to zero
617 Again, this will have to be converted to the standard encoding
618 to pass to primops.
sewardj8f3debf2004-09-08 23:42:23 +0000619
620 If one of these conversions gets an out-of-range condition,
621 or a NaN, as an argument, the result is host-defined. On x86
sewardj6c299f32009-12-31 18:00:12 +0000622 the "integer indefinite" value 0x80..00 is produced. On PPC
623 it is either 0x80..00 or 0x7F..FF depending on the sign of
624 the argument.
625
626 On ARMvfp, when converting to a signed integer result, the
627 overflow result is 0x80..00 for negative args and 0x7F..FF
628 for positive args. For unsigned integer results it is
629 0x00..00 and 0xFF..FF respectively.
sewardj52ace3e2004-09-11 17:10:08 +0000630
sewardj3bca9062004-12-04 14:36:09 +0000631 Rounding is required whenever the destination type cannot
632 represent exactly all values of the source type.
633 */
sewardj6c299f32009-12-31 18:00:12 +0000634 Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
635 Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
636 Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
sewardj4aa412a2011-07-24 14:13:21 +0000637 Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
sewardj3bca9062004-12-04 14:36:09 +0000638
sewardj6c299f32009-12-31 18:00:12 +0000639 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
sewardj3bca9062004-12-04 14:36:09 +0000640
sewardj6c299f32009-12-31 18:00:12 +0000641 Iop_I32StoF64, /* signed I32 -> F64 */
642 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
sewardj66d5ef22011-04-15 11:55:00 +0000643 Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
644 Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
sewardj6c299f32009-12-31 18:00:12 +0000645
florian1c8f7ff2012-09-01 00:12:11 +0000646 Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */
sewardj6c299f32009-12-31 18:00:12 +0000647 Iop_I32UtoF64, /* unsigned I32 -> F64 */
648
sewardj2019a972011-03-07 16:04:07 +0000649 Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
650 Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
florian1c8f7ff2012-09-01 00:12:11 +0000651 Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */
652 Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */
sewardj2019a972011-03-07 16:04:07 +0000653
sewardj2019a972011-03-07 16:04:07 +0000654 Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
655 Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
656
sewardj6c299f32009-12-31 18:00:12 +0000657 /* Conversion between floating point formats */
sewardj3bca9062004-12-04 14:36:09 +0000658 Iop_F32toF64, /* F32 -> F64 */
659 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */
sewardj4cb918d2004-12-03 19:43:31 +0000660
sewardj17442fe2004-09-20 14:54:28 +0000661 /* Reinterpretation. Take an F64 and produce an I64 with
662 the same bit pattern, or vice versa. */
sewardjc9a43662004-11-30 18:51:59 +0000663 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
sewardjfc1b5412007-01-09 15:20:07 +0000664 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
sewardjb183b852006-02-03 16:08:03 +0000665
sewardj2019a972011-03-07 16:04:07 +0000666 /* Support for 128-bit floating point */
667 Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
668 Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
669 Iop_F128LOtoF64,/* F128 -> low half of F128 into a F64 register */
670
671 /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
672 Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
Elliott Hughesa0664b92017-04-18 17:46:52 -0700673 Iop_MAddF128, // (A * B) + C
674 Iop_MSubF128, // (A * B) - C
675 Iop_NegMAddF128, // -((A * B) + C)
676 Iop_NegMSubF128, // -((A * B) - C)
sewardj2019a972011-03-07 16:04:07 +0000677
678 /* :: F128 -> F128 */
679 Iop_NegF128, Iop_AbsF128,
680
681 /* :: IRRoundingMode(I32) x F128 -> F128 */
682 Iop_SqrtF128,
683
684 Iop_I32StoF128, /* signed I32 -> F128 */
685 Iop_I64StoF128, /* signed I64 -> F128 */
florian1c8f7ff2012-09-01 00:12:11 +0000686 Iop_I32UtoF128, /* unsigned I32 -> F128 */
687 Iop_I64UtoF128, /* unsigned I64 -> F128 */
sewardj2019a972011-03-07 16:04:07 +0000688 Iop_F32toF128, /* F32 -> F128 */
689 Iop_F64toF128, /* F64 -> F128 */
690
691 Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32 */
692 Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64 */
florian1c8f7ff2012-09-01 00:12:11 +0000693 Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32 */
694 Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64 */
Elliott Hughesa0664b92017-04-18 17:46:52 -0700695 Iop_F128toI128S,/* IRRoundingMode(I32) x F128 -> signed I128 */
sewardj2019a972011-03-07 16:04:07 +0000696 Iop_F128toF64, /* IRRoundingMode(I32) x F128 -> F64 */
697 Iop_F128toF32, /* IRRoundingMode(I32) x F128 -> F32 */
Elliott Hughesa0664b92017-04-18 17:46:52 -0700698 Iop_RndF128, /* IRRoundingMode(I32) x F128 -> F128 */
699
700 /* Truncate to the specified value, source and result
701 * are stroed in a F128 register.
702 */
703 Iop_TruncF128toI32S, /* truncate F128 -> I32 */
704 Iop_TruncF128toI32U, /* truncate F128 -> I32 */
705 Iop_TruncF128toI64U, /* truncate F128 -> I64 */
706 Iop_TruncF128toI64S, /* truncate F128 -> I64 */
sewardj2019a972011-03-07 16:04:07 +0000707
sewardjb183b852006-02-03 16:08:03 +0000708 /* --- guest x86/amd64 specifics, not mandated by 754. --- */
709
710 /* Binary ops, with rounding. */
711 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
712 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
713 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
714 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
715 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */
716 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
717 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */
718 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
719 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
720 /* Note that on x86 guest, PRem1{C3210} has the same behaviour
721 as the IEEE mandated RemF64, except it is limited in the
722 range of its operand. Hence the partialness. */
723
724 /* Unary ops, with rounding. */
725 /* :: IRRoundingMode(I32) x F64 -> F64 */
726 Iop_SinF64, /* FSIN */
727 Iop_CosF64, /* FCOS */
728 Iop_TanF64, /* FTAN */
729 Iop_2xm1F64, /* (2^arg - 1.0) */
florianb53f9482015-09-05 20:35:52 +0000730 Iop_RoundF128toInt, /* F128 value to nearest integral value (still
731 as F128) */
sewardjb183b852006-02-03 16:08:03 +0000732 Iop_RoundF64toInt, /* F64 value to nearest integral value (still
733 as F64) */
sewardjd15b5972010-06-27 09:06:34 +0000734 Iop_RoundF32toInt, /* F32 value to nearest integral value (still
735 as F32) */
sewardjb183b852006-02-03 16:08:03 +0000736
sewardj2019a972011-03-07 16:04:07 +0000737 /* --- guest s390 specifics, not mandated by 754. --- */
738
739 /* Fused multiply-add/sub */
740 /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
florian5906a6b2012-10-16 02:53:33 +0000741 (computes arg2 * arg3 +/- arg4) */
sewardj2019a972011-03-07 16:04:07 +0000742 Iop_MAddF32, Iop_MSubF32,
743
sewardjb183b852006-02-03 16:08:03 +0000744 /* --- guest ppc32/64 specifics, not mandated by 754. --- */
745
sewardj40c80262006-02-08 19:30:46 +0000746 /* Ternary operations, with rounding. */
747 /* Fused multiply-add/sub, with 112-bit intermediate
sewardj2019a972011-03-07 16:04:07 +0000748 precision for ppc.
749 Also used to implement fused multiply-add/sub for s390. */
sewardj40c80262006-02-08 19:30:46 +0000750 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
751 (computes arg2 * arg3 +/- arg4) */
752 Iop_MAddF64, Iop_MSubF64,
753
754 /* Variants of the above which produce a 64-bit result but which
755 round their result to a IEEE float range first. */
756 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
757 Iop_MAddF64r32, Iop_MSubF64r32,
758
sewardjb183b852006-02-03 16:08:03 +0000759 /* :: F64 -> F64 */
sewardj1ddee212014-08-24 14:00:19 +0000760 Iop_RSqrtEst5GoodF64, /* reciprocal square root estimate, 5 good bits */
sewardj0f1ef862008-08-08 08:37:06 +0000761 Iop_RoundF64toF64_NEAREST, /* frin */
762 Iop_RoundF64toF64_NegINF, /* frim */
763 Iop_RoundF64toF64_PosINF, /* frip */
764 Iop_RoundF64toF64_ZERO, /* friz */
sewardjb183b852006-02-03 16:08:03 +0000765
766 /* :: F64 -> F32 */
767 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
768
769 /* :: IRRoundingMode(I32) x F64 -> F64 */
770 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
771 /* NB: pretty much the same as Iop_F64toF32, except no change
772 of type. */
773
sewardj89cefe42015-02-24 12:21:01 +0000774 /* --- guest arm64 specifics, not mandated by 754. --- */
775
776 Iop_RecpExpF64, /* FRECPX d :: IRRoundingMode(I32) x F64 -> F64 */
777 Iop_RecpExpF32, /* FRECPX s :: IRRoundingMode(I32) x F32 -> F32 */
778
Elliott Hughesed398002017-06-21 14:41:24 -0700779 /* --------- Possibly required by IEEE 754-2008. --------- */
780
781 Iop_MaxNumF64, /* max, F64, numerical operand if other is a qNaN */
782 Iop_MinNumF64, /* min, F64, ditto */
783 Iop_MaxNumF32, /* max, F32, ditto */
784 Iop_MinNumF32, /* min, F32, ditto */
785
sewardj3738bfc2015-03-30 08:50:27 +0000786 /* ------------------ 16-bit scalar FP ------------------ */
787
788 Iop_F16toF64, /* F16 -> F64 */
789 Iop_F64toF16, /* IRRoundingMode(I32) x F64 -> F16 */
790
791 Iop_F16toF32, /* F16 -> F32 */
792 Iop_F32toF16, /* IRRoundingMode(I32) x F32 -> F16 */
793
sewardje2ea1762010-09-22 00:56:37 +0000794 /* ------------------ 32-bit SIMD Integer ------------------ */
795
sewardj44ce46d2012-07-11 13:19:10 +0000796 /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
797 Iop_QAdd32S,
798 Iop_QSub32S,
799
sewardje2ea1762010-09-22 00:56:37 +0000800 /* 16x2 add/sub, also signed/unsigned saturating variants */
801 Iop_Add16x2, Iop_Sub16x2,
802 Iop_QAdd16Sx2, Iop_QAdd16Ux2,
803 Iop_QSub16Sx2, Iop_QSub16Ux2,
804
805 /* 16x2 signed/unsigned halving add/sub. For each lane, these
806 compute bits 16:1 of (eg) sx(argL) + sx(argR),
807 or zx(argL) - zx(argR) etc. */
808 Iop_HAdd16Ux2, Iop_HAdd16Sx2,
809 Iop_HSub16Ux2, Iop_HSub16Sx2,
810
811 /* 8x4 add/sub, also signed/unsigned saturating variants */
812 Iop_Add8x4, Iop_Sub8x4,
813 Iop_QAdd8Sx4, Iop_QAdd8Ux4,
814 Iop_QSub8Sx4, Iop_QSub8Ux4,
815
816 /* 8x4 signed/unsigned halving add/sub. For each lane, these
817 compute bits 8:1 of (eg) sx(argL) + sx(argR),
818 or zx(argL) - zx(argR) etc. */
819 Iop_HAdd8Ux4, Iop_HAdd8Sx4,
820 Iop_HSub8Ux4, Iop_HSub8Sx4,
821
sewardj310d6b22010-10-18 16:29:40 +0000822 /* 8x4 sum of absolute unsigned differences. */
823 Iop_Sad8Ux4,
824
sewardje2ea1762010-09-22 00:56:37 +0000825 /* MISC (vector integer cmp != 0) */
826 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
827
sewardj2fdd4162010-08-22 12:59:02 +0000828 /* ------------------ 64-bit SIMD FP ------------------------ */
829
830 /* Convertion to/from int */
831 Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */
832 Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */
833 /* Fixed32 format is floating-point number with fixed number of fraction
834 bits. The number of fraction bits is passed as a second argument of
835 type I8. */
836 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
837 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
838
839 /* Binary operations */
840 Iop_Max32Fx2, Iop_Min32Fx2,
841 /* Pairwise Min and Max. See integer pairwise operations for more
842 details. */
843 Iop_PwMax32Fx2, Iop_PwMin32Fx2,
844 /* Note: For the following compares, the arm front-end assumes a
845 nan in a lane of either argument returns zero for that lane. */
846 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
847
848 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
849 element in the operand vector, and places the results in the destination
850 vector. */
sewardj1ddee212014-08-24 14:00:19 +0000851 Iop_RecipEst32Fx2,
sewardj2fdd4162010-08-22 12:59:02 +0000852
853 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
854 Note, that if one of the arguments is zero and another one is infinity
855 of arbitrary sign the result of the operation is 2.0. */
sewardj1ddee212014-08-24 14:00:19 +0000856 Iop_RecipStep32Fx2,
sewardj2fdd4162010-08-22 12:59:02 +0000857
858 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
859 square root of each element in the operand vector. */
sewardj1ddee212014-08-24 14:00:19 +0000860 Iop_RSqrtEst32Fx2,
sewardj2fdd4162010-08-22 12:59:02 +0000861
862 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
863 Note, that of one of the arguments is zero and another one is infiinty
864 of arbitrary sign the result of the operation is 1.5. */
sewardj1ddee212014-08-24 14:00:19 +0000865 Iop_RSqrtStep32Fx2,
sewardj2fdd4162010-08-22 12:59:02 +0000866
867 /* Unary */
868 Iop_Neg32Fx2, Iop_Abs32Fx2,
869
sewardj38a3f862005-01-13 15:06:51 +0000870 /* ------------------ 64-bit SIMD Integer. ------------------ */
871
872 /* MISC (vector integer cmp != 0) */
sewardj18069182005-01-13 19:16:04 +0000873 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
sewardj38a3f862005-01-13 15:06:51 +0000874
875 /* ADDITION (normal / unsigned sat / signed sat) */
876 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000877 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
878 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
879
880 /* PAIRWISE operations */
881 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
882 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
883 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2,
884 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
885 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
886 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
887 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
888 /* Longening variant is unary. The resulting vector contains two times
889 less elements than operand, but they are two times wider.
890 Example:
891 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
892 where a+b and c+d are unsigned 32-bit values. */
893 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
894 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000895
896 /* SUBTRACTION (normal / unsigned sat / signed sat) */
897 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000898 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
899 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
sewardj38a3f862005-01-13 15:06:51 +0000900
sewardj2fdd4162010-08-22 12:59:02 +0000901 /* ABSOLUTE VALUE */
902 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
903
904 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
905 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
906 Iop_Mul32Fx2,
sewardj38a3f862005-01-13 15:06:51 +0000907 Iop_MulHi16Ux4,
908 Iop_MulHi16Sx4,
sewardj2fdd4162010-08-22 12:59:02 +0000909 /* Plynomial multiplication treats it's arguments as coefficients of
910 polynoms over {0, 1}. */
911 Iop_PolynomialMul8x8,
912
913 /* Vector Saturating Doubling Multiply Returning High Half and
914 Vector Saturating Rounding Doubling Multiply Returning High Half */
915 /* These IROp's multiply corresponding elements in two vectors, double
916 the results, and place the most significant half of the final results
917 in the destination vector. The results are truncated or rounded. If
918 any of the results overflow, they are saturated. */
919 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
920 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000921
sewardj5ce5fd62005-04-19 23:06:11 +0000922 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
sewardj38a3f862005-01-13 15:06:51 +0000923 Iop_Avg8Ux8,
924 Iop_Avg16Ux4,
925
926 /* MIN/MAX */
sewardj2fdd4162010-08-22 12:59:02 +0000927 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
928 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
929 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
930 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000931
932 /* COMPARISON */
933 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000934 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000935 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
936
sewardj2fdd4162010-08-22 12:59:02 +0000937 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
938 bit) */
939 Iop_Cnt8x8,
sewardja8c7b0f2014-06-26 08:18:08 +0000940 Iop_Clz8x8, Iop_Clz16x4, Iop_Clz32x2,
941 Iop_Cls8x8, Iop_Cls16x4, Iop_Cls32x2,
carll7deaf952013-10-15 18:11:20 +0000942 Iop_Clz64x2,
sewardj2fdd4162010-08-22 12:59:02 +0000943
Elliott Hughesa0664b92017-04-18 17:46:52 -0700944 /*Vector COUNT trailing zeros */
945 Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2,
946
sewardj2fdd4162010-08-22 12:59:02 +0000947 /* VECTOR x VECTOR SHIFT / ROTATE */
948 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
949 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
950 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
951 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
952
sewardj38a3f862005-01-13 15:06:51 +0000953 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
sewardjd166e282008-02-06 11:42:45 +0000954 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000955 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
sewardjd71ba832006-12-27 01:15:29 +0000956 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
sewardj38a3f862005-01-13 15:06:51 +0000957
sewardj2fdd4162010-08-22 12:59:02 +0000958 /* VECTOR x VECTOR SATURATING SHIFT */
959 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
960 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
961 /* VECTOR x INTEGER SATURATING SHIFT */
sewardj1dd3ec12014-08-15 09:11:08 +0000962 Iop_QShlNsatSU8x8, Iop_QShlNsatSU16x4,
963 Iop_QShlNsatSU32x2, Iop_QShlNsatSU64x1,
964 Iop_QShlNsatUU8x8, Iop_QShlNsatUU16x4,
965 Iop_QShlNsatUU32x2, Iop_QShlNsatUU64x1,
966 Iop_QShlNsatSS8x8, Iop_QShlNsatSS16x4,
967 Iop_QShlNsatSS32x2, Iop_QShlNsatSS64x1,
sewardj2fdd4162010-08-22 12:59:02 +0000968
sewardj5f438dd2011-06-16 11:36:23 +0000969 /* NARROWING (binary)
970 -- narrow 2xI64 into 1xI64, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +0000971 /* For saturated narrowing, I believe there are 4 variants of
972 the basic arithmetic operation, depending on the signedness
973 of argument and result. Here are examples that exemplify
974 what I mean:
975
976 QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255;
977 return x[7:0];
978
979 QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128;
980 if (x >s 127) x = 127;
981 return x[7:0];
982
983 QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127;
984 return x[7:0];
985
986 QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0;
987 if (x >s 255) x = 255;
988 return x[7:0];
989 */
sewardj5f438dd2011-06-16 11:36:23 +0000990 Iop_QNarrowBin16Sto8Ux8,
991 Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
sewardjad2c9ea2011-10-22 09:32:16 +0000992 Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4,
sewardj38a3f862005-01-13 15:06:51 +0000993
sewardj2fdd4162010-08-22 12:59:02 +0000994 /* INTERLEAVING */
995 /* Interleave lanes from low or high halves of
sewardj38a3f862005-01-13 15:06:51 +0000996 operands. Most-significant result lane is from the left
997 arg. */
998 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
999 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
sewardj2fdd4162010-08-22 12:59:02 +00001000 /* Interleave odd/even lanes of operands. Most-significant result lane
1001 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are
1002 identical to Interleave{HI,LO}32x2 and so are omitted.*/
1003 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
1004 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
1005
sewardjd166e282008-02-06 11:42:45 +00001006 /* CONCATENATION -- build a new value by concatenating either
1007 the even or odd lanes of both operands. Note that
1008 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
1009 and so are omitted. */
sewardj2fdd4162010-08-22 12:59:02 +00001010 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
1011 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
1012
1013 /* GET / SET elements of VECTOR
1014 GET is binop (I64, I8) -> I<elem_size>
1015 SET is triop (I64, I8, I<elem_size>) -> I64 */
1016 /* Note: the arm back-end handles only constant second argument */
1017 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
1018 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
1019
1020 /* DUPLICATING -- copy value to all lanes */
1021 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2,
1022
sewardje6b9bd92014-09-01 11:32:47 +00001023 /* SLICE -- produces the lowest 64 bits of (arg1:arg2) >> (8 * arg3).
1024 arg3 is a shift amount in bytes and may be between 0 and 8
1025 inclusive. When 0, the result is arg2; when 8, the result is arg1.
1026 Not all back ends handle all values. The arm32 and arm64 back
1027 ends handle only immediate arg3 values. */
1028 Iop_Slice64, // (I64, I64, I8) -> I64
sewardj2fdd4162010-08-22 12:59:02 +00001029
sewardj33680352014-06-26 10:49:33 +00001030 /* REVERSE the order of chunks in vector lanes. Chunks must be
1031 smaller than the vector lanes (obviously) and so may be 8-,
1032 16- and 32-bit in size. */
sewardj2fdd4162010-08-22 12:59:02 +00001033 /* Examples:
sewardj33680352014-06-26 10:49:33 +00001034 Reverse8sIn16_x4([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1035 Reverse8sIn32_x2([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
1036 Reverse8sIn64_x1([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
1037 Iop_Reverse8sIn16_x4,
1038 Iop_Reverse8sIn32_x2, Iop_Reverse16sIn32_x2,
1039 Iop_Reverse8sIn64_x1, Iop_Reverse16sIn64_x1, Iop_Reverse32sIn64_x1,
sewardjd166e282008-02-06 11:42:45 +00001040
1041 /* PERMUTING -- copy src bytes to dst,
1042 as indexed by control vector bytes:
1043 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
1044 argR[i] values may only be in the range 0 .. 7, else behaviour
1045 is undefined. */
1046 Iop_Perm8x8,
1047
sewardje13074c2012-11-08 10:57:08 +00001048 /* MISC CONVERSION -- get high bits of each byte lane, a la
1049 x86/amd64 pmovmskb */
1050 Iop_GetMSBs8x8, /* I64 -> I8 */
1051
sewardj2fdd4162010-08-22 12:59:02 +00001052 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
sewardj1ddee212014-08-24 14:00:19 +00001053 See floating-point equivalents for details. */
1054 Iop_RecipEst32Ux2, Iop_RSqrtEst32Ux2,
sewardj2fdd4162010-08-22 12:59:02 +00001055
sewardjc6bbd472012-04-02 10:20:48 +00001056 /* ------------------ Decimal Floating Point ------------------ */
1057
1058 /* ARITHMETIC INSTRUCTIONS 64-bit
1059 ----------------------------------
florian79e5a482013-06-06 19:12:46 +00001060 IRRoundingMode(I32) X D64 X D64 -> D64
sewardjc6bbd472012-04-02 10:20:48 +00001061 */
1062 Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1063
1064 /* ARITHMETIC INSTRUCTIONS 128-bit
1065 ----------------------------------
florian79e5a482013-06-06 19:12:46 +00001066 IRRoundingMode(I32) X D128 X D128 -> D128
sewardjc6bbd472012-04-02 10:20:48 +00001067 */
1068 Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1069
sewardj26217b02012-04-12 17:19:48 +00001070 /* SHIFT SIGNIFICAND INSTRUCTIONS
1071 * The DFP significand is shifted by the number of digits specified
1072 * by the U8 operand. Digits shifted out of the leftmost digit are
1073 * lost. Zeros are supplied to the vacated positions on the right.
1074 * The sign of the result is the same as the sign of the original
1075 * operand.
sewardjcdc376d2012-04-23 11:21:12 +00001076 *
1077 * D64 x U8 -> D64 left shift and right shift respectively */
sewardj26217b02012-04-12 17:19:48 +00001078 Iop_ShlD64, Iop_ShrD64,
1079
1080 /* D128 x U8 -> D128 left shift and right shift respectively */
1081 Iop_ShlD128, Iop_ShrD128,
1082
1083
1084 /* FORMAT CONVERSION INSTRUCTIONS
1085 * D32 -> D64
1086 */
1087 Iop_D32toD64,
1088
1089 /* D64 -> D128 */
1090 Iop_D64toD128,
1091
florianb17e16f2013-01-12 22:02:07 +00001092 /* I32S -> D128 */
1093 Iop_I32StoD128,
1094
1095 /* I32U -> D128 */
1096 Iop_I32UtoD128,
1097
sewardj26217b02012-04-12 17:19:48 +00001098 /* I64S -> D128 */
1099 Iop_I64StoD128,
1100
florianb17e16f2013-01-12 22:02:07 +00001101 /* I64U -> D128 */
1102 Iop_I64UtoD128,
1103
florian79e5a482013-06-06 19:12:46 +00001104 /* IRRoundingMode(I32) x D64 -> D32 */
sewardj26217b02012-04-12 17:19:48 +00001105 Iop_D64toD32,
1106
florian79e5a482013-06-06 19:12:46 +00001107 /* IRRoundingMode(I32) x D128 -> D64 */
sewardj26217b02012-04-12 17:19:48 +00001108 Iop_D128toD64,
1109
florianb17e16f2013-01-12 22:02:07 +00001110 /* I32S -> D64 */
1111 Iop_I32StoD64,
1112
1113 /* I32U -> D64 */
1114 Iop_I32UtoD64,
1115
florian79e5a482013-06-06 19:12:46 +00001116 /* IRRoundingMode(I32) x I64 -> D64 */
sewardj26217b02012-04-12 17:19:48 +00001117 Iop_I64StoD64,
1118
florian79e5a482013-06-06 19:12:46 +00001119 /* IRRoundingMode(I32) x I64 -> D64 */
florianb17e16f2013-01-12 22:02:07 +00001120 Iop_I64UtoD64,
1121
florian79e5a482013-06-06 19:12:46 +00001122 /* IRRoundingMode(I32) x D64 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001123 Iop_D64toI32S,
1124
florian79e5a482013-06-06 19:12:46 +00001125 /* IRRoundingMode(I32) x D64 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001126 Iop_D64toI32U,
1127
florian79e5a482013-06-06 19:12:46 +00001128 /* IRRoundingMode(I32) x D64 -> I64 */
sewardj26217b02012-04-12 17:19:48 +00001129 Iop_D64toI64S,
1130
florian79e5a482013-06-06 19:12:46 +00001131 /* IRRoundingMode(I32) x D64 -> I64 */
florianb17e16f2013-01-12 22:02:07 +00001132 Iop_D64toI64U,
1133
florian79e5a482013-06-06 19:12:46 +00001134 /* IRRoundingMode(I32) x D128 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001135 Iop_D128toI32S,
1136
florian79e5a482013-06-06 19:12:46 +00001137 /* IRRoundingMode(I32) x D128 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001138 Iop_D128toI32U,
1139
florian79e5a482013-06-06 19:12:46 +00001140 /* IRRoundingMode(I32) x D128 -> I64 */
sewardj26217b02012-04-12 17:19:48 +00001141 Iop_D128toI64S,
1142
florian79e5a482013-06-06 19:12:46 +00001143 /* IRRoundingMode(I32) x D128 -> I64 */
florianb17e16f2013-01-12 22:02:07 +00001144 Iop_D128toI64U,
1145
florianb22838d2013-06-17 18:59:51 +00001146 /* IRRoundingMode(I32) x F32 -> D32 */
1147 Iop_F32toD32,
1148
1149 /* IRRoundingMode(I32) x F32 -> D64 */
1150 Iop_F32toD64,
1151
1152 /* IRRoundingMode(I32) x F32 -> D128 */
1153 Iop_F32toD128,
1154
1155 /* IRRoundingMode(I32) x F64 -> D32 */
1156 Iop_F64toD32,
1157
florian79e5a482013-06-06 19:12:46 +00001158 /* IRRoundingMode(I32) x F64 -> D64 */
florian37c57f32013-05-05 15:04:30 +00001159 Iop_F64toD64,
1160
florian79e5a482013-06-06 19:12:46 +00001161 /* IRRoundingMode(I32) x F64 -> D128 */
florian37c57f32013-05-05 15:04:30 +00001162 Iop_F64toD128,
1163
florianb22838d2013-06-17 18:59:51 +00001164 /* IRRoundingMode(I32) x F128 -> D32 */
1165 Iop_F128toD32,
1166
1167 /* IRRoundingMode(I32) x F128 -> D64 */
1168 Iop_F128toD64,
florian37c57f32013-05-05 15:04:30 +00001169
florian79e5a482013-06-06 19:12:46 +00001170 /* IRRoundingMode(I32) x F128 -> D128 */
florian37c57f32013-05-05 15:04:30 +00001171 Iop_F128toD128,
1172
florianb22838d2013-06-17 18:59:51 +00001173 /* IRRoundingMode(I32) x D32 -> F32 */
1174 Iop_D32toF32,
1175
1176 /* IRRoundingMode(I32) x D32 -> F64 */
1177 Iop_D32toF64,
1178
1179 /* IRRoundingMode(I32) x D32 -> F128 */
1180 Iop_D32toF128,
1181
1182 /* IRRoundingMode(I32) x D64 -> F32 */
1183 Iop_D64toF32,
1184
1185 /* IRRoundingMode(I32) x D64 -> F64 */
1186 Iop_D64toF64,
1187
1188 /* IRRoundingMode(I32) x D64 -> F128 */
1189 Iop_D64toF128,
1190
1191 /* IRRoundingMode(I32) x D128 -> F32 */
1192 Iop_D128toF32,
1193
1194 /* IRRoundingMode(I32) x D128 -> F64 */
1195 Iop_D128toF64,
1196
florian79e5a482013-06-06 19:12:46 +00001197 /* IRRoundingMode(I32) x D128 -> F128 */
florian37c57f32013-05-05 15:04:30 +00001198 Iop_D128toF128,
1199
sewardjcdc376d2012-04-23 11:21:12 +00001200 /* ROUNDING INSTRUCTIONS
1201 * IRRoundingMode(I32) x D64 -> D64
carllcea07cc2013-01-22 20:25:31 +00001202 * The D64 operand, if a finite number, it is rounded to a
1203 * floating point integer value, i.e. no fractional part.
sewardjcdc376d2012-04-23 11:21:12 +00001204 */
1205 Iop_RoundD64toInt,
1206
1207 /* IRRoundingMode(I32) x D128 -> D128 */
1208 Iop_RoundD128toInt,
1209
1210 /* COMPARE INSTRUCTIONS
1211 * D64 x D64 -> IRCmpD64Result(I32) */
1212 Iop_CmpD64,
1213
floriandaa40842012-12-21 20:24:24 +00001214 /* D128 x D128 -> IRCmpD128Result(I32) */
sewardjcdc376d2012-04-23 11:21:12 +00001215 Iop_CmpD128,
1216
florian20c6bca2012-12-26 17:47:19 +00001217 /* COMPARE BIASED EXPONENET INSTRUCTIONS
1218 * D64 x D64 -> IRCmpD64Result(I32) */
1219 Iop_CmpExpD64,
1220
1221 /* D128 x D128 -> IRCmpD128Result(I32) */
1222 Iop_CmpExpD128,
1223
sewardjcdc376d2012-04-23 11:21:12 +00001224 /* QUANTIZE AND ROUND INSTRUCTIONS
1225 * The source operand is converted and rounded to the form with the
1226 * immediate exponent specified by the rounding and exponent parameter.
1227 *
1228 * The second operand is converted and rounded to the form
1229 * of the first operand's exponent and the rounded based on the specified
1230 * rounding mode parameter.
1231 *
florian79e5a482013-06-06 19:12:46 +00001232 * IRRoundingMode(I32) x D64 x D64-> D64 */
sewardjcdc376d2012-04-23 11:21:12 +00001233 Iop_QuantizeD64,
1234
florian79e5a482013-06-06 19:12:46 +00001235 /* IRRoundingMode(I32) x D128 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001236 Iop_QuantizeD128,
1237
florian79e5a482013-06-06 19:12:46 +00001238 /* IRRoundingMode(I32) x I8 x D64 -> D64
sewardjcdc376d2012-04-23 11:21:12 +00001239 * The Decimal Floating point operand is rounded to the requested
1240 * significance given by the I8 operand as specified by the rounding
1241 * mode.
1242 */
1243 Iop_SignificanceRoundD64,
1244
florian79e5a482013-06-06 19:12:46 +00001245 /* IRRoundingMode(I32) x I8 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001246 Iop_SignificanceRoundD128,
1247
1248 /* EXTRACT AND INSERT INSTRUCTIONS
1249 * D64 -> I64
1250 * The exponent of the D32 or D64 operand is extracted. The
1251 * extracted exponent is converted to a 64-bit signed binary integer.
1252 */
1253 Iop_ExtractExpD64,
1254
1255 /* D128 -> I64 */
1256 Iop_ExtractExpD128,
1257
florian4bbd3ec2012-12-27 20:01:13 +00001258 /* D64 -> I64
1259 * The number of significand digits of the D64 operand is extracted.
1260 * The number is stored as a 64-bit signed binary integer.
1261 */
1262 Iop_ExtractSigD64,
1263
1264 /* D128 -> I64 */
1265 Iop_ExtractSigD128,
1266
carllcea07cc2013-01-22 20:25:31 +00001267 /* I64 x D64 -> D64
sewardjcdc376d2012-04-23 11:21:12 +00001268 * The exponent is specified by the first I64 operand the signed
1269 * significand is given by the second I64 value. The result is a D64
1270 * value consisting of the specified significand and exponent whose
1271 * sign is that of the specified significand.
1272 */
1273 Iop_InsertExpD64,
1274
carllcea07cc2013-01-22 20:25:31 +00001275 /* I64 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001276 Iop_InsertExpD128,
1277
sewardjc6bbd472012-04-02 10:20:48 +00001278 /* Support for 128-bit DFP type */
1279 Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1280
sewardj4c96e612012-06-02 23:47:02 +00001281 /* I64 -> I64
1282 * Convert 50-bit densely packed BCD string to 60 bit BCD string
1283 */
1284 Iop_DPBtoBCD,
1285
1286 /* I64 -> I64
1287 * Convert 60 bit BCD string to 50-bit densely packed BCD string
1288 */
1289 Iop_BCDtoDPB,
1290
carll7deaf952013-10-15 18:11:20 +00001291 /* BCD arithmetic instructions, (V128, V128) -> V128
1292 * The BCD format is the same as that used in the BCD<->DPB conversion
sewardj9571dc02014-01-26 18:34:23 +00001293 * routines, except using 124 digits (vs 60) plus the trailing 4-bit
1294 * signed code. */
carll7deaf952013-10-15 18:11:20 +00001295 Iop_BCDAdd, Iop_BCDSub,
1296
Elliott Hughesa0664b92017-04-18 17:46:52 -07001297 /* Conversion signed 128-bit integer to signed BCD 128-bit */
1298 Iop_I128StoBCD128,
1299
1300 /* Conversion signed BCD 128-bit to 128-bit integer */
1301 Iop_BCD128toI128S,
1302
sewardjcdc376d2012-04-23 11:21:12 +00001303 /* Conversion I64 -> D64 */
1304 Iop_ReinterpI64asD64,
1305
sewardj5eff1c52012-04-29 20:19:17 +00001306 /* Conversion D64 -> I64 */
1307 Iop_ReinterpD64asI64,
1308
sewardj164f9272004-12-09 00:39:32 +00001309 /* ------------------ 128-bit SIMD FP. ------------------ */
sewardjc9a43662004-11-30 18:51:59 +00001310
1311 /* --- 32x4 vector FP --- */
1312
sewardj9571dc02014-01-26 18:34:23 +00001313 /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
sewardjc9a43662004-11-30 18:51:59 +00001314 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
sewardj9571dc02014-01-26 18:34:23 +00001315
1316 /* binary */
sewardjc9a43662004-11-30 18:51:59 +00001317 Iop_Max32Fx4, Iop_Min32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001318 Iop_Add32Fx2, Iop_Sub32Fx2,
1319 /* Note: For the following compares, the ppc and arm front-ends assume a
cerionf294eb32005-11-16 17:21:10 +00001320 nan in a lane of either argument returns zero for that lane. */
sewardj2fdd4162010-08-22 12:59:02 +00001321 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
cerion206c3642005-11-14 00:35:59 +00001322 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
sewardjc9a43662004-11-30 18:51:59 +00001323
sewardj2fdd4162010-08-22 12:59:02 +00001324 /* Pairwise Max and Min. See integer pairwise operations for details. */
1325 Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1326
sewardjc9a43662004-11-30 18:51:59 +00001327 /* unary */
sewardjfab09142014-02-10 10:28:13 +00001328 Iop_Abs32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001329 Iop_Neg32Fx4,
1330
sewardj4b21c3d2015-04-06 19:34:03 +00001331 /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1332 Iop_Sqrt32Fx4,
1333
sewardj2fdd4162010-08-22 12:59:02 +00001334 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
sewardj89cefe42015-02-24 12:21:01 +00001335 element in the operand vector, and places the results in the
1336 destination vector. */
sewardj1ddee212014-08-24 14:00:19 +00001337 Iop_RecipEst32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001338
1339 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1340 Note, that if one of the arguments is zero and another one is infinity
1341 of arbitrary sign the result of the operation is 2.0. */
sewardj1ddee212014-08-24 14:00:19 +00001342 Iop_RecipStep32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001343
1344 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1345 square root of each element in the operand vector. */
sewardj1ddee212014-08-24 14:00:19 +00001346 Iop_RSqrtEst32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001347
1348 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1349 Note, that of one of the arguments is zero and another one is infiinty
1350 of arbitrary sign the result of the operation is 1.5. */
sewardj1ddee212014-08-24 14:00:19 +00001351 Iop_RSqrtStep32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001352
cerionf294eb32005-11-16 17:21:10 +00001353 /* --- Int to/from FP conversion --- */
1354 /* Unlike the standard fp conversions, these irops take no
1355 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1356 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
sewardj8b1715b2014-01-21 16:33:51 +00001357 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */
sewardj2fdd4162010-08-22 12:59:02 +00001358 Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */
sewardj8b1715b2014-01-21 16:33:51 +00001359 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (saturating) */
cerionf294eb32005-11-16 17:21:10 +00001360 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
1361 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
sewardj2fdd4162010-08-22 12:59:02 +00001362 /* Fixed32 format is floating-point number with fixed number of fraction
1363 bits. The number of fraction bits is passed as a second argument of
1364 type I8. */
1365 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1366 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1367
1368 /* --- Single to/from half conversion --- */
sewardj5f438dd2011-06-16 11:36:23 +00001369 /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
sewardj2fdd4162010-08-22 12:59:02 +00001370 Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */
cerionf294eb32005-11-16 17:21:10 +00001371
Elliott Hughesa0664b92017-04-18 17:46:52 -07001372 /* -- Double to/from half conversion -- */
1373 Iop_F64toF16x2, Iop_F16toF64x2,
1374
sewardjc9a43662004-11-30 18:51:59 +00001375 /* --- 32x4 lowest-lane-only scalar FP --- */
1376
1377 /* In binary cases, upper 3/4 is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001378 unary cases, upper 3/4 is copied from the operand. */
sewardjc9a43662004-11-30 18:51:59 +00001379
1380 /* binary */
1381 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1382 Iop_Max32F0x4, Iop_Min32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001383 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
sewardjc9a43662004-11-30 18:51:59 +00001384
1385 /* unary */
sewardj1ddee212014-08-24 14:00:19 +00001386 Iop_RecipEst32F0x4, Iop_Sqrt32F0x4, Iop_RSqrtEst32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001387
1388 /* --- 64x2 vector FP --- */
1389
sewardj9571dc02014-01-26 18:34:23 +00001390 /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
sewardj636ad762004-12-07 11:16:04 +00001391 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
sewardj9571dc02014-01-26 18:34:23 +00001392
1393 /* binary */
sewardj636ad762004-12-07 11:16:04 +00001394 Iop_Max64Fx2, Iop_Min64Fx2,
1395 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1396
1397 /* unary */
sewardjfab09142014-02-10 10:28:13 +00001398 Iop_Abs64Fx2,
sewardjfab09142014-02-10 10:28:13 +00001399 Iop_Neg64Fx2,
1400
sewardj4b21c3d2015-04-06 19:34:03 +00001401 /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1402 Iop_Sqrt64Fx2,
1403
sewardj89cefe42015-02-24 12:21:01 +00001404 /* see 32Fx4 variants for description */
1405 Iop_RecipEst64Fx2, // unary
1406 Iop_RecipStep64Fx2, // binary
1407 Iop_RSqrtEst64Fx2, // unary
1408 Iop_RSqrtStep64Fx2, // binary
1409
sewardj636ad762004-12-07 11:16:04 +00001410 /* --- 64x2 lowest-lane-only scalar FP --- */
1411
1412 /* In binary cases, upper half is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001413 unary cases, upper half is copied from the operand. */
sewardj636ad762004-12-07 11:16:04 +00001414
1415 /* binary */
1416 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1417 Iop_Max64F0x2, Iop_Min64F0x2,
1418 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1419
1420 /* unary */
sewardj1ddee212014-08-24 14:00:19 +00001421 Iop_Sqrt64F0x2,
sewardjc9a43662004-11-30 18:51:59 +00001422
1423 /* --- pack / unpack --- */
1424
sewardjf0c1c582005-02-07 23:47:38 +00001425 /* 64 <-> 128 bit vector */
1426 Iop_V128to64, // :: V128 -> I64, low half
1427 Iop_V128HIto64, // :: V128 -> I64, high half
1428 Iop_64HLtoV128, // :: (I64,I64) -> V128
sewardjc9a43662004-11-30 18:51:59 +00001429
sewardjf0c1c582005-02-07 23:47:38 +00001430 Iop_64UtoV128,
1431 Iop_SetV128lo64,
sewardj164f9272004-12-09 00:39:32 +00001432
sewardjecde6972014-02-05 11:01:19 +00001433 /* Copies lower 64/32/16/8 bits, zeroes out the rest. */
1434 Iop_ZeroHI64ofV128, // :: V128 -> V128
1435 Iop_ZeroHI96ofV128, // :: V128 -> V128
1436 Iop_ZeroHI112ofV128, // :: V128 -> V128
1437 Iop_ZeroHI120ofV128, // :: V128 -> V128
sewardj606c4ba2014-01-26 19:11:14 +00001438
sewardjf0c1c582005-02-07 23:47:38 +00001439 /* 32 <-> 128 bit vector */
1440 Iop_32UtoV128,
1441 Iop_V128to32, // :: V128 -> I32, lowest lane
1442 Iop_SetV128lo32, // :: (V128,I32) -> V128
sewardj70f676d2004-12-10 14:59:57 +00001443
sewardj164f9272004-12-09 00:39:32 +00001444 /* ------------------ 128-bit SIMD Integer. ------------------ */
1445
1446 /* BITWISE OPS */
sewardjf0c1c582005-02-07 23:47:38 +00001447 Iop_NotV128,
1448 Iop_AndV128, Iop_OrV128, Iop_XorV128,
sewardj164f9272004-12-09 00:39:32 +00001449
cerionf887b3e2005-09-13 16:34:28 +00001450 /* VECTOR SHIFT (shift amt :: Ity_I8) */
1451 Iop_ShlV128, Iop_ShrV128,
1452
sewardj2e383862004-12-12 16:46:47 +00001453 /* MISC (vector integer cmp != 0) */
1454 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
sewardj70f676d2004-12-10 14:59:57 +00001455
sewardjf7003bc2014-08-18 12:28:02 +00001456 /* ADDITION (normal / U->U sat / S->S sat) */
1457 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2,
1458 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1459 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
1460
1461 /* ADDITION, ARM64 specific saturating variants. */
1462 /* Unsigned widen left arg, signed widen right arg, add, saturate S->S.
1463 This corresponds to SUQADD. */
1464 Iop_QAddExtUSsatSS8x16, Iop_QAddExtUSsatSS16x8,
1465 Iop_QAddExtUSsatSS32x4, Iop_QAddExtUSsatSS64x2,
1466 /* Signed widen left arg, unsigned widen right arg, add, saturate U->U.
1467 This corresponds to USQADD. */
1468 Iop_QAddExtSUsatUU8x16, Iop_QAddExtSUsatUU16x8,
1469 Iop_QAddExtSUsatUU32x4, Iop_QAddExtSUsatUU64x2,
sewardj164f9272004-12-09 00:39:32 +00001470
1471 /* SUBTRACTION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001472 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2,
1473 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1474 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001475
1476 /* MULTIPLICATION (normal / high half of signed/unsigned) */
sewardj2fdd4162010-08-22 12:59:02 +00001477 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4,
1478 Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1479 Iop_MulHi16Sx8, Iop_MulHi32Sx4,
cerion24d06f12005-11-09 21:34:20 +00001480 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
carll48ae46b2013-10-01 15:45:54 +00001481 Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4,
1482 Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4,
sewardj51d012a2014-07-21 09:19:50 +00001483
1484 /* Widening multiplies, all of the form (I64, I64) -> V128 */
sewardj2fdd4162010-08-22 12:59:02 +00001485 Iop_Mull8Ux8, Iop_Mull8Sx8,
1486 Iop_Mull16Ux4, Iop_Mull16Sx4,
1487 Iop_Mull32Ux2, Iop_Mull32Sx2,
sewardj51d012a2014-07-21 09:19:50 +00001488
1489 /* Signed doubling saturating widening multiplies, (I64, I64) -> V128 */
1490 Iop_QDMull16Sx4, Iop_QDMull32Sx2,
1491
sewardj2fdd4162010-08-22 12:59:02 +00001492 /* Vector Saturating Doubling Multiply Returning High Half and
sewardjf3eaabd2014-07-22 09:26:36 +00001493 Vector Saturating Rounding Doubling Multiply Returning High Half.
1494 These IROps multiply corresponding elements in two vectors, double
sewardj2fdd4162010-08-22 12:59:02 +00001495 the results, and place the most significant half of the final results
sewardjf3eaabd2014-07-22 09:26:36 +00001496 in the destination vector. The results are truncated or rounded. If
1497 any of the results overflow, they are saturated. To be more precise,
1498 for each lane, the computed result is:
1499 QDMulHi:
1500 hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2 )
1501 QRDMulHi:
1502 hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2
1503 +q (1 << (lane-width-in-bits - 1)) )
1504 */
1505 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4, /* (V128, V128) -> V128 */
1506 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, /* (V128, V128) -> V128 */
sewardj51d012a2014-07-21 09:19:50 +00001507
sewardjf5b08912014-02-06 12:57:58 +00001508 /* Polynomial multiplication treats its arguments as
1509 coefficients of polynomials over {0, 1}. */
sewardj2fdd4162010-08-22 12:59:02 +00001510 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1511 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */
1512
carll7deaf952013-10-15 18:11:20 +00001513 /* Vector Polynomial multiplication add. (V128, V128) -> V128
1514
1515 *** Below is the algorithm for the instructions. These Iops could
1516 be emulated to get this functionality, but the emulation would
1517 be long and messy.
1518
1519 Example for polynomial multiply add for vector of bytes
1520 do i = 0 to 15
1521 prod[i].bit[0:14] <- 0
1522 srcA <- VR[argL].byte[i]
1523 srcB <- VR[argR].byte[i]
1524 do j = 0 to 7
1525 do k = 0 to j
1526 gbit <- srcA.bit[k] & srcB.bit[j-k]
1527 prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1528 end
1529 end
1530
1531 do j = 8 to 14
1532 do k = j-7 to 7
1533 gbit <- (srcA.bit[k] & srcB.bit[j-k])
1534 prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1535 end
1536 end
1537 end
1538
1539 do i = 0 to 7
1540 VR[dst].hword[i] <- 0b0 || (prod[2×i] ^ prod[2×i+1])
1541 end
1542 */
1543 Iop_PolynomialMulAdd8x16, Iop_PolynomialMulAdd16x8,
1544 Iop_PolynomialMulAdd32x4, Iop_PolynomialMulAdd64x2,
1545
sewardj2fdd4162010-08-22 12:59:02 +00001546 /* PAIRWISE operations */
1547 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1548 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1549 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1550 Iop_PwAdd32Fx2,
1551 /* Longening variant is unary. The resulting vector contains two times
1552 less elements than operand, but they are two times wider.
1553 Example:
1554 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1555 where a+b and c+d are unsigned 32-bit values. */
1556 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1557 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1558
carll60c6bac2013-10-18 01:19:06 +00001559 /* Other unary pairwise ops */
1560
1561 /* Vector bit matrix transpose. (V128) -> V128 */
1562 /* For each doubleword element of the source vector, an 8-bit x 8-bit
1563 * matrix transpose is performed. */
1564 Iop_PwBitMtxXpose64x2,
1565
sewardj2fdd4162010-08-22 12:59:02 +00001566 /* ABSOLUTE VALUE */
sewardj25523c42014-06-15 19:36:29 +00001567 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2,
cerion1ac656a2005-11-04 19:44:48 +00001568
sewardj5ce5fd62005-04-19 23:06:11 +00001569 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
cerionf887b3e2005-09-13 16:34:28 +00001570 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1571 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
sewardj164f9272004-12-09 00:39:32 +00001572
1573 /* MIN/MAX */
carll48ae46b2013-10-01 15:45:54 +00001574 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2,
1575 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2,
1576 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2,
1577 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2,
sewardj164f9272004-12-09 00:39:32 +00001578
1579 /* COMPARISON */
sewardjd8815622011-10-19 15:24:01 +00001580 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2,
sewardj69d98e32010-06-18 08:17:41 +00001581 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
carll48ae46b2013-10-01 15:45:54 +00001582 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, Iop_CmpGT64Ux2,
sewardj164f9272004-12-09 00:39:32 +00001583
sewardj2fdd4162010-08-22 12:59:02 +00001584 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1585 bit) */
1586 Iop_Cnt8x16,
sewardja8c7b0f2014-06-26 08:18:08 +00001587 Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4,
1588 Iop_Cls8x16, Iop_Cls16x8, Iop_Cls32x4,
sewardj2fdd4162010-08-22 12:59:02 +00001589
sewardj164f9272004-12-09 00:39:32 +00001590 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
cerion2a4b8452005-09-15 16:28:36 +00001591 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1592 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001593 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
sewardj164f9272004-12-09 00:39:32 +00001594
cerionf887b3e2005-09-13 16:34:28 +00001595 /* VECTOR x VECTOR SHIFT / ROTATE */
sewardj15ceaef2014-08-26 18:29:26 +00001596 /* FIXME: I'm pretty sure the ARM32 front/back ends interpret these
1597 differently from all other targets. The intention is that
1598 the shift amount (2nd arg) is interpreted as unsigned and
1599 only the lowest log2(lane-bits) bits are relevant. But the
1600 ARM32 versions treat the shift amount as an 8 bit signed
1601 number. The ARM32 uses should be replaced by the relevant
1602 vector x vector bidirectional shifts instead. */
sewardj2fdd4162010-08-22 12:59:02 +00001603 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1604 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1605 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1606 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
carll48ae46b2013-10-01 15:45:54 +00001607 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2,
cerionf887b3e2005-09-13 16:34:28 +00001608
sewardj2fdd4162010-08-22 12:59:02 +00001609 /* VECTOR x VECTOR SATURATING SHIFT */
1610 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1611 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1612 /* VECTOR x INTEGER SATURATING SHIFT */
sewardj1dd3ec12014-08-15 09:11:08 +00001613 Iop_QShlNsatSU8x16, Iop_QShlNsatSU16x8,
1614 Iop_QShlNsatSU32x4, Iop_QShlNsatSU64x2,
1615 Iop_QShlNsatUU8x16, Iop_QShlNsatUU16x8,
1616 Iop_QShlNsatUU32x4, Iop_QShlNsatUU64x2,
1617 Iop_QShlNsatSS8x16, Iop_QShlNsatSS16x8,
1618 Iop_QShlNsatSS32x4, Iop_QShlNsatSS64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001619
sewardj12972182014-08-04 08:09:47 +00001620 /* VECTOR x VECTOR BIDIRECTIONAL SATURATING (& MAYBE ROUNDING) SHIFT */
sewardja6b61f02014-08-17 18:32:14 +00001621 /* All of type (V128, V128) -> V256. */
sewardj12972182014-08-04 08:09:47 +00001622 /* The least significant 8 bits of each lane of the second
1623 operand are used as the shift amount, and interpreted signedly.
1624 Positive values mean a shift left, negative a shift right. The
1625 result is signedly or unsignedly saturated. There are also
1626 rounding variants, which add 2^(shift_amount-1) to the value before
1627 shifting, but only in the shift-right case. Vacated positions
1628 are filled with zeroes. IOW, it's either SHR or SHL, but not SAR.
1629
1630 These operations return 129 bits: one bit ("Q") indicating whether
1631 saturation occurred, and the shift result. The result type is V256,
1632 of which the lower V128 is the shift result, and Q occupies the
1633 least significant bit of the upper V128. All other bits of the
1634 upper V128 are zero. */
1635 // Unsigned saturation, no rounding
1636 Iop_QandUQsh8x16, Iop_QandUQsh16x8,
1637 Iop_QandUQsh32x4, Iop_QandUQsh64x2,
1638 // Signed saturation, no rounding
1639 Iop_QandSQsh8x16, Iop_QandSQsh16x8,
1640 Iop_QandSQsh32x4, Iop_QandSQsh64x2,
1641
1642 // Unsigned saturation, rounding
1643 Iop_QandUQRsh8x16, Iop_QandUQRsh16x8,
1644 Iop_QandUQRsh32x4, Iop_QandUQRsh64x2,
1645 // Signed saturation, rounding
1646 Iop_QandSQRsh8x16, Iop_QandSQRsh16x8,
1647 Iop_QandSQRsh32x4, Iop_QandSQRsh64x2,
1648
sewardja6b61f02014-08-17 18:32:14 +00001649 /* VECTOR x VECTOR BIDIRECTIONAL (& MAYBE ROUNDING) SHIFT */
1650 /* All of type (V128, V128) -> V128 */
1651 /* The least significant 8 bits of each lane of the second
1652 operand are used as the shift amount, and interpreted signedly.
1653 Positive values mean a shift left, negative a shift right.
1654 There are also rounding variants, which add 2^(shift_amount-1)
1655 to the value before shifting, but only in the shift-right case.
1656
1657 For left shifts, the vacated places are filled with zeroes.
1658 For right shifts, the vacated places are filled with zeroes
1659 for the U variants and sign bits for the S variants. */
1660 // Signed and unsigned, non-rounding
1661 Iop_Sh8Sx16, Iop_Sh16Sx8, Iop_Sh32Sx4, Iop_Sh64Sx2,
1662 Iop_Sh8Ux16, Iop_Sh16Ux8, Iop_Sh32Ux4, Iop_Sh64Ux2,
1663
1664 // Signed and unsigned, rounding
1665 Iop_Rsh8Sx16, Iop_Rsh16Sx8, Iop_Rsh32Sx4, Iop_Rsh64Sx2,
1666 Iop_Rsh8Ux16, Iop_Rsh16Ux8, Iop_Rsh32Ux4, Iop_Rsh64Ux2,
1667
1668 /* The least significant 8 bits of each lane of the second
1669 operand are used as the shift amount, and interpreted signedly.
1670 Positive values mean a shift left, negative a shift right. The
1671 result is signedly or unsignedly saturated. There are also
1672 rounding variants, which add 2^(shift_amount-1) to the value before
1673 shifting, but only in the shift-right case. Vacated positions
1674 are filled with zeroes. IOW, it's either SHR or SHL, but not SAR.
1675 */
1676
sewardjecedd982014-08-11 14:02:47 +00001677 /* VECTOR x SCALAR SATURATING (& MAYBE ROUNDING) NARROWING SHIFT RIGHT */
1678 /* All of type (V128, I8) -> V128 */
1679 /* The first argument is shifted right, then narrowed to half the width
1680 by saturating it. The second argument is a scalar shift amount that
1681 applies to all lanes, and must be a value in the range 1 to lane_width.
1682 The shift may be done signedly (Sar variants) or unsignedly (Shr
1683 variants). The saturation is done according to the two signedness
1684 indicators at the end of the name. For example 64Sto32U means a
1685 signed 64 bit value is saturated into an unsigned 32 bit value.
1686 Additionally, the QRS variants do rounding, that is, they add the
1687 value (1 << (shift_amount-1)) to each source lane before shifting.
1688
1689 These operations return 65 bits: one bit ("Q") indicating whether
1690 saturation occurred, and the shift result. The result type is V128,
1691 of which the lower half is the shift result, and Q occupies the
1692 least significant bit of the upper half. All other bits of the
1693 upper half are zero. */
1694 // No rounding, sat U->U
1695 Iop_QandQShrNnarrow16Uto8Ux8,
1696 Iop_QandQShrNnarrow32Uto16Ux4, Iop_QandQShrNnarrow64Uto32Ux2,
1697 // No rounding, sat S->S
1698 Iop_QandQSarNnarrow16Sto8Sx8,
1699 Iop_QandQSarNnarrow32Sto16Sx4, Iop_QandQSarNnarrow64Sto32Sx2,
1700 // No rounding, sat S->U
1701 Iop_QandQSarNnarrow16Sto8Ux8,
1702 Iop_QandQSarNnarrow32Sto16Ux4, Iop_QandQSarNnarrow64Sto32Ux2,
1703
1704 // Rounding, sat U->U
1705 Iop_QandQRShrNnarrow16Uto8Ux8,
1706 Iop_QandQRShrNnarrow32Uto16Ux4, Iop_QandQRShrNnarrow64Uto32Ux2,
1707 // Rounding, sat S->S
1708 Iop_QandQRSarNnarrow16Sto8Sx8,
1709 Iop_QandQRSarNnarrow32Sto16Sx4, Iop_QandQRSarNnarrow64Sto32Sx2,
1710 // Rounding, sat S->U
1711 Iop_QandQRSarNnarrow16Sto8Ux8,
1712 Iop_QandQRSarNnarrow32Sto16Ux4, Iop_QandQRSarNnarrow64Sto32Ux2,
1713
sewardj5f438dd2011-06-16 11:36:23 +00001714 /* NARROWING (binary)
1715 -- narrow 2xV128 into 1xV128, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +00001716 /* See comments above w.r.t. U vs S issues in saturated narrowing. */
sewardj5f438dd2011-06-16 11:36:23 +00001717 Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1718 Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1719 Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1720 Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
carll48ae46b2013-10-01 15:45:54 +00001721 Iop_QNarrowBin64Sto32Sx4, Iop_QNarrowBin64Uto32Ux4,
carll0c74bb52013-08-12 18:01:40 +00001722 Iop_NarrowBin64to32x4,
sewardj164f9272004-12-09 00:39:32 +00001723
sewardj5f438dd2011-06-16 11:36:23 +00001724 /* NARROWING (unary) -- narrow V128 into I64 */
1725 Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
sewardj8b1715b2014-01-21 16:33:51 +00001726 /* Saturating narrowing from signed source to signed/unsigned
1727 destination */
sewardj5f438dd2011-06-16 11:36:23 +00001728 Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1729 Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1730 /* Saturating narrowing from unsigned source to unsigned destination */
1731 Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1732
1733 /* WIDENING -- sign or zero extend each element of the argument
1734 vector to the twice original size. The resulting vector consists of
sewardj2fdd4162010-08-22 12:59:02 +00001735 the same number of elements but each element and the vector itself
sewardj5f438dd2011-06-16 11:36:23 +00001736 are twice as wide.
sewardj2fdd4162010-08-22 12:59:02 +00001737 All operations are I64->V128.
1738 Example
sewardj5f438dd2011-06-16 11:36:23 +00001739 Iop_Widen32Sto64x2( [a, b] ) = [c, d]
sewardj2fdd4162010-08-22 12:59:02 +00001740 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
sewardj5f438dd2011-06-16 11:36:23 +00001741 Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1742 Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001743
1744 /* INTERLEAVING */
1745 /* Interleave lanes from low or high halves of
sewardj164f9272004-12-09 00:39:32 +00001746 operands. Most-significant result lane is from the left
1747 arg. */
1748 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1749 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001750 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
cerionf887b3e2005-09-13 16:34:28 +00001751 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001752 /* Interleave odd/even lanes of operands. Most-significant result lane
1753 is from the left arg. */
1754 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1755 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1756 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1757
1758 /* CONCATENATION -- build a new value by concatenating either
sewardj487559e2014-07-10 14:22:45 +00001759 the even or odd lanes of both operands. Note that
1760 Cat{Odd,Even}Lanes64x2 are identical to Interleave{HI,LO}64x2
1761 and so are omitted. */
sewardj2fdd4162010-08-22 12:59:02 +00001762 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1763 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1764
1765 /* GET elements of VECTOR
1766 GET is binop (V128, I8) -> I<elem_size> */
1767 /* Note: the arm back-end handles only constant second argument. */
1768 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
cerionf887b3e2005-09-13 16:34:28 +00001769
1770 /* DUPLICATING -- copy value to all lanes */
sewardj2fdd4162010-08-22 12:59:02 +00001771 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
1772
sewardje6b9bd92014-09-01 11:32:47 +00001773 /* SLICE -- produces the lowest 128 bits of (arg1:arg2) >> (8 * arg3).
1774 arg3 is a shift amount in bytes and may be between 0 and 16
1775 inclusive. When 0, the result is arg2; when 16, the result is arg1.
1776 Not all back ends handle all values. The arm64 back
1777 end handles only immediate arg3 values. */
1778 Iop_SliceV128, // (V128, V128, I8) -> V128
sewardj2fdd4162010-08-22 12:59:02 +00001779
sewardj33680352014-06-26 10:49:33 +00001780 /* REVERSE the order of chunks in vector lanes. Chunks must be
1781 smaller than the vector lanes (obviously) and so may be 8-,
1782 16- and 32-bit in size. See definitions of 64-bit SIMD
1783 versions above for examples. */
1784 Iop_Reverse8sIn16_x8,
1785 Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
1786 Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
sewardj715d1622014-06-26 12:39:05 +00001787 Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
cerionf887b3e2005-09-13 16:34:28 +00001788
1789 /* PERMUTING -- copy src bytes to dst,
sewardjdc1f9132005-10-22 12:49:49 +00001790 as indexed by control vector bytes:
1791 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1792 argR[i] values may only be in the range 0 .. 15, else behaviour
1793 is undefined. */
sewardj2fdd4162010-08-22 12:59:02 +00001794 Iop_Perm8x16,
sewardjd8bca7e2012-06-20 11:46:19 +00001795 Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
sewardj2fdd4162010-08-22 12:59:02 +00001796
sewardj78a20592012-12-13 18:29:56 +00001797 /* MISC CONVERSION -- get high bits of each byte lane, a la
1798 x86/amd64 pmovmskb */
sewardj0e7d2802013-01-26 11:39:13 +00001799 Iop_GetMSBs8x16, /* V128 -> I16 */
sewardj78a20592012-12-13 18:29:56 +00001800
sewardj2fdd4162010-08-22 12:59:02 +00001801 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
sewardj1ddee212014-08-24 14:00:19 +00001802 See floating-point equivalents for details. */
1803 Iop_RecipEst32Ux4, Iop_RSqrtEst32Ux4,
sewardjc4530ae2012-05-21 10:18:49 +00001804
Elliott Hughesa0664b92017-04-18 17:46:52 -07001805 /* 128-bit multipy by 10 instruction, result is lower 128-bits */
1806 Iop_MulI128by10,
1807
1808 /* 128-bit multipy by 10 instruction, result is carry out from the MSB */
1809 Iop_MulI128by10Carry,
1810
1811 /* 128-bit multipy by 10 instruction, result is lower 128-bits of the
1812 * source times 10 plus the carry in
1813 */
1814 Iop_MulI128by10E,
1815
1816 /* 128-bit multipy by 10 instruction, result is carry out from the MSB
1817 * of the source times 10 plus the carry in
1818 */
1819 Iop_MulI128by10ECarry,
1820
sewardjc4530ae2012-05-21 10:18:49 +00001821 /* ------------------ 256-bit SIMD Integer. ------------------ */
1822
1823 /* Pack/unpack */
sewardj4b1cc832012-06-13 11:10:20 +00001824 Iop_V256to64_0, // V256 -> I64, extract least significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001825 Iop_V256to64_1,
1826 Iop_V256to64_2,
sewardj4b1cc832012-06-13 11:10:20 +00001827 Iop_V256to64_3, // V256 -> I64, extract most significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001828
sewardj56c30312012-06-12 08:45:39 +00001829 Iop_64x4toV256, // (I64,I64,I64,I64)->V256
sewardjc4530ae2012-05-21 10:18:49 +00001830 // first arg is most significant lane
sewardj56c30312012-06-12 08:45:39 +00001831
sewardj4b1cc832012-06-13 11:10:20 +00001832 Iop_V256toV128_0, // V256 -> V128, less significant lane
1833 Iop_V256toV128_1, // V256 -> V128, more significant lane
1834 Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1835
1836 Iop_AndV256,
sewardj2a2bda92012-06-14 23:32:02 +00001837 Iop_OrV256,
sewardj4b1cc832012-06-13 11:10:20 +00001838 Iop_XorV256,
sewardj2a2bda92012-06-14 23:32:02 +00001839 Iop_NotV256,
sewardj4b1cc832012-06-13 11:10:20 +00001840
sewardj23db8a02012-06-25 07:46:18 +00001841 /* MISC (vector integer cmp != 0) */
sewardjcc3d2192013-03-27 11:37:33 +00001842 Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1843
1844 Iop_Add8x32, Iop_Add16x16, Iop_Add32x8, Iop_Add64x4,
1845 Iop_Sub8x32, Iop_Sub16x16, Iop_Sub32x8, Iop_Sub64x4,
1846
1847 Iop_CmpEQ8x32, Iop_CmpEQ16x16, Iop_CmpEQ32x8, Iop_CmpEQ64x4,
1848 Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4,
1849
1850 Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4,
1851 Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4,
1852 Iop_SarN16x16, Iop_SarN32x8,
1853
1854 Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8,
1855 Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8,
1856 Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8,
1857 Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8,
1858
1859 Iop_Mul16x16, Iop_Mul32x8,
1860 Iop_MulHi16Ux16, Iop_MulHi16Sx16,
1861
1862 Iop_QAdd8Ux32, Iop_QAdd16Ux16,
1863 Iop_QAdd8Sx32, Iop_QAdd16Sx16,
1864 Iop_QSub8Ux32, Iop_QSub16Ux16,
1865 Iop_QSub8Sx32, Iop_QSub16Sx16,
1866
1867 Iop_Avg8Ux32, Iop_Avg16Ux16,
1868
1869 Iop_Perm32x8,
sewardj23db8a02012-06-25 07:46:18 +00001870
carll7deaf952013-10-15 18:11:20 +00001871 /* (V128, V128) -> V128 */
1872 Iop_CipherV128, Iop_CipherLV128, Iop_CipherSV128,
1873 Iop_NCipherV128, Iop_NCipherLV128,
1874
1875 /* Hash instructions, Federal Information Processing Standards
1876 * Publication 180-3 Secure Hash Standard. */
1877 /* (V128, I8) -> V128; The I8 input arg is (ST | SIX), where ST and
1878 * SIX are fields from the insn. See ISA 2.07 description of
1879 * vshasigmad and vshasigmaw insns.*/
1880 Iop_SHA512, Iop_SHA256,
1881
sewardj56c30312012-06-12 08:45:39 +00001882 /* ------------------ 256-bit SIMD FP. ------------------ */
sewardj9571dc02014-01-26 18:34:23 +00001883
1884 /* ternary :: IRRoundingMode(I32) x V256 x V256 -> V256 */
1885 Iop_Add64Fx4, Iop_Sub64Fx4, Iop_Mul64Fx4, Iop_Div64Fx4,
1886 Iop_Add32Fx8, Iop_Sub32Fx8, Iop_Mul32Fx8, Iop_Div32Fx8,
sewardjf0ad4f82012-06-19 06:57:59 +00001887
1888 Iop_Sqrt32Fx8,
1889 Iop_Sqrt64Fx4,
sewardj1ddee212014-08-24 14:00:19 +00001890 Iop_RSqrtEst32Fx8,
1891 Iop_RecipEst32Fx8,
sewardj8eb7ae82012-06-24 14:00:27 +00001892
1893 Iop_Max32Fx8, Iop_Min32Fx8,
florian2245ce92012-08-28 16:49:30 +00001894 Iop_Max64Fx4, Iop_Min64Fx4,
1895 Iop_LAST /* must be the last enumerator */
sewardjac6b7122004-06-27 01:03:57 +00001896 }
1897 IROp;
sewardjec6ad592004-06-20 12:26:53 +00001898
sewardj57c10c82006-11-15 02:57:05 +00001899/* Pretty-print an op. */
sewardj35421a32004-07-05 13:12:34 +00001900extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +00001901
florian2074a442015-10-16 17:26:22 +00001902/* For a given operand return the types of its arguments and its result. */
1903extern void typeOfPrimop ( IROp op,
1904 /*OUTs*/ IRType* t_dst, IRType* t_arg1,
1905 IRType* t_arg2, IRType* t_arg3, IRType* t_arg4 );
sewardje3d0d2e2004-06-27 10:42:44 +00001906
florian79e5a482013-06-06 19:12:46 +00001907/* Encoding of IEEE754-specified rounding modes.
sewardjf1b5b1a2006-02-03 22:54:17 +00001908 Note, various front and back ends rely on the actual numerical
1909 values of these, so do not change them. */
sewardjc9868d72004-09-12 19:19:17 +00001910typedef
sewardjf1b5b1a2006-02-03 22:54:17 +00001911 enum {
florian79e5a482013-06-06 19:12:46 +00001912 Irrm_NEAREST = 0, // Round to nearest, ties to even
1913 Irrm_NegINF = 1, // Round to negative infinity
1914 Irrm_PosINF = 2, // Round to positive infinity
1915 Irrm_ZERO = 3, // Round toward zero
1916 Irrm_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0
sewardjbbcf1882014-01-12 12:49:10 +00001917 Irrm_PREPARE_SHORTER = 5, // Round to prepare for shorter
florian79e5a482013-06-06 19:12:46 +00001918 // precision
1919 Irrm_AWAY_FROM_ZERO = 6, // Round to away from 0
1920 Irrm_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0
sewardjf1b5b1a2006-02-03 22:54:17 +00001921 }
sewardjc9868d72004-09-12 19:19:17 +00001922 IRRoundingMode;
1923
floriandaa40842012-12-21 20:24:24 +00001924/* Binary floating point comparison result values.
sewardjc9868d72004-09-12 19:19:17 +00001925 This is also derived from what IA32 does. */
1926typedef
1927 enum {
1928 Ircr_UN = 0x45,
1929 Ircr_LT = 0x01,
1930 Ircr_GT = 0x00,
1931 Ircr_EQ = 0x40
1932 }
floriandaa40842012-12-21 20:24:24 +00001933 IRCmpFResult;
sewardjc9868d72004-09-12 19:19:17 +00001934
floriandaa40842012-12-21 20:24:24 +00001935typedef IRCmpFResult IRCmpF32Result;
1936typedef IRCmpFResult IRCmpF64Result;
1937typedef IRCmpFResult IRCmpF128Result;
1938
1939/* Decimal floating point result values. */
1940typedef IRCmpFResult IRCmpDResult;
1941typedef IRCmpDResult IRCmpD64Result;
1942typedef IRCmpDResult IRCmpD128Result;
sewardjc9868d72004-09-12 19:19:17 +00001943
sewardjc97096c2004-06-30 09:28:04 +00001944/* ------------------ Expressions ------------------ */
sewardjd1725d12004-08-12 20:46:53 +00001945
florianeadea2e2012-06-06 12:53:14 +00001946typedef struct _IRQop IRQop; /* forward declaration */
1947typedef struct _IRTriop IRTriop; /* forward declaration */
florian96d7cc32012-06-01 20:41:24 +00001948
1949
sewardj57c10c82006-11-15 02:57:05 +00001950/* The different kinds of expressions. Their meaning is explained below
1951 in the comments for IRExpr. */
sewardje3d0d2e2004-06-27 10:42:44 +00001952typedef
sewardjb3bce0e2004-09-14 23:20:10 +00001953 enum {
sewardjcfe046e2013-01-17 14:23:53 +00001954 Iex_Binder=0x1900,
sewardj57c10c82006-11-15 02:57:05 +00001955 Iex_Get,
1956 Iex_GetI,
sewardjdd40fdf2006-12-24 02:20:24 +00001957 Iex_RdTmp,
sewardj57c10c82006-11-15 02:57:05 +00001958 Iex_Qop,
1959 Iex_Triop,
1960 Iex_Binop,
1961 Iex_Unop,
1962 Iex_Load,
1963 Iex_Const,
florian99dd03e2013-01-29 03:56:06 +00001964 Iex_ITE,
florian90419562013-08-15 20:54:52 +00001965 Iex_CCall,
1966 Iex_VECRET,
Elliott Hughesed398002017-06-21 14:41:24 -07001967 Iex_GSPTR
sewardjb3bce0e2004-09-14 23:20:10 +00001968 }
sewardje3d0d2e2004-06-27 10:42:44 +00001969 IRExprTag;
1970
sewardj57c10c82006-11-15 02:57:05 +00001971/* An expression. Stored as a tagged union. 'tag' indicates what kind
1972 of expression this is. 'Iex' is the union that holds the fields. If
1973 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1974 expression, and the fields can be accessed with
1975 'e.Iex.Load.<fieldname>'.
1976
1977 For each kind of expression, we show what it looks like when
1978 pretty-printed with ppIRExpr().
1979*/
1980typedef
1981 struct _IRExpr
sewardje3d0d2e2004-06-27 10:42:44 +00001982 IRExpr;
1983
sewardj57c10c82006-11-15 02:57:05 +00001984struct _IRExpr {
1985 IRExprTag tag;
1986 union {
1987 /* Used only in pattern matching within Vex. Should not be seen
1988 outside of Vex. */
1989 struct {
1990 Int binder;
1991 } Binder;
1992
1993 /* Read a guest register, at a fixed offset in the guest state.
1994 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1995 */
1996 struct {
1997 Int offset; /* Offset into the guest state */
1998 IRType ty; /* Type of the value being read */
1999 } Get;
2000
2001 /* Read a guest register at a non-fixed offset in the guest
2002 state. This allows circular indexing into parts of the guest
2003 state, which is essential for modelling situations where the
2004 identity of guest registers is not known until run time. One
2005 example is the x87 FP register stack.
2006
2007 The part of the guest state to be treated as a circular array
sewardjdd40fdf2006-12-24 02:20:24 +00002008 is described in the IRRegArray 'descr' field. It holds the
sewardj57c10c82006-11-15 02:57:05 +00002009 offset of the first element in the array, the type of each
2010 element, and the number of elements.
2011
2012 The array index is indicated rather indirectly, in a way
2013 which makes optimisation easy: as the sum of variable part
2014 (the 'ix' field) and a constant offset (the 'bias' field).
2015
2016 Since the indexing is circular, the actual array index to use
2017 is computed as (ix + bias) % num-of-elems-in-the-array.
2018
2019 Here's an example. The description
2020
2021 (96:8xF64)[t39,-7]
2022
2023 describes an array of 8 F64-typed values, the
2024 guest-state-offset of the first being 96. This array is
2025 being indexed at (t39 - 7) % 8.
2026
2027 It is important to get the array size/type exactly correct
2028 since IR optimisation looks closely at such info in order to
2029 establish aliasing/non-aliasing between seperate GetI and
2030 PutI events, which is used to establish when they can be
2031 reordered, etc. Putting incorrect info in will lead to
2032 obscure IR optimisation bugs.
2033
2034 ppIRExpr output: GETI<descr>[<ix>,<bias]
2035 eg. GETI(128:8xI8)[t1,0]
2036 */
2037 struct {
sewardjdd40fdf2006-12-24 02:20:24 +00002038 IRRegArray* descr; /* Part of guest state treated as circular */
2039 IRExpr* ix; /* Variable part of index into array */
2040 Int bias; /* Constant offset part of index into array */
sewardj57c10c82006-11-15 02:57:05 +00002041 } GetI;
2042
2043 /* The value held by a temporary.
2044 ppIRExpr output: t<tmp>, eg. t1
2045 */
2046 struct {
2047 IRTemp tmp; /* The temporary number */
sewardjdd40fdf2006-12-24 02:20:24 +00002048 } RdTmp;
sewardj57c10c82006-11-15 02:57:05 +00002049
2050 /* A quaternary operation.
2051 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
2052 eg. MAddF64r32(t1, t2, t3, t4)
2053 */
2054 struct {
florian96d7cc32012-06-01 20:41:24 +00002055 IRQop* details;
sewardj57c10c82006-11-15 02:57:05 +00002056 } Qop;
2057
2058 /* A ternary operation.
2059 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
2060 eg. MulF64(1, 2.0, 3.0)
2061 */
2062 struct {
florian420bfa92012-06-02 20:29:22 +00002063 IRTriop* details;
sewardj57c10c82006-11-15 02:57:05 +00002064 } Triop;
2065
2066 /* A binary operation.
2067 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
2068 */
2069 struct {
2070 IROp op; /* op-code */
2071 IRExpr* arg1; /* operand 1 */
2072 IRExpr* arg2; /* operand 2 */
2073 } Binop;
2074
2075 /* A unary operation.
2076 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
2077 */
2078 struct {
2079 IROp op; /* op-code */
2080 IRExpr* arg; /* operand */
2081 } Unop;
2082
sewardje768e922009-11-26 17:17:37 +00002083 /* A load from memory -- a normal load, not a load-linked.
2084 Load-Linkeds (and Store-Conditionals) are instead represented
2085 by IRStmt.LLSC since Load-Linkeds have side effects and so
2086 are not semantically valid IRExpr's.
sewardj57c10c82006-11-15 02:57:05 +00002087 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
2088 */
2089 struct {
2090 IREndness end; /* Endian-ness of the load */
2091 IRType ty; /* Type of the loaded value */
2092 IRExpr* addr; /* Address being loaded from */
2093 } Load;
2094
2095 /* A constant-valued expression.
2096 ppIRExpr output: <con>, eg. 0x4:I32
2097 */
2098 struct {
2099 IRConst* con; /* The constant itself */
2100 } Const;
2101
2102 /* A call to a pure (no side-effects) helper C function.
2103
2104 With the 'cee' field, 'name' is the function's name. It is
2105 only used for pretty-printing purposes. The address to call
2106 (host address, of course) is stored in the 'addr' field
2107 inside 'cee'.
2108
2109 The 'args' field is a NULL-terminated array of arguments.
2110 The stated return IRType, and the implied argument types,
2111 must match that of the function being called well enough so
2112 that the back end can actually generate correct code for the
2113 call.
2114
2115 The called function **must** satisfy the following:
2116
2117 * no side effects -- must be a pure function, the result of
2118 which depends only on the passed parameters.
2119
2120 * it may not look at, nor modify, any of the guest state
2121 since that would hide guest state transitions from
2122 instrumenters
2123
2124 * it may not access guest memory, since that would hide
2125 guest memory transactions from the instrumenters
2126
florian52af7bc2012-05-12 03:44:49 +00002127 * it must not assume that arguments are being evaluated in a
2128 particular order. The oder of evaluation is unspecified.
2129
sewardj57c10c82006-11-15 02:57:05 +00002130 This is restrictive, but makes the semantics clean, and does
2131 not interfere with IR optimisation.
2132
2133 If you want to call a helper which can mess with guest state
2134 and/or memory, instead use Ist_Dirty. This is a lot more
2135 flexible, but you have to give a bunch of details about what
2136 the helper does (and you better be telling the truth,
2137 otherwise any derived instrumentation will be wrong). Also
2138 Ist_Dirty inhibits various IR optimisations and so can cause
2139 quite poor code to be generated. Try to avoid it.
2140
sewardj74142b82013-08-08 10:28:59 +00002141 In principle it would be allowable to have the arg vector
Elliott Hughesed398002017-06-21 14:41:24 -07002142 contain an IRExpr_VECRET(), although not IRExpr_GSPTR(). However,
florian90419562013-08-15 20:54:52 +00002143 at the moment there is no requirement for clean helper calls to
2144 be able to return V128 or V256 values. Hence this is not allowed.
sewardj74142b82013-08-08 10:28:59 +00002145
sewardj57c10c82006-11-15 02:57:05 +00002146 ppIRExpr output: <cee>(<args>):<retty>
2147 eg. foo{0x80489304}(t1, t2):I32
2148 */
2149 struct {
2150 IRCallee* cee; /* Function to call. */
2151 IRType retty; /* Type of return value. */
2152 IRExpr** args; /* Vector of argument expressions. */
2153 } CCall;
2154
florian99dd03e2013-01-29 03:56:06 +00002155 /* A ternary if-then-else operator. It returns iftrue if cond is
2156 nonzero, iffalse otherwise. Note that it is STRICT, ie. both
2157 iftrue and iffalse are evaluated in all cases.
sewardj57c10c82006-11-15 02:57:05 +00002158
florian99dd03e2013-01-29 03:56:06 +00002159 ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>),
2160 eg. ITE(t6,t7,t8)
sewardj57c10c82006-11-15 02:57:05 +00002161 */
2162 struct {
2163 IRExpr* cond; /* Condition */
florian99dd03e2013-01-29 03:56:06 +00002164 IRExpr* iftrue; /* True expression */
2165 IRExpr* iffalse; /* False expression */
2166 } ITE;
sewardj57c10c82006-11-15 02:57:05 +00002167 } Iex;
2168};
2169
sewardjcfe046e2013-01-17 14:23:53 +00002170/* Expression auxiliaries: a ternary expression. */
florian420bfa92012-06-02 20:29:22 +00002171struct _IRTriop {
2172 IROp op; /* op-code */
2173 IRExpr* arg1; /* operand 1 */
2174 IRExpr* arg2; /* operand 2 */
2175 IRExpr* arg3; /* operand 3 */
2176};
2177
sewardjcfe046e2013-01-17 14:23:53 +00002178/* Expression auxiliaries: a quarternary expression. */
florian96d7cc32012-06-01 20:41:24 +00002179struct _IRQop {
2180 IROp op; /* op-code */
2181 IRExpr* arg1; /* operand 1 */
2182 IRExpr* arg2; /* operand 2 */
2183 IRExpr* arg3; /* operand 3 */
2184 IRExpr* arg4; /* operand 4 */
2185};
2186
sewardj74142b82013-08-08 10:28:59 +00002187
florian90419562013-08-15 20:54:52 +00002188/* Two special kinds of IRExpr, which can ONLY be used in
sewardj74142b82013-08-08 10:28:59 +00002189 argument lists for dirty helper calls (IRDirty.args) and in NO
florian90419562013-08-15 20:54:52 +00002190 OTHER PLACES. And then only in very limited ways. */
sewardj74142b82013-08-08 10:28:59 +00002191
2192/* Denotes an argument which (in the helper) takes a pointer to a
2193 (naturally aligned) V128 or V256, into which the helper is expected
florian90419562013-08-15 20:54:52 +00002194 to write its result. Use of IRExpr_VECRET() is strictly
sewardj74142b82013-08-08 10:28:59 +00002195 controlled. If the helper returns a V128 or V256 value then
florian90419562013-08-15 20:54:52 +00002196 IRExpr_VECRET() must appear exactly once in the arg list, although
sewardj74142b82013-08-08 10:28:59 +00002197 it can appear anywhere, and the helper must have a C 'void' return
florian90419562013-08-15 20:54:52 +00002198 type. If the helper returns any other type, IRExpr_VECRET() may
sewardj74142b82013-08-08 10:28:59 +00002199 not appear in the argument list. */
sewardj74142b82013-08-08 10:28:59 +00002200
2201/* Denotes an void* argument which is passed to the helper, which at
2202 run time will point to the thread's guest state area. This can
2203 only appear at most once in an argument list, and it may not appear
2204 at all in argument lists for clean helper calls. */
sewardj74142b82013-08-08 10:28:59 +00002205
Elliott Hughesed398002017-06-21 14:41:24 -07002206static inline Bool is_IRExpr_VECRET_or_GSPTR ( const IRExpr* e ) {
2207 return e->tag == Iex_VECRET || e->tag == Iex_GSPTR;
sewardj74142b82013-08-08 10:28:59 +00002208}
2209
2210
sewardj57c10c82006-11-15 02:57:05 +00002211/* Expression constructors. */
sewardj443cd9d2004-07-18 23:06:45 +00002212extern IRExpr* IRExpr_Binder ( Int binder );
2213extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjdd40fdf2006-12-24 02:20:24 +00002214extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
2215extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
sewardj40c80262006-02-08 19:30:46 +00002216extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
2217 IRExpr* arg3, IRExpr* arg4 );
sewardjb183b852006-02-03 16:08:03 +00002218extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
2219 IRExpr* arg2, IRExpr* arg3 );
sewardj443cd9d2004-07-18 23:06:45 +00002220extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
2221extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
sewardje768e922009-11-26 17:17:37 +00002222extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
sewardj443cd9d2004-07-18 23:06:45 +00002223extern IRExpr* IRExpr_Const ( IRConst* con );
sewardj8ea867b2004-10-30 19:03:02 +00002224extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
florian99dd03e2013-01-29 03:56:06 +00002225extern IRExpr* IRExpr_ITE ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse );
florian90419562013-08-15 20:54:52 +00002226extern IRExpr* IRExpr_VECRET ( void );
Elliott Hughesed398002017-06-21 14:41:24 -07002227extern IRExpr* IRExpr_GSPTR ( void );
sewardje3d0d2e2004-06-27 10:42:44 +00002228
sewardj57c10c82006-11-15 02:57:05 +00002229/* Deep-copy an IRExpr. */
florian0b70efa2014-09-21 21:53:39 +00002230extern IRExpr* deepCopyIRExpr ( const IRExpr* );
sewardj695cff92004-10-13 14:50:14 +00002231
sewardj57c10c82006-11-15 02:57:05 +00002232/* Pretty-print an IRExpr. */
florian0b70efa2014-09-21 21:53:39 +00002233extern void ppIRExpr ( const IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00002234
sewardj57c10c82006-11-15 02:57:05 +00002235/* NULL-terminated IRExpr vector constructors, suitable for
2236 use as arg lists in clean/dirty helper calls. */
sewardjc5fc7aa2004-10-27 23:00:55 +00002237extern IRExpr** mkIRExprVec_0 ( void );
sewardjf9655262004-10-31 20:02:16 +00002238extern IRExpr** mkIRExprVec_1 ( IRExpr* );
2239extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
2240extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
2241extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
sewardj78ec32b2007-01-08 05:09:55 +00002242extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2243 IRExpr* );
2244extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2245 IRExpr*, IRExpr* );
2246extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
sewardjf32c67d2004-11-08 13:10:44 +00002247 IRExpr*, IRExpr*, IRExpr* );
sewardj2fdd4162010-08-22 12:59:02 +00002248extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
Elliott Hughesa0664b92017-04-18 17:46:52 -07002249 IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2250extern IRExpr** mkIRExprVec_9 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2251 IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2252extern IRExpr** mkIRExprVec_13 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2253 IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2254 IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
sewardjc5fc7aa2004-10-27 23:00:55 +00002255
sewardj57c10c82006-11-15 02:57:05 +00002256/* IRExpr copiers:
sewardjdd40fdf2006-12-24 02:20:24 +00002257 - shallowCopy: shallow-copy (ie. create a new vector that shares the
sewardj57c10c82006-11-15 02:57:05 +00002258 elements with the original).
sewardjdd40fdf2006-12-24 02:20:24 +00002259 - deepCopy: deep-copy (ie. create a completely new vector). */
2260extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
florian0b70efa2014-09-21 21:53:39 +00002261extern IRExpr** deepCopyIRExprVec ( IRExpr *const * );
sewardjc5fc7aa2004-10-27 23:00:55 +00002262
sewardjf9655262004-10-31 20:02:16 +00002263/* Make a constant expression from the given host word taking into
sewardj57c10c82006-11-15 02:57:05 +00002264 account (of course) the host word size. */
sewardj49651f42004-10-28 22:11:04 +00002265extern IRExpr* mkIRExpr_HWord ( HWord );
2266
sewardjf9655262004-10-31 20:02:16 +00002267/* Convenience function for constructing clean helper calls. */
2268extern
2269IRExpr* mkIRExprCCall ( IRType retty,
florian1ff47562012-10-21 02:09:51 +00002270 Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002271 IRExpr** args );
2272
sewardj49651f42004-10-28 22:11:04 +00002273
sewardj57c10c82006-11-15 02:57:05 +00002274/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
2275 * Iex_Const). */
florian0b70efa2014-09-21 21:53:39 +00002276static inline Bool isIRAtom ( const IRExpr* e ) {
sewardjdd40fdf2006-12-24 02:20:24 +00002277 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
sewardj49651f42004-10-28 22:11:04 +00002278}
2279
sewardj496a58d2005-03-20 18:44:44 +00002280/* Are these two IR atoms identical? Causes an assertion
2281 failure if they are passed non-atoms. */
florian0b70efa2014-09-21 21:53:39 +00002282extern Bool eqIRAtom ( const IRExpr*, const IRExpr* );
sewardj496a58d2005-03-20 18:44:44 +00002283
sewardje87b4842004-07-10 12:23:30 +00002284
sewardj893aada2004-11-29 19:57:54 +00002285/* ------------------ Jump kinds ------------------ */
2286
2287/* This describes hints which can be passed to the dispatcher at guest
2288 control-flow transfer points.
sewardj7ce9d152005-03-15 16:54:13 +00002289
sewardj05f5e012014-05-04 10:52:11 +00002290 Re Ijk_InvalICache and Ijk_FlushDCache: the guest state _must_ have
2291 two pseudo-registers, guest_CMSTART and guest_CMLEN, which specify
2292 the start and length of the region to be invalidated. CM stands
2293 for "Cache Management". These are both the size of a guest word.
2294 It is the responsibility of the relevant toIR.c to ensure that
2295 these are filled in with suitable values before issuing a jump of
2296 kind Ijk_InvalICache or Ijk_FlushDCache.
sewardj9dd9cf12006-01-20 14:13:55 +00002297
sewardj05f5e012014-05-04 10:52:11 +00002298 Ijk_InvalICache requests invalidation of translations taken from
2299 the requested range. Ijk_FlushDCache requests flushing of the D
2300 cache for the specified range.
sewardj65902992014-05-03 21:20:56 +00002301
sewardj9dd9cf12006-01-20 14:13:55 +00002302 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
florian6ef84be2012-08-26 03:20:07 +00002303 pseudo-register guest_EMNOTE, which is 32-bits regardless of the
2304 host or guest word size. That register should be made to hold a
2305 VexEmNote value to indicate the reason for the exit.
sewardj9dd9cf12006-01-20 14:13:55 +00002306
2307 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
2308 cannot continue) and so the jump destination can be anything.
sewardje86310f2009-03-19 22:21:40 +00002309
2310 Re Ijk_Sys_ (syscall jumps): the guest state must have a
2311 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
2312 word. Front ends should set this to be the IP at the most recently
2313 executed kernel-entering (system call) instruction. This makes it
2314 very much easier (viz, actually possible at all) to back up the
2315 guest to restart a syscall that has been interrupted by a signal.
sewardj893aada2004-11-29 19:57:54 +00002316*/
2317typedef
sewardjc6f970f2012-04-02 21:54:49 +00002318 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002319 Ijk_INVALID=0x1A00,
sewardjc6f970f2012-04-02 21:54:49 +00002320 Ijk_Boring, /* not interesting; just goto next */
sewardj893aada2004-11-29 19:57:54 +00002321 Ijk_Call, /* guest is doing a call */
2322 Ijk_Ret, /* guest is doing a return */
2323 Ijk_ClientReq, /* do guest client req before continuing */
sewardj893aada2004-11-29 19:57:54 +00002324 Ijk_Yield, /* client is yielding to thread scheduler */
sewardj52444cb2004-12-13 14:09:01 +00002325 Ijk_EmWarn, /* report emulation warning before continuing */
sewardj9dd9cf12006-01-20 14:13:55 +00002326 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
florian0b390082012-08-25 02:01:25 +00002327 Ijk_NoDecode, /* current instruction cannot be decoded */
sewardj7ce9d152005-03-15 16:54:13 +00002328 Ijk_MapFail, /* Vex-provided address translation failed */
sewardj05f5e012014-05-04 10:52:11 +00002329 Ijk_InvalICache, /* Inval icache for range [CMSTART, +CMLEN) */
2330 Ijk_FlushDCache, /* Flush dcache for range [CMSTART, +CMLEN) */
sewardjce02aa72006-01-12 12:27:58 +00002331 Ijk_NoRedir, /* Jump to un-redirected guest addr */
dejanj0e006f22014-02-19 11:56:29 +00002332 Ijk_SigILL, /* current instruction synths SIGILL */
sewardj0f500042007-08-29 09:09:17 +00002333 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
2334 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
sewardje9d8a262009-07-01 08:06:34 +00002335 Ijk_SigBUS, /* current instruction synths SIGBUS */
petarja6a19862012-10-19 14:55:58 +00002336 Ijk_SigFPE_IntDiv, /* current instruction synths SIGFPE - IntDiv */
2337 Ijk_SigFPE_IntOvf, /* current instruction synths SIGFPE - IntOvf */
sewardj4fa325a2005-11-03 13:27:24 +00002338 /* Unfortunately, various guest-dependent syscall kinds. They
2339 all mean: do a syscall before continuing. */
tomf0bb6792014-02-09 11:40:20 +00002340 Ijk_Sys_syscall, /* amd64/x86 'syscall', ppc 'sc', arm 'svc #0' */
sewardj4fa325a2005-11-03 13:27:24 +00002341 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
2342 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
sewardjd660d412008-12-03 21:29:59 +00002343 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
2344 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
sewardj3e5d82d2015-07-21 14:43:23 +00002345 Ijk_Sys_int145, /* amd64/x86 'int $0x91' */
2346 Ijk_Sys_int210, /* amd64/x86 'int $0xD2' */
sewardj4fa325a2005-11-03 13:27:24 +00002347 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes
2348 invalid at the point this happens. */
sewardj893aada2004-11-29 19:57:54 +00002349 }
2350 IRJumpKind;
2351
2352extern void ppIRJumpKind ( IRJumpKind );
2353
2354
sewardjb3bce0e2004-09-14 23:20:10 +00002355/* ------------------ Dirty helper calls ------------------ */
sewardje87b4842004-07-10 12:23:30 +00002356
sewardj57c10c82006-11-15 02:57:05 +00002357/* A dirty call is a flexible mechanism for calling (possibly
2358 conditionally) a helper function or procedure. The helper function
2359 may read, write or modify client memory, and may read, write or
2360 modify client state. It can take arguments and optionally return a
2361 value. It may return different results and/or do different things
2362 when called repeatedly with the same arguments, by means of storing
2363 private state.
sewardje87b4842004-07-10 12:23:30 +00002364
sewardjc5fc7aa2004-10-27 23:00:55 +00002365 If a value is returned, it is assigned to the nominated return
2366 temporary.
sewardjb3bce0e2004-09-14 23:20:10 +00002367
2368 Dirty calls are statements rather than expressions for obvious
sewardj57c10c82006-11-15 02:57:05 +00002369 reasons. If a dirty call is marked as writing guest state, any
sewardjcfe046e2013-01-17 14:23:53 +00002370 pre-existing values derived from the written parts of the guest
2371 state are invalid. Similarly, if the dirty call is stated as
2372 writing memory, any pre-existing loaded values are invalidated by
2373 it.
sewardjb3bce0e2004-09-14 23:20:10 +00002374
2375 In order that instrumentation is possible, the call must state, and
sewardj57c10c82006-11-15 02:57:05 +00002376 state correctly:
sewardjb3bce0e2004-09-14 23:20:10 +00002377
sewardjcfe046e2013-01-17 14:23:53 +00002378 * Whether it reads, writes or modifies memory, and if so where.
sewardjb3bce0e2004-09-14 23:20:10 +00002379
sewardjcfe046e2013-01-17 14:23:53 +00002380 * Whether it reads, writes or modifies guest state, and if so which
2381 pieces. Several pieces may be stated, and their extents must be
2382 known at translation-time. Each piece is allowed to repeat some
2383 number of times at a fixed interval, if required.
sewardjc5fc7aa2004-10-27 23:00:55 +00002384
2385 Normally, code is generated to pass just the args to the helper.
Elliott Hughesed398002017-06-21 14:41:24 -07002386 However, if IRExpr_GSPTR() is present in the argument list (at most
2387 one instance is allowed), then the guest state pointer is passed for
sewardj74142b82013-08-08 10:28:59 +00002388 that arg, so that the callee can access the guest state. It is
Elliott Hughesed398002017-06-21 14:41:24 -07002389 invalid for .nFxState to be zero but IRExpr_GSPTR() to be present,
sewardj74142b82013-08-08 10:28:59 +00002390 since .nFxState==0 is a claim that the call does not access guest
2391 state.
sewardjb8385d82004-11-02 01:34:15 +00002392
2393 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
sewardjcfe046e2013-01-17 14:23:53 +00002394 arguments and 'mFx' are evaluated REGARDLESS of the guard value.
2395 The order of argument evaluation is unspecified. The guard
2396 expression is evaluated AFTER the arguments and 'mFx' have been
2397 evaluated. 'mFx' is expected (by Memcheck) to be a defined value
2398 even if the guard evaluates to false.
sewardje87b4842004-07-10 12:23:30 +00002399*/
sewardjc97096c2004-06-30 09:28:04 +00002400
sewardja0e83b02005-01-06 12:36:38 +00002401#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
sewardjb3bce0e2004-09-14 23:20:10 +00002402
sewardj57c10c82006-11-15 02:57:05 +00002403/* Effects on resources (eg. registers, memory locations) */
sewardjb3bce0e2004-09-14 23:20:10 +00002404typedef
2405 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002406 Ifx_None=0x1B00, /* no effect */
sewardj17442fe2004-09-20 14:54:28 +00002407 Ifx_Read, /* reads the resource */
2408 Ifx_Write, /* writes the resource */
2409 Ifx_Modify, /* modifies the resource */
sewardjb3bce0e2004-09-14 23:20:10 +00002410 }
2411 IREffect;
2412
sewardj57c10c82006-11-15 02:57:05 +00002413/* Pretty-print an IREffect */
sewardjb3bce0e2004-09-14 23:20:10 +00002414extern void ppIREffect ( IREffect );
2415
sewardjb3bce0e2004-09-14 23:20:10 +00002416typedef
sewardjc9069f22012-06-01 16:09:50 +00002417 struct _IRDirty {
sewardjf5dfa3b2012-07-10 16:41:46 +00002418 /* What to call, and details of args/results. .guard must be
sewardjcfe046e2013-01-17 14:23:53 +00002419 non-NULL. If .tmp is not IRTemp_INVALID, then the call
2420 returns a result which is placed in .tmp. If at runtime the
2421 guard evaluates to false, .tmp has an 0x555..555 bit pattern
2422 written to it. Hence conditional calls that assign .tmp are
sewardjf5dfa3b2012-07-10 16:41:46 +00002423 allowed. */
sewardj8ea867b2004-10-30 19:03:02 +00002424 IRCallee* cee; /* where to call */
sewardjb8385d82004-11-02 01:34:15 +00002425 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
Elliott Hughesed398002017-06-21 14:41:24 -07002426 /* The args vector may contain IRExpr_GSPTR() and/or
florian90419562013-08-15 20:54:52 +00002427 IRExpr_VECRET(), in both cases, at most once. */
sewardj74142b82013-08-08 10:28:59 +00002428 IRExpr** args; /* arg vector, ends in NULL. */
sewardj92d168d2004-11-15 14:22:12 +00002429 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
sewardjb3bce0e2004-09-14 23:20:10 +00002430
2431 /* Mem effects; we allow only one R/W/M region to be stated */
sewardj8ea867b2004-10-30 19:03:02 +00002432 IREffect mFx; /* indicates memory effects, if any */
2433 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
2434 Int mSize; /* of access, or zero if mFx==Ifx_None */
sewardjb3bce0e2004-09-14 23:20:10 +00002435
2436 /* Guest state effects; up to N allowed */
sewardjc5fc7aa2004-10-27 23:00:55 +00002437 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
sewardjb3bce0e2004-09-14 23:20:10 +00002438 struct {
sewardjc9069f22012-06-01 16:09:50 +00002439 IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
2440 UShort offset;
2441 UShort size;
2442 UChar nRepeats;
2443 UChar repeatLen;
sewardjb3bce0e2004-09-14 23:20:10 +00002444 } fxState[VEX_N_FXSTATE];
sewardjc9069f22012-06-01 16:09:50 +00002445 /* The access can be repeated, as specified by nRepeats and
2446 repeatLen. To describe only a single access, nRepeats and
2447 repeatLen should be zero. Otherwise, repeatLen must be a
2448 multiple of size and greater than size. */
2449 /* Overall, the parts of the guest state denoted by (offset,
2450 size, nRepeats, repeatLen) is
2451 [offset, +size)
2452 and, if nRepeats > 0,
2453 for (i = 1; i <= nRepeats; i++)
2454 [offset + i * repeatLen, +size)
2455 A convenient way to enumerate all segments is therefore
2456 for (i = 0; i < 1 + nRepeats; i++)
2457 [offset + i * repeatLen, +size)
2458 */
sewardjb3bce0e2004-09-14 23:20:10 +00002459 }
2460 IRDirty;
2461
sewardj57c10c82006-11-15 02:57:05 +00002462/* Pretty-print a dirty call */
florian0b70efa2014-09-21 21:53:39 +00002463extern void ppIRDirty ( const IRDirty* );
sewardj57c10c82006-11-15 02:57:05 +00002464
2465/* Allocate an uninitialised dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00002466extern IRDirty* emptyIRDirty ( void );
2467
sewardj57c10c82006-11-15 02:57:05 +00002468/* Deep-copy a dirty call */
florian0b70efa2014-09-21 21:53:39 +00002469extern IRDirty* deepCopyIRDirty ( const IRDirty* );
sewardj695cff92004-10-13 14:50:14 +00002470
sewardjc5fc7aa2004-10-27 23:00:55 +00002471/* A handy function which takes some of the tedium out of constructing
2472 dirty helper calls. The called function impliedly does not return
sewardjb8385d82004-11-02 01:34:15 +00002473 any value and has a constant-True guard. The call is marked as
2474 accessing neither guest state nor memory (hence the "unsafe"
sewardj57c10c82006-11-15 02:57:05 +00002475 designation) -- you can change this marking later if need be. A
sewardjb8385d82004-11-02 01:34:15 +00002476 suitable IRCallee is constructed from the supplied bits. */
sewardjf9655262004-10-31 20:02:16 +00002477extern
florian1ff47562012-10-21 02:09:51 +00002478IRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002479 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002480
2481/* Similarly, make a zero-annotation dirty call which returns a value,
2482 and assign that to the given temp. */
sewardjf9655262004-10-31 20:02:16 +00002483extern
2484IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
florian1ff47562012-10-21 02:09:51 +00002485 Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002486 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002487
sewardjb3bce0e2004-09-14 23:20:10 +00002488
sewardjc4356f02007-11-09 21:15:04 +00002489/* --------------- Memory Bus Events --------------- */
2490
2491typedef
2492 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002493 Imbe_Fence=0x1C00,
sewardj6d615ba2011-09-26 16:19:43 +00002494 /* Needed only on ARM. It cancels a reservation made by a
2495 preceding Linked-Load, and needs to be handed through to the
2496 back end, just as LL and SC themselves are. */
2497 Imbe_CancelReservation
sewardjc4356f02007-11-09 21:15:04 +00002498 }
2499 IRMBusEvent;
2500
2501extern void ppIRMBusEvent ( IRMBusEvent );
2502
2503
sewardje9d8a262009-07-01 08:06:34 +00002504/* --------------- Compare and Swap --------------- */
2505
2506/* This denotes an atomic compare and swap operation, either
2507 a single-element one or a double-element one.
2508
2509 In the single-element case:
2510
2511 .addr is the memory address.
2512 .end is the endianness with which memory is accessed
2513
2514 If .addr contains the same value as .expdLo, then .dataLo is
2515 written there, else there is no write. In both cases, the
2516 original value at .addr is copied into .oldLo.
2517
2518 Types: .expdLo, .dataLo and .oldLo must all have the same type.
2519 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2520 guests, I64.
2521
2522 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2523 be NULL.
2524
2525 In the double-element case:
2526
2527 .addr is the memory address.
2528 .end is the endianness with which memory is accessed
2529
2530 The operation is the same:
2531
2532 If .addr contains the same value as .expdHi:.expdLo, then
2533 .dataHi:.dataLo is written there, else there is no write. In
2534 both cases the original value at .addr is copied into
2535 .oldHi:.oldLo.
2536
2537 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2538 all have the same type, which may be any integral type, viz: I8,
2539 I16, I32 or, for 64-bit guests, I64.
2540
2541 The double-element case is complicated by the issue of
2542 endianness. In all cases, the two elements are understood to be
2543 located adjacently in memory, starting at the address .addr.
2544
2545 If .end is Iend_LE, then the .xxxLo component is at the lower
2546 address and the .xxxHi component is at the higher address, and
2547 each component is itself stored little-endianly.
2548
2549 If .end is Iend_BE, then the .xxxHi component is at the lower
2550 address and the .xxxLo component is at the higher address, and
2551 each component is itself stored big-endianly.
2552
2553 This allows representing more cases than most architectures can
2554 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
2555
2556 How to know if the CAS succeeded?
2557
2558 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2559 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2560 stored at .addr, and the original value there was .oldLo (resp
2561 .oldHi:.oldLo).
2562
2563 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2564 then the CAS failed, and the original value at .addr was .oldLo
2565 (resp. .oldHi:.oldLo).
2566
2567 Hence it is easy to know whether or not the CAS succeeded.
2568*/
2569typedef
2570 struct {
2571 IRTemp oldHi; /* old value of *addr is written here */
2572 IRTemp oldLo;
2573 IREndness end; /* endianness of the data in memory */
2574 IRExpr* addr; /* store address */
2575 IRExpr* expdHi; /* expected old value at *addr */
2576 IRExpr* expdLo;
2577 IRExpr* dataHi; /* new value for *addr */
2578 IRExpr* dataLo;
2579 }
2580 IRCAS;
2581
florian0b70efa2014-09-21 21:53:39 +00002582extern void ppIRCAS ( const IRCAS* cas );
sewardje9d8a262009-07-01 08:06:34 +00002583
2584extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2585 IREndness end, IRExpr* addr,
2586 IRExpr* expdHi, IRExpr* expdLo,
2587 IRExpr* dataHi, IRExpr* dataLo );
2588
florian0b70efa2014-09-21 21:53:39 +00002589extern IRCAS* deepCopyIRCAS ( const IRCAS* );
sewardje9d8a262009-07-01 08:06:34 +00002590
floriand6f38b32012-05-31 15:46:18 +00002591
2592/* ------------------ Circular Array Put ------------------ */
sewardjcfe046e2013-01-17 14:23:53 +00002593
floriand6f38b32012-05-31 15:46:18 +00002594typedef
2595 struct {
2596 IRRegArray* descr; /* Part of guest state treated as circular */
2597 IRExpr* ix; /* Variable part of index into array */
2598 Int bias; /* Constant offset part of index into array */
2599 IRExpr* data; /* The value to write */
2600 } IRPutI;
2601
florian0b70efa2014-09-21 21:53:39 +00002602extern void ppIRPutI ( const IRPutI* puti );
floriand6f38b32012-05-31 15:46:18 +00002603
2604extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2605 Int bias, IRExpr* data );
2606
florian0b70efa2014-09-21 21:53:39 +00002607extern IRPutI* deepCopyIRPutI ( const IRPutI* );
floriand6f38b32012-05-31 15:46:18 +00002608
sewardjc9069f22012-06-01 16:09:50 +00002609
sewardjcfe046e2013-01-17 14:23:53 +00002610/* --------------- Guarded loads and stores --------------- */
2611
2612/* Conditional stores are straightforward. They are the same as
2613 normal stores, with an extra 'guard' field :: Ity_I1 that
2614 determines whether or not the store actually happens. If not,
2615 memory is unmodified.
2616
2617 The semantics of this is that 'addr' and 'data' are fully evaluated
2618 even in the case where 'guard' evaluates to zero (false).
2619*/
2620typedef
2621 struct {
2622 IREndness end; /* Endianness of the store */
2623 IRExpr* addr; /* store address */
2624 IRExpr* data; /* value to write */
2625 IRExpr* guard; /* Guarding value */
2626 }
2627 IRStoreG;
2628
2629/* Conditional loads are a little more complex. 'addr' is the
2630 address, 'guard' is the guarding condition. If the load takes
2631 place, the loaded value is placed in 'dst'. If it does not take
2632 place, 'alt' is copied to 'dst'. However, the loaded value is not
2633 placed directly in 'dst' -- it is first subjected to the conversion
2634 specified by 'cvt'.
2635
2636 For example, imagine doing a conditional 8-bit load, in which the
2637 loaded value is zero extended to 32 bits. Hence:
2638 * 'dst' and 'alt' must have type I32
2639 * 'cvt' must be a unary op which converts I8 to I32. In this
2640 example, it would be ILGop_8Uto32.
2641
2642 There is no explicit indication of the type at which the load is
2643 done, since that is inferrable from the arg type of 'cvt'. Note
2644 that the types of 'alt' and 'dst' and the result type of 'cvt' must
2645 all be the same.
2646
2647 Semantically, 'addr' is evaluated even in the case where 'guard'
2648 evaluates to zero (false), and 'alt' is evaluated even when 'guard'
2649 evaluates to one (true). That is, 'addr' and 'alt' are always
2650 evaluated.
2651*/
2652typedef
2653 enum {
2654 ILGop_INVALID=0x1D00,
sewardj70dbeb02015-08-12 11:15:53 +00002655 ILGop_IdentV128, /* 128 bit vector, no conversion */
sewardj802bbae2015-01-27 23:09:23 +00002656 ILGop_Ident64, /* 64 bit, no conversion */
sewardjcfe046e2013-01-17 14:23:53 +00002657 ILGop_Ident32, /* 32 bit, no conversion */
2658 ILGop_16Uto32, /* 16 bit load, Z-widen to 32 */
2659 ILGop_16Sto32, /* 16 bit load, S-widen to 32 */
2660 ILGop_8Uto32, /* 8 bit load, Z-widen to 32 */
2661 ILGop_8Sto32 /* 8 bit load, S-widen to 32 */
2662 }
2663 IRLoadGOp;
2664
2665typedef
2666 struct {
2667 IREndness end; /* Endianness of the load */
2668 IRLoadGOp cvt; /* Conversion to apply to the loaded value */
2669 IRTemp dst; /* Destination (LHS) of assignment */
2670 IRExpr* addr; /* Address being loaded from */
2671 IRExpr* alt; /* Value if load is not done. */
2672 IRExpr* guard; /* Guarding value */
2673 }
2674 IRLoadG;
2675
florian0b70efa2014-09-21 21:53:39 +00002676extern void ppIRStoreG ( const IRStoreG* sg );
sewardjcfe046e2013-01-17 14:23:53 +00002677
2678extern void ppIRLoadGOp ( IRLoadGOp cvt );
2679
florian0b70efa2014-09-21 21:53:39 +00002680extern void ppIRLoadG ( const IRLoadG* lg );
sewardjcfe046e2013-01-17 14:23:53 +00002681
2682extern IRStoreG* mkIRStoreG ( IREndness end,
2683 IRExpr* addr, IRExpr* data,
2684 IRExpr* guard );
2685
2686extern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
2687 IRTemp dst, IRExpr* addr, IRExpr* alt,
2688 IRExpr* guard );
2689
2690
sewardjc97096c2004-06-30 09:28:04 +00002691/* ------------------ Statements ------------------ */
sewardjb3bce0e2004-09-14 23:20:10 +00002692
sewardj57c10c82006-11-15 02:57:05 +00002693/* The different kinds of statements. Their meaning is explained
2694 below in the comments for IRStmt.
sewardj5a9ffab2005-05-12 17:55:01 +00002695
sewardj57c10c82006-11-15 02:57:05 +00002696 Those marked META do not represent code, but rather extra
2697 information about the code. These statements can be removed
2698 without affecting the functional behaviour of the code, however
2699 they are required by some IR consumers such as tools that
2700 instrument the code.
sewardj5a9ffab2005-05-12 17:55:01 +00002701*/
sewardjc4356f02007-11-09 21:15:04 +00002702
sewardjac6b7122004-06-27 01:03:57 +00002703typedef
sewardjd2445f62005-03-21 00:15:53 +00002704 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002705 Ist_NoOp=0x1E00,
sewardj57c10c82006-11-15 02:57:05 +00002706 Ist_IMark, /* META */
2707 Ist_AbiHint, /* META */
2708 Ist_Put,
2709 Ist_PutI,
sewardjdd40fdf2006-12-24 02:20:24 +00002710 Ist_WrTmp,
sewardj57c10c82006-11-15 02:57:05 +00002711 Ist_Store,
sewardjcfe046e2013-01-17 14:23:53 +00002712 Ist_LoadG,
2713 Ist_StoreG,
sewardje9d8a262009-07-01 08:06:34 +00002714 Ist_CAS,
sewardje768e922009-11-26 17:17:37 +00002715 Ist_LLSC,
sewardj57c10c82006-11-15 02:57:05 +00002716 Ist_Dirty,
sewardjcfe046e2013-01-17 14:23:53 +00002717 Ist_MBE,
sewardj57c10c82006-11-15 02:57:05 +00002718 Ist_Exit
sewardjb3bce0e2004-09-14 23:20:10 +00002719 }
sewardjac6b7122004-06-27 01:03:57 +00002720 IRStmtTag;
2721
sewardj57c10c82006-11-15 02:57:05 +00002722/* A statement. Stored as a tagged union. 'tag' indicates what kind
2723 of expression this is. 'Ist' is the union that holds the fields.
2724 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2725 statement, and the fields can be accessed with
2726 'st.Ist.Store.<fieldname>'.
2727
2728 For each kind of statement, we show what it looks like when
sewardje9d8a262009-07-01 08:06:34 +00002729 pretty-printed with ppIRStmt().
sewardj57c10c82006-11-15 02:57:05 +00002730*/
sewardjac6b7122004-06-27 01:03:57 +00002731typedef
2732 struct _IRStmt {
2733 IRStmtTag tag;
2734 union {
sewardj57c10c82006-11-15 02:57:05 +00002735 /* A no-op (usually resulting from IR optimisation). Can be
2736 omitted without any effect.
2737
sewardje9d8a262009-07-01 08:06:34 +00002738 ppIRStmt output: IR-NoOp
sewardj57c10c82006-11-15 02:57:05 +00002739 */
sewardjac6b7122004-06-27 01:03:57 +00002740 struct {
sewardjd2445f62005-03-21 00:15:53 +00002741 } NoOp;
sewardj57c10c82006-11-15 02:57:05 +00002742
2743 /* META: instruction mark. Marks the start of the statements
2744 that represent a single machine instruction (the end of
2745 those statements is marked by the next IMark or the end of
sewardjdd40fdf2006-12-24 02:20:24 +00002746 the IRSB). Contains the address and length of the
sewardj57c10c82006-11-15 02:57:05 +00002747 instruction.
2748
sewardj2f10aa62011-05-27 13:20:56 +00002749 It also contains a delta value. The delta must be
2750 subtracted from a guest program counter value before
2751 attempting to establish, by comparison with the address
2752 and length values, whether or not that program counter
2753 value refers to this instruction. For x86, amd64, ppc32,
2754 ppc64 and arm, the delta value is zero. For Thumb
2755 instructions, the delta value is one. This is because, on
2756 Thumb, guest PC values (guest_R15T) are encoded using the
2757 top 31 bits of the instruction address and a 1 in the lsb;
2758 hence they appear to be (numerically) 1 past the start of
2759 the instruction they refer to. IOW, guest_R15T on ARM
2760 holds a standard ARM interworking address.
2761
2762 ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2763 eg. ------ IMark(0x4000792, 5, 0) ------,
sewardj57c10c82006-11-15 02:57:05 +00002764 */
sewardjd2445f62005-03-21 00:15:53 +00002765 struct {
floriandcd6d232015-01-02 17:32:21 +00002766 Addr addr; /* instruction address */
2767 UInt len; /* instruction length */
sewardj2f10aa62011-05-27 13:20:56 +00002768 UChar delta; /* addr = program counter as encoded in guest state
2769 - delta */
sewardjf1689312005-03-16 18:19:10 +00002770 } IMark;
sewardj57c10c82006-11-15 02:57:05 +00002771
2772 /* META: An ABI hint, which says something about this
2773 platform's ABI.
2774
2775 At the moment, the only AbiHint is one which indicates
2776 that a given chunk of address space, [base .. base+len-1],
2777 has become undefined. This is used on amd64-linux and
2778 some ppc variants to pass stack-redzoning hints to whoever
sewardj478646f2008-05-01 20:13:04 +00002779 wants to see them. It also indicates the address of the
2780 next (dynamic) instruction that will be executed. This is
2781 to help Memcheck to origin tracking.
sewardj57c10c82006-11-15 02:57:05 +00002782
sewardje9d8a262009-07-01 08:06:34 +00002783 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
sewardj478646f2008-05-01 20:13:04 +00002784 eg. ====== AbiHint(t1, 16, t2) ======
sewardj57c10c82006-11-15 02:57:05 +00002785 */
sewardjf1689312005-03-16 18:19:10 +00002786 struct {
sewardj57c10c82006-11-15 02:57:05 +00002787 IRExpr* base; /* Start of undefined chunk */
2788 Int len; /* Length of undefined chunk */
sewardj478646f2008-05-01 20:13:04 +00002789 IRExpr* nia; /* Address of next (guest) insn */
sewardj5a9ffab2005-05-12 17:55:01 +00002790 } AbiHint;
sewardj57c10c82006-11-15 02:57:05 +00002791
2792 /* Write a guest register, at a fixed offset in the guest state.
sewardje9d8a262009-07-01 08:06:34 +00002793 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
sewardj57c10c82006-11-15 02:57:05 +00002794 */
sewardj5a9ffab2005-05-12 17:55:01 +00002795 struct {
sewardj57c10c82006-11-15 02:57:05 +00002796 Int offset; /* Offset into the guest state */
2797 IRExpr* data; /* The value to write */
sewardjac6b7122004-06-27 01:03:57 +00002798 } Put;
sewardj57c10c82006-11-15 02:57:05 +00002799
2800 /* Write a guest register, at a non-fixed offset in the guest
2801 state. See the comment for GetI expressions for more
2802 information.
2803
sewardje9d8a262009-07-01 08:06:34 +00002804 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
sewardj57c10c82006-11-15 02:57:05 +00002805 eg. PUTI(64:8xF64)[t5,0] = t1
2806 */
sewardjac6b7122004-06-27 01:03:57 +00002807 struct {
floriand6f38b32012-05-31 15:46:18 +00002808 IRPutI* details;
sewardjd1725d12004-08-12 20:46:53 +00002809 } PutI;
sewardj57c10c82006-11-15 02:57:05 +00002810
sewardjdd40fdf2006-12-24 02:20:24 +00002811 /* Assign a value to a temporary. Note that SSA rules require
2812 each tmp is only assigned to once. IR sanity checking will
2813 reject any block containing a temporary which is not assigned
2814 to exactly once.
sewardj57c10c82006-11-15 02:57:05 +00002815
sewardje9d8a262009-07-01 08:06:34 +00002816 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
sewardj57c10c82006-11-15 02:57:05 +00002817 */
sewardjd1725d12004-08-12 20:46:53 +00002818 struct {
sewardj57c10c82006-11-15 02:57:05 +00002819 IRTemp tmp; /* Temporary (LHS of assignment) */
2820 IRExpr* data; /* Expression (RHS of assignment) */
sewardjdd40fdf2006-12-24 02:20:24 +00002821 } WrTmp;
sewardj57c10c82006-11-15 02:57:05 +00002822
sewardje768e922009-11-26 17:17:37 +00002823 /* Write a value to memory. This is a normal store, not a
2824 Store-Conditional. To represent a Store-Conditional,
2825 instead use IRStmt.LLSC.
sewardje9d8a262009-07-01 08:06:34 +00002826 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
sewardj57c10c82006-11-15 02:57:05 +00002827 */
sewardjac6b7122004-06-27 01:03:57 +00002828 struct {
sewardj57c10c82006-11-15 02:57:05 +00002829 IREndness end; /* Endianness of the store */
2830 IRExpr* addr; /* store address */
2831 IRExpr* data; /* value to write */
sewardjaf1ceca2005-06-30 23:31:27 +00002832 } Store;
sewardj57c10c82006-11-15 02:57:05 +00002833
sewardjcfe046e2013-01-17 14:23:53 +00002834 /* Guarded store. Note that this is defined to evaluate all
2835 expression fields (addr, data) even if the guard evaluates
2836 to false.
2837 ppIRStmt output:
2838 if (<guard>) ST<end>(<addr>) = <data> */
2839 struct {
2840 IRStoreG* details;
2841 } StoreG;
2842
2843 /* Guarded load. Note that this is defined to evaluate all
2844 expression fields (addr, alt) even if the guard evaluates
2845 to false.
2846 ppIRStmt output:
2847 t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */
2848 struct {
2849 IRLoadG* details;
2850 } LoadG;
2851
sewardje9d8a262009-07-01 08:06:34 +00002852 /* Do an atomic compare-and-swap operation. Semantics are
2853 described above on a comment at the definition of IRCAS.
2854
2855 ppIRStmt output:
2856 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2857 eg
2858 t1 = CASle(t2 :: t3->Add32(t3,1))
2859 which denotes a 32-bit atomic increment
2860 of a value at address t2
2861
2862 A double-element CAS may also be denoted, in which case <tmp>,
2863 <expected> and <new> are all pairs of items, separated by
2864 commas.
2865 */
2866 struct {
2867 IRCAS* details;
2868 } CAS;
2869
sewardje768e922009-11-26 17:17:37 +00002870 /* Either Load-Linked or Store-Conditional, depending on
2871 STOREDATA.
2872
2873 If STOREDATA is NULL then this is a Load-Linked, meaning
2874 that data is loaded from memory as normal, but a
2875 'reservation' for the address is also lodged in the
2876 hardware.
2877
2878 result = Load-Linked(addr, end)
2879
2880 The data transfer type is the type of RESULT (I32, I64,
2881 etc). ppIRStmt output:
2882
2883 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2884
2885 If STOREDATA is not NULL then this is a Store-Conditional,
2886 hence:
2887
2888 result = Store-Conditional(addr, storedata, end)
2889
2890 The data transfer type is the type of STOREDATA and RESULT
2891 has type Ity_I1. The store may fail or succeed depending
2892 on the state of a previously lodged reservation on this
2893 address. RESULT is written 1 if the store succeeds and 0
2894 if it fails. eg ppIRStmt output:
2895
2896 result = ( ST<end>-Cond(<addr>) = <storedata> )
2897 eg t3 = ( STbe-Cond(t1, t2) )
2898
2899 In all cases, the address must be naturally aligned for
2900 the transfer type -- any misaligned addresses should be
2901 caught by a dominating IR check and side exit. This
2902 alignment restriction exists because on at least some
2903 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2904 misaligned addresses, and we have to actually generate
2905 stwcx. on the host, and we don't want it trapping on the
2906 host.
2907
2908 Summary of rules for transfer type:
2909 STOREDATA == NULL (LL):
2910 transfer type = type of RESULT
2911 STOREDATA != NULL (SC):
2912 transfer type = type of STOREDATA, and RESULT :: Ity_I1
2913 */
2914 struct {
2915 IREndness end;
2916 IRTemp result;
2917 IRExpr* addr;
2918 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
2919 } LLSC;
2920
sewardj57c10c82006-11-15 02:57:05 +00002921 /* Call (possibly conditionally) a C function that has side
2922 effects (ie. is "dirty"). See the comments above the
2923 IRDirty type declaration for more information.
2924
sewardje9d8a262009-07-01 08:06:34 +00002925 ppIRStmt output:
sewardj57c10c82006-11-15 02:57:05 +00002926 t<tmp> = DIRTY <guard> <effects>
2927 ::: <callee>(<args>)
2928 eg.
2929 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
2930 ::: foo{0x380035f4}(t2)
2931 */
sewardj64e1d652004-07-12 14:00:46 +00002932 struct {
sewardjb3bce0e2004-09-14 23:20:10 +00002933 IRDirty* details;
2934 } Dirty;
sewardj57c10c82006-11-15 02:57:05 +00002935
sewardjc4356f02007-11-09 21:15:04 +00002936 /* A memory bus event - a fence, or acquisition/release of the
2937 hardware bus lock. IR optimisation treats all these as fences
2938 across which no memory references may be moved.
sewardje9d8a262009-07-01 08:06:34 +00002939 ppIRStmt output: MBusEvent-Fence,
sewardjc4356f02007-11-09 21:15:04 +00002940 MBusEvent-BusLock, MBusEvent-BusUnlock.
sewardj57c10c82006-11-15 02:57:05 +00002941 */
sewardjb3bce0e2004-09-14 23:20:10 +00002942 struct {
sewardjc4356f02007-11-09 21:15:04 +00002943 IRMBusEvent event;
2944 } MBE;
sewardj57c10c82006-11-15 02:57:05 +00002945
sewardjdd40fdf2006-12-24 02:20:24 +00002946 /* Conditional exit from the middle of an IRSB.
sewardje9d8a262009-07-01 08:06:34 +00002947 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
sewardj57c10c82006-11-15 02:57:05 +00002948 eg. if (t69) goto {Boring} 0x4000AAA:I32
sewardjc6f970f2012-04-02 21:54:49 +00002949 If <guard> is true, the guest state is also updated by
2950 PUT-ing <dst> at <offsIP>. This is done because a
2951 taken exit must update the guest program counter.
sewardj57c10c82006-11-15 02:57:05 +00002952 */
sewardj3e838932005-01-07 12:09:15 +00002953 struct {
sewardj57c10c82006-11-15 02:57:05 +00002954 IRExpr* guard; /* Conditional expression */
sewardj57c10c82006-11-15 02:57:05 +00002955 IRConst* dst; /* Jump target (constant only) */
floriand6f38b32012-05-31 15:46:18 +00002956 IRJumpKind jk; /* Jump kind */
sewardjc6f970f2012-04-02 21:54:49 +00002957 Int offsIP; /* Guest state offset for IP */
sewardj64e1d652004-07-12 14:00:46 +00002958 } Exit;
sewardjac6b7122004-06-27 01:03:57 +00002959 } Ist;
sewardjac6b7122004-06-27 01:03:57 +00002960 }
2961 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +00002962
sewardj57c10c82006-11-15 02:57:05 +00002963/* Statement constructors. */
sewardj5a9ffab2005-05-12 17:55:01 +00002964extern IRStmt* IRStmt_NoOp ( void );
floriandcd6d232015-01-02 17:32:21 +00002965extern IRStmt* IRStmt_IMark ( Addr addr, UInt len, UChar delta );
sewardj478646f2008-05-01 20:13:04 +00002966extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
sewardj5a9ffab2005-05-12 17:55:01 +00002967extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
floriand6f38b32012-05-31 15:46:18 +00002968extern IRStmt* IRStmt_PutI ( IRPutI* details );
sewardjdd40fdf2006-12-24 02:20:24 +00002969extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
sewardje768e922009-11-26 17:17:37 +00002970extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
sewardjcfe046e2013-01-17 14:23:53 +00002971extern IRStmt* IRStmt_StoreG ( IREndness end, IRExpr* addr, IRExpr* data,
2972 IRExpr* guard );
2973extern IRStmt* IRStmt_LoadG ( IREndness end, IRLoadGOp cvt, IRTemp dst,
2974 IRExpr* addr, IRExpr* alt, IRExpr* guard );
sewardje9d8a262009-07-01 08:06:34 +00002975extern IRStmt* IRStmt_CAS ( IRCAS* details );
sewardje768e922009-11-26 17:17:37 +00002976extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
2977 IRExpr* addr, IRExpr* storedata );
sewardj5a9ffab2005-05-12 17:55:01 +00002978extern IRStmt* IRStmt_Dirty ( IRDirty* details );
sewardjc4356f02007-11-09 21:15:04 +00002979extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
sewardjc6f970f2012-04-02 21:54:49 +00002980extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2981 Int offsIP );
sewardjec6ad592004-06-20 12:26:53 +00002982
sewardj57c10c82006-11-15 02:57:05 +00002983/* Deep-copy an IRStmt. */
florian0b70efa2014-09-21 21:53:39 +00002984extern IRStmt* deepCopyIRStmt ( const IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002985
sewardj57c10c82006-11-15 02:57:05 +00002986/* Pretty-print an IRStmt. */
florian0b70efa2014-09-21 21:53:39 +00002987extern void ppIRStmt ( const IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +00002988
2989
sewardje539a402004-07-14 18:24:17 +00002990/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +00002991
sewardj57c10c82006-11-15 02:57:05 +00002992/* Type environments: a bunch of statements, expressions, etc, are
2993 incomplete without an environment indicating the type of each
2994 IRTemp. So this provides one. IR temporaries are really just
2995 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2996 them.
sewardjc97096c2004-06-30 09:28:04 +00002997*/
2998typedef
sewardjc97096c2004-06-30 09:28:04 +00002999 struct {
sewardje539a402004-07-14 18:24:17 +00003000 IRType* types;
3001 Int types_size;
3002 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +00003003 }
3004 IRTypeEnv;
3005
sewardj57c10c82006-11-15 02:57:05 +00003006/* Obtain a new IRTemp */
3007extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
3008
3009/* Deep-copy a type environment */
florian0b70efa2014-09-21 21:53:39 +00003010extern IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* );
sewardj695cff92004-10-13 14:50:14 +00003011
sewardj57c10c82006-11-15 02:57:05 +00003012/* Pretty-print a type environment */
florian0b70efa2014-09-21 21:53:39 +00003013extern void ppIRTypeEnv ( const IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +00003014
sewardjec6ad592004-06-20 12:26:53 +00003015
sewardjdd40fdf2006-12-24 02:20:24 +00003016/* Code blocks, which in proper compiler terminology are superblocks
3017 (single entry, multiple exit code sequences) contain:
3018
sewardj57c10c82006-11-15 02:57:05 +00003019 - A table giving a type for each temp (the "type environment")
sewardjd7cb8532004-08-17 23:59:23 +00003020 - An expandable array of statements
sewardje539a402004-07-14 18:24:17 +00003021 - An expression of type 32 or 64 bits, depending on the
sewardjdd40fdf2006-12-24 02:20:24 +00003022 guest's word size, indicating the next destination if the block
3023 executes all the way to the end, without a side exit
sewardjd7cb8532004-08-17 23:59:23 +00003024 - An indication of any special actions (JumpKind) needed
3025 for this final jump.
sewardjc6f970f2012-04-02 21:54:49 +00003026 - Offset of the IP field in the guest state. This will be
3027 updated before the final jump is done.
sewardj57c10c82006-11-15 02:57:05 +00003028
sewardjdd40fdf2006-12-24 02:20:24 +00003029 "IRSB" stands for "IR Super Block".
sewardjec6ad592004-06-20 12:26:53 +00003030*/
sewardjac6b7122004-06-27 01:03:57 +00003031typedef
sewardj57c10c82006-11-15 02:57:05 +00003032 struct {
sewardjc97096c2004-06-30 09:28:04 +00003033 IRTypeEnv* tyenv;
sewardjd7cb8532004-08-17 23:59:23 +00003034 IRStmt** stmts;
3035 Int stmts_size;
3036 Int stmts_used;
sewardje539a402004-07-14 18:24:17 +00003037 IRExpr* next;
3038 IRJumpKind jumpkind;
sewardjc6f970f2012-04-02 21:54:49 +00003039 Int offsIP;
sewardjac6b7122004-06-27 01:03:57 +00003040 }
sewardjdd40fdf2006-12-24 02:20:24 +00003041 IRSB;
sewardjec6ad592004-06-20 12:26:53 +00003042
sewardjdd40fdf2006-12-24 02:20:24 +00003043/* Allocate a new, uninitialised IRSB */
3044extern IRSB* emptyIRSB ( void );
sewardj695cff92004-10-13 14:50:14 +00003045
sewardjdd40fdf2006-12-24 02:20:24 +00003046/* Deep-copy an IRSB */
florian0b70efa2014-09-21 21:53:39 +00003047extern IRSB* deepCopyIRSB ( const IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00003048
sewardjdd40fdf2006-12-24 02:20:24 +00003049/* Deep-copy an IRSB, except for the statements list, which set to be
sewardj6f2f2832006-11-24 23:32:55 +00003050 a new, empty, list of statements. */
florian0b70efa2014-09-21 21:53:39 +00003051extern IRSB* deepCopyIRSBExceptStmts ( const IRSB* );
sewardj57c10c82006-11-15 02:57:05 +00003052
sewardjdd40fdf2006-12-24 02:20:24 +00003053/* Pretty-print an IRSB */
florian0b70efa2014-09-21 21:53:39 +00003054extern void ppIRSB ( const IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00003055
sewardjdd40fdf2006-12-24 02:20:24 +00003056/* Append an IRStmt to an IRSB */
3057extern void addStmtToIRSB ( IRSB*, IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00003058
3059
sewardjec6ad592004-06-20 12:26:53 +00003060/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +00003061/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +00003062/*---------------------------------------------------------------*/
3063
sewardjc97096c2004-06-30 09:28:04 +00003064/* For messing with IR type environments */
sewardjd7cb8532004-08-17 23:59:23 +00003065extern IRTypeEnv* emptyIRTypeEnv ( void );
sewardjec6ad592004-06-20 12:26:53 +00003066
sewardjc97096c2004-06-30 09:28:04 +00003067/* What is the type of this expression? */
florian0b70efa2014-09-21 21:53:39 +00003068extern IRType typeOfIRConst ( const IRConst* );
3069extern IRType typeOfIRTemp ( const IRTypeEnv*, IRTemp );
3070extern IRType typeOfIRExpr ( const IRTypeEnv*, const IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00003071
sewardjcfe046e2013-01-17 14:23:53 +00003072/* What are the arg and result type for this IRLoadGOp? */
3073extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
3074 /*OUT*/IRType* t_res,
3075 /*OUT*/IRType* t_arg );
3076
sewardj35439212004-07-14 22:36:10 +00003077/* Sanity check a BB of IR */
florian0b70efa2014-09-21 21:53:39 +00003078extern void sanityCheckIRSB ( const IRSB* bb,
florian1ff47562012-10-21 02:09:51 +00003079 const HChar* caller,
sewardjb9230752004-12-29 19:25:06 +00003080 Bool require_flatness,
3081 IRType guest_word_size );
florian0b70efa2014-09-21 21:53:39 +00003082extern Bool isFlatIRStmt ( const IRStmt* );
sewardjec6ad592004-06-20 12:26:53 +00003083
sewardj6d2638e2004-07-15 09:38:27 +00003084/* Is this any value actually in the enumeration 'IRType' ? */
sewardj496a58d2005-03-20 18:44:44 +00003085extern Bool isPlausibleIRType ( IRType ty );
sewardj6d2638e2004-07-15 09:38:27 +00003086
florian2245ce92012-08-28 16:49:30 +00003087
3088/*---------------------------------------------------------------*/
3089/*--- IR injection ---*/
3090/*---------------------------------------------------------------*/
sewardj7d009132014-02-20 17:43:38 +00003091
florian2245ce92012-08-28 16:49:30 +00003092void vex_inject_ir(IRSB *, IREndness);
3093
3094
sewardj887a11a2004-07-05 17:26:47 +00003095#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +00003096
sewardjac9af022004-07-05 01:15:34 +00003097/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +00003098/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +00003099/*---------------------------------------------------------------*/