blob: bf35796149274312a942871c967cc1cd117b3316 [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
sewardj25e54732012-08-05 15:36:51 +000010 Copyright (C) 2004-2012 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 */
sewardjc9a43662004-11-30 18:51:59 +0000228 Ity_F32, /* IEEE 754 float */
229 Ity_F64, /* IEEE 754 double */
sewardjc6bbd472012-04-02 10:20:48 +0000230 Ity_D32, /* 32-bit Decimal floating point */
231 Ity_D64, /* 64-bit Decimal floating point */
232 Ity_D128, /* 128-bit Decimal floating point */
sewardj2019a972011-03-07 16:04:07 +0000233 Ity_F128, /* 128-bit floating point; implementation defined */
sewardjc4530ae2012-05-21 10:18:49 +0000234 Ity_V128, /* 128-bit SIMD */
235 Ity_V256 /* 256-bit SIMD */
sewardjd1725d12004-08-12 20:46:53 +0000236 }
sewardje3d0d2e2004-06-27 10:42:44 +0000237 IRType;
238
sewardj57c10c82006-11-15 02:57:05 +0000239/* Pretty-print an IRType */
sewardj35421a32004-07-05 13:12:34 +0000240extern void ppIRType ( IRType );
sewardj57c10c82006-11-15 02:57:05 +0000241
242/* Get the size (in bytes) of an IRType */
243extern Int sizeofIRType ( IRType );
sewardje3d0d2e2004-06-27 10:42:44 +0000244
sewardjc97096c2004-06-30 09:28:04 +0000245
sewardjaf1ceca2005-06-30 23:31:27 +0000246/* ------------------ Endianness ------------------ */
247
sewardj57c10c82006-11-15 02:57:05 +0000248/* IREndness is used in load IRExprs and store IRStmts. */
sewardjaf1ceca2005-06-30 23:31:27 +0000249typedef
250 enum {
sewardjcfe046e2013-01-17 14:23:53 +0000251 Iend_LE=0x1200, /* little endian */
sewardjc4356f02007-11-09 21:15:04 +0000252 Iend_BE /* big endian */
sewardjaf1ceca2005-06-30 23:31:27 +0000253 }
254 IREndness;
255
256
sewardjc97096c2004-06-30 09:28:04 +0000257/* ------------------ Constants ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000258
sewardj57c10c82006-11-15 02:57:05 +0000259/* IRConsts are used within 'Const' and 'Exit' IRExprs. */
260
261/* The various kinds of constant. */
sewardjac6b7122004-06-27 01:03:57 +0000262typedef
sewardjc9a43662004-11-30 18:51:59 +0000263 enum {
sewardjcfe046e2013-01-17 14:23:53 +0000264 Ico_U1=0x1300,
sewardjc9a43662004-11-30 18:51:59 +0000265 Ico_U8,
266 Ico_U16,
267 Ico_U32,
268 Ico_U64,
sewardj2019a972011-03-07 16:04:07 +0000269 Ico_F32, /* 32-bit IEEE754 floating */
270 Ico_F32i, /* 32-bit unsigned int to be interpreted literally
271 as a IEEE754 single value. */
sewardj1e6ad742004-12-02 16:16:11 +0000272 Ico_F64, /* 64-bit IEEE754 floating */
273 Ico_F64i, /* 64-bit unsigned int to be interpreted literally
274 as a IEEE754 double value. */
sewardj37a505b2012-06-29 15:28:24 +0000275 Ico_V128, /* 128-bit restricted vector constant, with 1 bit
sewardj57c10c82006-11-15 02:57:05 +0000276 (repeated 8 times) for each of the 16 x 1-byte lanes */
sewardj37a505b2012-06-29 15:28:24 +0000277 Ico_V256 /* 256-bit restricted vector constant, with 1 bit
278 (repeated 8 times) for each of the 32 x 1-byte lanes */
sewardj207557a2004-08-27 12:00:18 +0000279 }
sewardjac6b7122004-06-27 01:03:57 +0000280 IRConstTag;
281
sewardj57c10c82006-11-15 02:57:05 +0000282/* A constant. Stored as a tagged union. 'tag' indicates what kind of
283 constant this is. 'Ico' is the union that holds the fields. If an
284 IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
285 and its value can be accessed with 'c.Ico.U32'. */
sewardjac6b7122004-06-27 01:03:57 +0000286typedef
sewardje3d0d2e2004-06-27 10:42:44 +0000287 struct _IRConst {
sewardjac6b7122004-06-27 01:03:57 +0000288 IRConstTag tag;
289 union {
sewardjba999312004-11-15 15:21:17 +0000290 Bool U1;
sewardjc97096c2004-06-30 09:28:04 +0000291 UChar U8;
292 UShort U16;
293 UInt U32;
294 ULong U64;
sewardj2019a972011-03-07 16:04:07 +0000295 Float F32;
296 UInt F32i;
sewardja58ea662004-08-15 03:12:41 +0000297 Double F64;
sewardj17442fe2004-09-20 14:54:28 +0000298 ULong F64i;
sewardj57c10c82006-11-15 02:57:05 +0000299 UShort V128; /* 16-bit value; see Ico_V128 comment above */
sewardj37a505b2012-06-29 15:28:24 +0000300 UInt V256; /* 32-bit value; see Ico_V256 comment above */
sewardjac6b7122004-06-27 01:03:57 +0000301 } Ico;
302 }
303 IRConst;
sewardjec6ad592004-06-20 12:26:53 +0000304
sewardj57c10c82006-11-15 02:57:05 +0000305/* IRConst constructors */
sewardjba999312004-11-15 15:21:17 +0000306extern IRConst* IRConst_U1 ( Bool );
sewardj17442fe2004-09-20 14:54:28 +0000307extern IRConst* IRConst_U8 ( UChar );
308extern IRConst* IRConst_U16 ( UShort );
309extern IRConst* IRConst_U32 ( UInt );
310extern IRConst* IRConst_U64 ( ULong );
sewardj2019a972011-03-07 16:04:07 +0000311extern IRConst* IRConst_F32 ( Float );
312extern IRConst* IRConst_F32i ( UInt );
sewardj17442fe2004-09-20 14:54:28 +0000313extern IRConst* IRConst_F64 ( Double );
314extern IRConst* IRConst_F64i ( ULong );
sewardj1e6ad742004-12-02 16:16:11 +0000315extern IRConst* IRConst_V128 ( UShort );
sewardj37a505b2012-06-29 15:28:24 +0000316extern IRConst* IRConst_V256 ( UInt );
sewardjec6ad592004-06-20 12:26:53 +0000317
sewardj57c10c82006-11-15 02:57:05 +0000318/* Deep-copy an IRConst */
sewardjdd40fdf2006-12-24 02:20:24 +0000319extern IRConst* deepCopyIRConst ( IRConst* );
sewardj695cff92004-10-13 14:50:14 +0000320
sewardj57c10c82006-11-15 02:57:05 +0000321/* Pretty-print an IRConst */
sewardj35421a32004-07-05 13:12:34 +0000322extern void ppIRConst ( IRConst* );
sewardj57c10c82006-11-15 02:57:05 +0000323
324/* Compare two IRConsts for equality */
sewardj4345f7a2004-09-22 19:49:27 +0000325extern Bool eqIRConst ( IRConst*, IRConst* );
sewardjc97096c2004-06-30 09:28:04 +0000326
327
sewardj8ea867b2004-10-30 19:03:02 +0000328/* ------------------ Call targets ------------------ */
329
330/* Describes a helper function to call. The name part is purely for
sewardj77352542004-10-30 20:39:01 +0000331 pretty printing and not actually used. regparms=n tells the back
sewardj8ea867b2004-10-30 19:03:02 +0000332 end that the callee has been declared
sewardj03d91142011-03-14 12:35:18 +0000333 "__attribute__((regparm(n)))", although indirectly using the
334 VEX_REGPARM(n) macro. On some targets (x86) the back end will need
335 to construct a non-standard sequence to call a function declared
336 like this.
sewardj43c56462004-11-06 12:17:57 +0000337
338 mcx_mask is a sop to Memcheck. It indicates which args should be
339 considered 'always defined' when lazily computing definedness of
340 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to
341 args[1], etc. If a bit is set, the corresponding arg is excluded
342 (hence "x" in "mcx") from definedness checking.
343*/
sewardj8ea867b2004-10-30 19:03:02 +0000344
345typedef
346 struct {
florian1ff47562012-10-21 02:09:51 +0000347 Int regparms;
348 const HChar* name;
349 void* addr;
350 UInt mcx_mask;
sewardj8ea867b2004-10-30 19:03:02 +0000351 }
352 IRCallee;
353
sewardj57c10c82006-11-15 02:57:05 +0000354/* Create an IRCallee. */
florian1ff47562012-10-21 02:09:51 +0000355extern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr );
sewardj8ea867b2004-10-30 19:03:02 +0000356
sewardj57c10c82006-11-15 02:57:05 +0000357/* Deep-copy an IRCallee. */
sewardjdd40fdf2006-12-24 02:20:24 +0000358extern IRCallee* deepCopyIRCallee ( IRCallee* );
sewardj8ea867b2004-10-30 19:03:02 +0000359
sewardj57c10c82006-11-15 02:57:05 +0000360/* Pretty-print an IRCallee. */
sewardj8ea867b2004-10-30 19:03:02 +0000361extern void ppIRCallee ( IRCallee* );
362
363
sewardj2d3f77c2004-09-22 23:49:09 +0000364/* ------------------ Guest state arrays ------------------ */
365
sewardj57c10c82006-11-15 02:57:05 +0000366/* This describes a section of the guest state that we want to
367 be able to index at run time, so as to be able to describe
368 indexed or rotating register files on the guest. */
sewardj2d3f77c2004-09-22 23:49:09 +0000369typedef
370 struct {
sewardj57c10c82006-11-15 02:57:05 +0000371 Int base; /* guest state offset of start of indexed area */
372 IRType elemTy; /* type of each element in the indexed area */
373 Int nElems; /* number of elements in the indexed area */
sewardj2d3f77c2004-09-22 23:49:09 +0000374 }
sewardjdd40fdf2006-12-24 02:20:24 +0000375 IRRegArray;
sewardj2d3f77c2004-09-22 23:49:09 +0000376
sewardjdd40fdf2006-12-24 02:20:24 +0000377extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
sewardj2d3f77c2004-09-22 23:49:09 +0000378
sewardjdd40fdf2006-12-24 02:20:24 +0000379extern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
sewardj695cff92004-10-13 14:50:14 +0000380
sewardjdd40fdf2006-12-24 02:20:24 +0000381extern void ppIRRegArray ( IRRegArray* );
382extern Bool eqIRRegArray ( IRRegArray*, IRRegArray* );
sewardj2d3f77c2004-09-22 23:49:09 +0000383
384
sewardjc97096c2004-06-30 09:28:04 +0000385/* ------------------ Temporaries ------------------ */
sewardjec6ad592004-06-20 12:26:53 +0000386
sewardj57c10c82006-11-15 02:57:05 +0000387/* This represents a temporary, eg. t1. The IR optimiser relies on the
388 fact that IRTemps are 32-bit ints. Do not change them to be ints of
389 any other size. */
sewardjfbcaf332004-07-08 01:46:01 +0000390typedef UInt IRTemp;
sewardjec6ad592004-06-20 12:26:53 +0000391
sewardj57c10c82006-11-15 02:57:05 +0000392/* Pretty-print an IRTemp. */
sewardj35421a32004-07-05 13:12:34 +0000393extern void ppIRTemp ( IRTemp );
sewardjec6ad592004-06-20 12:26:53 +0000394
sewardj92d168d2004-11-15 14:22:12 +0000395#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
sewardjfbcaf332004-07-08 01:46:01 +0000396
sewardjc97096c2004-06-30 09:28:04 +0000397
sewardj40c80262006-02-08 19:30:46 +0000398/* --------------- Primops (arity 1,2,3 and 4) --------------- */
sewardjec6ad592004-06-20 12:26:53 +0000399
sewardj57c10c82006-11-15 02:57:05 +0000400/* Primitive operations that are used in Unop, Binop, Triop and Qop
401 IRExprs. Once we take into account integer, floating point and SIMD
402 operations of all the different sizes, there are quite a lot of them.
403 Most instructions supported by the architectures that Vex supports
404 (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid)
405 are not; they are instead handled with dirty helpers that emulate
406 their functionality. Such obscure ones are thus not directly visible
407 in the IR, but their effects on guest state (memory and registers)
408 are made visible via the annotations in IRDirty structures.
409*/
sewardjac6b7122004-06-27 01:03:57 +0000410typedef
sewardj41f43bc2004-07-08 14:23:22 +0000411 enum {
sewardj71a35e72005-05-03 12:20:15 +0000412 /* -- Do not change this ordering. The IR generators rely on
413 (eg) Iop_Add64 == IopAdd8 + 3. -- */
414
sewardjcfe046e2013-01-17 14:23:53 +0000415 Iop_INVALID=0x1400,
sewardj66de2272004-07-16 21:19:05 +0000416 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
sewardj41f43bc2004-07-08 14:23:22 +0000417 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
sewardj41f43bc2004-07-08 14:23:22 +0000418 /* Signless mul. MullS/MullU is elsewhere. */
419 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
420 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
421 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
422 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
423 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
424 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
425 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
sewardje90ad6a2004-07-10 19:02:10 +0000426 /* Integer comparisons. */
427 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
428 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
sewardj41f43bc2004-07-08 14:23:22 +0000429 /* Tags for unary ops */
430 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
sewardj71a35e72005-05-03 12:20:15 +0000431
sewardj1fb8c922009-07-12 12:56:53 +0000432 /* Exactly like CmpEQ8/16/32/64, but carrying the additional
433 hint that these compute the success/failure of a CAS
434 operation, and hence are almost certainly applied to two
435 copies of the same value, which in turn has implications for
436 Memcheck's instrumentation. */
437 Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
438 Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
439
sewardje13074c2012-11-08 10:57:08 +0000440 /* Exactly like CmpNE8/16/32/64, but carrying the additional
441 hint that these needs expensive definedness tracking. */
442 Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
443
sewardj71a35e72005-05-03 12:20:15 +0000444 /* -- Ordering not important after here. -- */
445
sewardj9690d922004-07-14 01:39:17 +0000446 /* Widening multiplies */
sewardj9b967672005-02-08 11:13:09 +0000447 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
448 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
sewardj8f3debf2004-09-08 23:42:23 +0000449
sewardjce646f22004-08-31 23:55:54 +0000450 /* Wierdo integer stuff */
sewardjf53b7352005-04-06 20:01:56 +0000451 Iop_Clz64, Iop_Clz32, /* count leading zeroes */
452 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
453 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
454 zero. You must ensure they are never given a zero argument.
sewardj8f3debf2004-09-08 23:42:23 +0000455 */
456
sewardjb51f0f42005-07-18 11:38:02 +0000457 /* Standard integer comparisons */
sewardj98540072005-04-26 01:52:01 +0000458 Iop_CmpLT32S, Iop_CmpLT64S,
459 Iop_CmpLE32S, Iop_CmpLE64S,
460 Iop_CmpLT32U, Iop_CmpLT64U,
461 Iop_CmpLE32U, Iop_CmpLE64U,
sewardj343b9d02005-01-31 18:08:45 +0000462
sewardj0033ddc2005-04-26 23:34:34 +0000463 /* As a sop to Valgrind-Memcheck, the following are useful. */
464 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
sewardjeb17e492007-08-25 23:07:44 +0000465 Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
466 Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
sewardj478646f2008-05-01 20:13:04 +0000467 Iop_Max32U, /* unsigned max */
sewardj0033ddc2005-04-26 23:34:34 +0000468
sewardj57c10c82006-11-15 02:57:05 +0000469 /* PowerPC-style 3-way integer comparisons. Without them it is
470 difficult to simulate PPC efficiently.
sewardjb51f0f42005-07-18 11:38:02 +0000471 op(x,y) | x < y = 0x8 else
472 | x > y = 0x4 else
473 | x == y = 0x2
474 */
cerion2831b002005-11-30 19:55:22 +0000475 Iop_CmpORD32U, Iop_CmpORD64U,
476 Iop_CmpORD32S, Iop_CmpORD64S,
sewardjb51f0f42005-07-18 11:38:02 +0000477
sewardj9690d922004-07-14 01:39:17 +0000478 /* Division */
sewardj8f3debf2004-09-08 23:42:23 +0000479 /* TODO: clarify semantics wrt rounding, negative values, whatever */
cerion5c8a0cb2005-02-03 13:59:46 +0000480 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod)
481 Iop_DivS32, // ditto, signed
cerionf0de28c2005-12-13 20:21:11 +0000482 Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod)
483 Iop_DivS64, // ditto, signed
sewardje71e56a2011-09-05 12:11:06 +0000484 Iop_DivU64E, // :: I64,I64 -> I64 (dividend is 64-bit arg (hi) concat with 64 0's (low))
485 Iop_DivS64E, // ditto, signed
sewardj4aa412a2011-07-24 14:13:21 +0000486 Iop_DivU32E, // :: I32,I32 -> I32 (dividend is 32-bit arg (hi) concat with 32 0's (low))
sewardje71e56a2011-09-05 12:11:06 +0000487 Iop_DivS32E, // ditto, signed
cerion5c8a0cb2005-02-03 13:59:46 +0000488
sewardj9690d922004-07-14 01:39:17 +0000489 Iop_DivModU64to32, // :: I64,I32 -> I64
490 // of which lo half is div and hi half is mod
491 Iop_DivModS64to32, // ditto, signed
sewardj89d4e982004-09-12 19:14:46 +0000492
sewardj343b9d02005-01-31 18:08:45 +0000493 Iop_DivModU128to64, // :: V128,I64 -> V128
494 // of which lo half is div and hi half is mod
495 Iop_DivModS128to64, // ditto, signed
496
sewardj2019a972011-03-07 16:04:07 +0000497 Iop_DivModS64to64, // :: I64,I64 -> I128
498 // of which lo half is div and hi half is mod
499
sewardj0033ddc2005-04-26 23:34:34 +0000500 /* Integer conversions. Some of these are redundant (eg
501 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
502 having a complete set reduces the typical dynamic size of IR
503 and makes the instruction selectors easier to write. */
504
sewardj9690d922004-07-14 01:39:17 +0000505 /* Widening conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000506 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64,
507 Iop_16Uto32, Iop_16Uto64,
508 Iop_32Uto64,
509 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64,
510 Iop_16Sto32, Iop_16Sto64,
511 Iop_32Sto64,
512
sewardja2384712004-07-29 14:36:40 +0000513 /* Narrowing conversions */
sewardj0033ddc2005-04-26 23:34:34 +0000514 Iop_64to8, Iop_32to8, Iop_64to16,
sewardjb81f8b32004-07-30 10:17:50 +0000515 /* 8 <-> 16 bit conversions */
516 Iop_16to8, // :: I16 -> I8, low half
517 Iop_16HIto8, // :: I16 -> I8, high half
518 Iop_8HLto16, // :: (I8,I8) -> I16
sewardj8c7f1ab2004-07-29 20:31:09 +0000519 /* 16 <-> 32 bit conversions */
520 Iop_32to16, // :: I32 -> I16, low half
521 Iop_32HIto16, // :: I32 -> I16, high half
522 Iop_16HLto32, // :: (I16,I16) -> I32
sewardj9690d922004-07-14 01:39:17 +0000523 /* 32 <-> 64 bit conversions */
sewardj8c7f1ab2004-07-29 20:31:09 +0000524 Iop_64to32, // :: I64 -> I32, low half
sewardj9690d922004-07-14 01:39:17 +0000525 Iop_64HIto32, // :: I64 -> I32, high half
526 Iop_32HLto64, // :: (I32,I32) -> I64
sewardj9b967672005-02-08 11:13:09 +0000527 /* 64 <-> 128 bit conversions */
528 Iop_128to64, // :: I128 -> I64, low half
529 Iop_128HIto64, // :: I128 -> I64, high half
530 Iop_64HLto128, // :: (I64,I64) -> I128
sewardjcf780b42004-07-13 18:42:17 +0000531 /* 1-bit stuff */
sewardj6e797c52004-10-13 15:20:17 +0000532 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */
sewardj84ff0652004-08-23 16:16:08 +0000533 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
sewardj291a7e82005-04-27 11:42:44 +0000534 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
535 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
sewardj84ff0652004-08-23 16:16:08 +0000536 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
sewardj291a7e82005-04-27 11:42:44 +0000537 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
sewardjfd332772004-11-09 16:01:40 +0000538 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */
sewardj8eda6302004-11-05 01:55:46 +0000539 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
sewardjcf787902004-11-03 09:08:33 +0000540 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
sewardjb5874aa2004-11-04 16:57:50 +0000541 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
sewardj8f3debf2004-09-08 23:42:23 +0000542
sewardjbaf971a2006-01-27 15:09:35 +0000543 /* ------ Floating point. We try to be IEEE754 compliant. ------ */
sewardj8f3debf2004-09-08 23:42:23 +0000544
sewardjb183b852006-02-03 16:08:03 +0000545 /* --- Simple stuff as mandated by 754. --- */
sewardjcfded9a2004-09-09 11:44:16 +0000546
sewardjb183b852006-02-03 16:08:03 +0000547 /* Binary operations, with rounding. */
548 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
549 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
sewardj52ace3e2004-09-11 17:10:08 +0000550
sewardj6c299f32009-12-31 18:00:12 +0000551 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
552 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
553
sewardjb183b852006-02-03 16:08:03 +0000554 /* Variants of the above which produce a 64-bit result but which
555 round their result to a IEEE float range first. */
556 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
557 Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
sewardj52ace3e2004-09-11 17:10:08 +0000558
sewardjb183b852006-02-03 16:08:03 +0000559 /* Unary operations, without rounding. */
560 /* :: F64 -> F64 */
561 Iop_NegF64, Iop_AbsF64,
sewardj8f3debf2004-09-08 23:42:23 +0000562
sewardj6c299f32009-12-31 18:00:12 +0000563 /* :: F32 -> F32 */
564 Iop_NegF32, Iop_AbsF32,
565
sewardjb183b852006-02-03 16:08:03 +0000566 /* Unary operations, with rounding. */
567 /* :: IRRoundingMode(I32) x F64 -> F64 */
florian6d522282012-08-21 22:15:19 +0000568 Iop_SqrtF64,
sewardjbaf971a2006-01-27 15:09:35 +0000569
sewardj6c299f32009-12-31 18:00:12 +0000570 /* :: IRRoundingMode(I32) x F32 -> F32 */
571 Iop_SqrtF32,
572
sewardj8f3debf2004-09-08 23:42:23 +0000573 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
sewardj883b00b2004-09-11 09:30:24 +0000574 0x45 Unordered
sewardj8f3debf2004-09-08 23:42:23 +0000575 0x01 LT
576 0x00 GT
sewardj883b00b2004-09-11 09:30:24 +0000577 0x40 EQ
sewardj8f3debf2004-09-08 23:42:23 +0000578 This just happens to be the Intel encoding. The values
579 are recorded in the type IRCmpF64Result.
580 */
sewardj6c299f32009-12-31 18:00:12 +0000581 /* :: F64 x F64 -> IRCmpF64Result(I32) */
sewardj8f3debf2004-09-08 23:42:23 +0000582 Iop_CmpF64,
sewardj2019a972011-03-07 16:04:07 +0000583 Iop_CmpF32,
584 Iop_CmpF128,
sewardj8f3debf2004-09-08 23:42:23 +0000585
sewardj3bca9062004-12-04 14:36:09 +0000586 /* --- Int to/from FP conversions. --- */
sewardjb183b852006-02-03 16:08:03 +0000587
sewardj6c299f32009-12-31 18:00:12 +0000588 /* For the most part, these take a first argument :: Ity_I32 (as
589 IRRoundingMode) which is an indication of the rounding mode
590 to use, as per the following encoding ("the standard
591 encoding"):
sewardj8f3debf2004-09-08 23:42:23 +0000592 00b to nearest (the default)
593 01b to -infinity
594 10b to +infinity
595 11b to zero
596 This just happens to be the Intel encoding. For reference only,
597 the PPC encoding is:
598 00b to nearest (the default)
599 01b to zero
600 10b to +infinity
601 11b to -infinity
602 Any PPC -> IR front end will have to translate these PPC
sewardj6c299f32009-12-31 18:00:12 +0000603 encodings, as encoded in the guest state, to the standard
604 encodings, to pass to the primops.
605 For reference only, the ARM VFP encoding is:
606 00b to nearest
607 01b to +infinity
608 10b to -infinity
609 11b to zero
610 Again, this will have to be converted to the standard encoding
611 to pass to primops.
sewardj8f3debf2004-09-08 23:42:23 +0000612
613 If one of these conversions gets an out-of-range condition,
614 or a NaN, as an argument, the result is host-defined. On x86
sewardj6c299f32009-12-31 18:00:12 +0000615 the "integer indefinite" value 0x80..00 is produced. On PPC
616 it is either 0x80..00 or 0x7F..FF depending on the sign of
617 the argument.
618
619 On ARMvfp, when converting to a signed integer result, the
620 overflow result is 0x80..00 for negative args and 0x7F..FF
621 for positive args. For unsigned integer results it is
622 0x00..00 and 0xFF..FF respectively.
sewardj52ace3e2004-09-11 17:10:08 +0000623
sewardj3bca9062004-12-04 14:36:09 +0000624 Rounding is required whenever the destination type cannot
625 represent exactly all values of the source type.
626 */
sewardj6c299f32009-12-31 18:00:12 +0000627 Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
628 Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
629 Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
sewardj4aa412a2011-07-24 14:13:21 +0000630 Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
sewardj3bca9062004-12-04 14:36:09 +0000631
sewardj6c299f32009-12-31 18:00:12 +0000632 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
sewardj3bca9062004-12-04 14:36:09 +0000633
sewardj6c299f32009-12-31 18:00:12 +0000634 Iop_I32StoF64, /* signed I32 -> F64 */
635 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
sewardj66d5ef22011-04-15 11:55:00 +0000636 Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
637 Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
sewardj6c299f32009-12-31 18:00:12 +0000638
florian1c8f7ff2012-09-01 00:12:11 +0000639 Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */
sewardj6c299f32009-12-31 18:00:12 +0000640 Iop_I32UtoF64, /* unsigned I32 -> F64 */
641
sewardj2019a972011-03-07 16:04:07 +0000642 Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
643 Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
florian1c8f7ff2012-09-01 00:12:11 +0000644 Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */
645 Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */
sewardj2019a972011-03-07 16:04:07 +0000646
sewardj2019a972011-03-07 16:04:07 +0000647 Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
648 Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
649
sewardj6c299f32009-12-31 18:00:12 +0000650 /* Conversion between floating point formats */
sewardj3bca9062004-12-04 14:36:09 +0000651 Iop_F32toF64, /* F32 -> F64 */
652 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */
sewardj4cb918d2004-12-03 19:43:31 +0000653
sewardj17442fe2004-09-20 14:54:28 +0000654 /* Reinterpretation. Take an F64 and produce an I64 with
655 the same bit pattern, or vice versa. */
sewardjc9a43662004-11-30 18:51:59 +0000656 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
sewardjfc1b5412007-01-09 15:20:07 +0000657 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
sewardjb183b852006-02-03 16:08:03 +0000658
sewardj2019a972011-03-07 16:04:07 +0000659 /* Support for 128-bit floating point */
660 Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
661 Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
662 Iop_F128LOtoF64,/* F128 -> low half of F128 into a F64 register */
663
664 /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
665 Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
666
667 /* :: F128 -> F128 */
668 Iop_NegF128, Iop_AbsF128,
669
670 /* :: IRRoundingMode(I32) x F128 -> F128 */
671 Iop_SqrtF128,
672
673 Iop_I32StoF128, /* signed I32 -> F128 */
674 Iop_I64StoF128, /* signed I64 -> F128 */
florian1c8f7ff2012-09-01 00:12:11 +0000675 Iop_I32UtoF128, /* unsigned I32 -> F128 */
676 Iop_I64UtoF128, /* unsigned I64 -> F128 */
sewardj2019a972011-03-07 16:04:07 +0000677 Iop_F32toF128, /* F32 -> F128 */
678 Iop_F64toF128, /* F64 -> F128 */
679
680 Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32 */
681 Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64 */
florian1c8f7ff2012-09-01 00:12:11 +0000682 Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32 */
683 Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64 */
sewardj2019a972011-03-07 16:04:07 +0000684 Iop_F128toF64, /* IRRoundingMode(I32) x F128 -> F64 */
685 Iop_F128toF32, /* IRRoundingMode(I32) x F128 -> F32 */
686
sewardjb183b852006-02-03 16:08:03 +0000687 /* --- guest x86/amd64 specifics, not mandated by 754. --- */
688
689 /* Binary ops, with rounding. */
690 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
691 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
692 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
693 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
694 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */
695 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
696 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */
697 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
698 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
699 /* Note that on x86 guest, PRem1{C3210} has the same behaviour
700 as the IEEE mandated RemF64, except it is limited in the
701 range of its operand. Hence the partialness. */
702
703 /* Unary ops, with rounding. */
704 /* :: IRRoundingMode(I32) x F64 -> F64 */
705 Iop_SinF64, /* FSIN */
706 Iop_CosF64, /* FCOS */
707 Iop_TanF64, /* FTAN */
708 Iop_2xm1F64, /* (2^arg - 1.0) */
709 Iop_RoundF64toInt, /* F64 value to nearest integral value (still
710 as F64) */
sewardjd15b5972010-06-27 09:06:34 +0000711 Iop_RoundF32toInt, /* F32 value to nearest integral value (still
712 as F32) */
sewardjb183b852006-02-03 16:08:03 +0000713
sewardj2019a972011-03-07 16:04:07 +0000714 /* --- guest s390 specifics, not mandated by 754. --- */
715
716 /* Fused multiply-add/sub */
717 /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
florian5906a6b2012-10-16 02:53:33 +0000718 (computes arg2 * arg3 +/- arg4) */
sewardj2019a972011-03-07 16:04:07 +0000719 Iop_MAddF32, Iop_MSubF32,
720
sewardjb183b852006-02-03 16:08:03 +0000721 /* --- guest ppc32/64 specifics, not mandated by 754. --- */
722
sewardj40c80262006-02-08 19:30:46 +0000723 /* Ternary operations, with rounding. */
724 /* Fused multiply-add/sub, with 112-bit intermediate
sewardj2019a972011-03-07 16:04:07 +0000725 precision for ppc.
726 Also used to implement fused multiply-add/sub for s390. */
sewardj40c80262006-02-08 19:30:46 +0000727 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
728 (computes arg2 * arg3 +/- arg4) */
729 Iop_MAddF64, Iop_MSubF64,
730
731 /* Variants of the above which produce a 64-bit result but which
732 round their result to a IEEE float range first. */
733 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
734 Iop_MAddF64r32, Iop_MSubF64r32,
735
sewardjb183b852006-02-03 16:08:03 +0000736 /* :: F64 -> F64 */
737 Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */
sewardj0f1ef862008-08-08 08:37:06 +0000738 Iop_RoundF64toF64_NEAREST, /* frin */
739 Iop_RoundF64toF64_NegINF, /* frim */
740 Iop_RoundF64toF64_PosINF, /* frip */
741 Iop_RoundF64toF64_ZERO, /* friz */
sewardjb183b852006-02-03 16:08:03 +0000742
743 /* :: F64 -> F32 */
744 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
745
746 /* :: IRRoundingMode(I32) x F64 -> F64 */
747 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
748 /* NB: pretty much the same as Iop_F64toF32, except no change
749 of type. */
750
sewardje2ea1762010-09-22 00:56:37 +0000751 /* ------------------ 32-bit SIMD Integer ------------------ */
752
sewardj44ce46d2012-07-11 13:19:10 +0000753 /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
754 Iop_QAdd32S,
755 Iop_QSub32S,
756
sewardje2ea1762010-09-22 00:56:37 +0000757 /* 16x2 add/sub, also signed/unsigned saturating variants */
758 Iop_Add16x2, Iop_Sub16x2,
759 Iop_QAdd16Sx2, Iop_QAdd16Ux2,
760 Iop_QSub16Sx2, Iop_QSub16Ux2,
761
762 /* 16x2 signed/unsigned halving add/sub. For each lane, these
763 compute bits 16:1 of (eg) sx(argL) + sx(argR),
764 or zx(argL) - zx(argR) etc. */
765 Iop_HAdd16Ux2, Iop_HAdd16Sx2,
766 Iop_HSub16Ux2, Iop_HSub16Sx2,
767
768 /* 8x4 add/sub, also signed/unsigned saturating variants */
769 Iop_Add8x4, Iop_Sub8x4,
770 Iop_QAdd8Sx4, Iop_QAdd8Ux4,
771 Iop_QSub8Sx4, Iop_QSub8Ux4,
772
773 /* 8x4 signed/unsigned halving add/sub. For each lane, these
774 compute bits 8:1 of (eg) sx(argL) + sx(argR),
775 or zx(argL) - zx(argR) etc. */
776 Iop_HAdd8Ux4, Iop_HAdd8Sx4,
777 Iop_HSub8Ux4, Iop_HSub8Sx4,
778
sewardj310d6b22010-10-18 16:29:40 +0000779 /* 8x4 sum of absolute unsigned differences. */
780 Iop_Sad8Ux4,
781
sewardje2ea1762010-09-22 00:56:37 +0000782 /* MISC (vector integer cmp != 0) */
783 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
784
sewardj2fdd4162010-08-22 12:59:02 +0000785 /* ------------------ 64-bit SIMD FP ------------------------ */
786
787 /* Convertion to/from int */
788 Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */
789 Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */
790 /* Fixed32 format is floating-point number with fixed number of fraction
791 bits. The number of fraction bits is passed as a second argument of
792 type I8. */
793 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
794 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
795
796 /* Binary operations */
797 Iop_Max32Fx2, Iop_Min32Fx2,
798 /* Pairwise Min and Max. See integer pairwise operations for more
799 details. */
800 Iop_PwMax32Fx2, Iop_PwMin32Fx2,
801 /* Note: For the following compares, the arm front-end assumes a
802 nan in a lane of either argument returns zero for that lane. */
803 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
804
805 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
806 element in the operand vector, and places the results in the destination
807 vector. */
808 Iop_Recip32Fx2,
809
810 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
811 Note, that if one of the arguments is zero and another one is infinity
812 of arbitrary sign the result of the operation is 2.0. */
813 Iop_Recps32Fx2,
814
815 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
816 square root of each element in the operand vector. */
817 Iop_Rsqrte32Fx2,
818
819 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
820 Note, that of one of the arguments is zero and another one is infiinty
821 of arbitrary sign the result of the operation is 1.5. */
822 Iop_Rsqrts32Fx2,
823
824 /* Unary */
825 Iop_Neg32Fx2, Iop_Abs32Fx2,
826
sewardj38a3f862005-01-13 15:06:51 +0000827 /* ------------------ 64-bit SIMD Integer. ------------------ */
828
829 /* MISC (vector integer cmp != 0) */
sewardj18069182005-01-13 19:16:04 +0000830 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
sewardj38a3f862005-01-13 15:06:51 +0000831
832 /* ADDITION (normal / unsigned sat / signed sat) */
833 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000834 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
835 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
836
837 /* PAIRWISE operations */
838 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
839 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
840 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2,
841 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
842 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
843 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
844 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
845 /* Longening variant is unary. The resulting vector contains two times
846 less elements than operand, but they are two times wider.
847 Example:
848 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
849 where a+b and c+d are unsigned 32-bit values. */
850 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
851 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000852
853 /* SUBTRACTION (normal / unsigned sat / signed sat) */
854 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000855 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
856 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
sewardj38a3f862005-01-13 15:06:51 +0000857
sewardj2fdd4162010-08-22 12:59:02 +0000858 /* ABSOLUTE VALUE */
859 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
860
861 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
862 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
863 Iop_Mul32Fx2,
sewardj38a3f862005-01-13 15:06:51 +0000864 Iop_MulHi16Ux4,
865 Iop_MulHi16Sx4,
sewardj2fdd4162010-08-22 12:59:02 +0000866 /* Plynomial multiplication treats it's arguments as coefficients of
867 polynoms over {0, 1}. */
868 Iop_PolynomialMul8x8,
869
870 /* Vector Saturating Doubling Multiply Returning High Half and
871 Vector Saturating Rounding Doubling Multiply Returning High Half */
872 /* These IROp's multiply corresponding elements in two vectors, double
873 the results, and place the most significant half of the final results
874 in the destination vector. The results are truncated or rounded. If
875 any of the results overflow, they are saturated. */
876 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
877 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
sewardj38a3f862005-01-13 15:06:51 +0000878
sewardj5ce5fd62005-04-19 23:06:11 +0000879 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
sewardj38a3f862005-01-13 15:06:51 +0000880 Iop_Avg8Ux8,
881 Iop_Avg16Ux4,
882
883 /* MIN/MAX */
sewardj2fdd4162010-08-22 12:59:02 +0000884 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
885 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
886 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
887 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000888
889 /* COMPARISON */
890 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000891 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
sewardj38a3f862005-01-13 15:06:51 +0000892 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
893
sewardj2fdd4162010-08-22 12:59:02 +0000894 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
895 bit) */
896 Iop_Cnt8x8,
897 Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2,
898 Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2,
899
900 /* VECTOR x VECTOR SHIFT / ROTATE */
901 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
902 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
903 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
904 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
905
sewardj38a3f862005-01-13 15:06:51 +0000906 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
sewardjd166e282008-02-06 11:42:45 +0000907 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000908 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
sewardjd71ba832006-12-27 01:15:29 +0000909 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
sewardj38a3f862005-01-13 15:06:51 +0000910
sewardj2fdd4162010-08-22 12:59:02 +0000911 /* VECTOR x VECTOR SATURATING SHIFT */
912 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
913 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
914 /* VECTOR x INTEGER SATURATING SHIFT */
915 Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1,
916 Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1,
917 Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1,
918
sewardj5f438dd2011-06-16 11:36:23 +0000919 /* NARROWING (binary)
920 -- narrow 2xI64 into 1xI64, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +0000921 /* For saturated narrowing, I believe there are 4 variants of
922 the basic arithmetic operation, depending on the signedness
923 of argument and result. Here are examples that exemplify
924 what I mean:
925
926 QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255;
927 return x[7:0];
928
929 QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128;
930 if (x >s 127) x = 127;
931 return x[7:0];
932
933 QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127;
934 return x[7:0];
935
936 QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0;
937 if (x >s 255) x = 255;
938 return x[7:0];
939 */
sewardj5f438dd2011-06-16 11:36:23 +0000940 Iop_QNarrowBin16Sto8Ux8,
941 Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
sewardjad2c9ea2011-10-22 09:32:16 +0000942 Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4,
sewardj38a3f862005-01-13 15:06:51 +0000943
sewardj2fdd4162010-08-22 12:59:02 +0000944 /* INTERLEAVING */
945 /* Interleave lanes from low or high halves of
sewardj38a3f862005-01-13 15:06:51 +0000946 operands. Most-significant result lane is from the left
947 arg. */
948 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
949 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
sewardj2fdd4162010-08-22 12:59:02 +0000950 /* Interleave odd/even lanes of operands. Most-significant result lane
951 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are
952 identical to Interleave{HI,LO}32x2 and so are omitted.*/
953 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
954 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
955
sewardjd166e282008-02-06 11:42:45 +0000956 /* CONCATENATION -- build a new value by concatenating either
957 the even or odd lanes of both operands. Note that
958 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
959 and so are omitted. */
sewardj2fdd4162010-08-22 12:59:02 +0000960 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
961 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
962
963 /* GET / SET elements of VECTOR
964 GET is binop (I64, I8) -> I<elem_size>
965 SET is triop (I64, I8, I<elem_size>) -> I64 */
966 /* Note: the arm back-end handles only constant second argument */
967 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
968 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
969
970 /* DUPLICATING -- copy value to all lanes */
971 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2,
972
973 /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes
974 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
975 result.
976 It is a triop: (I64, I64, I8) -> I64 */
977 /* Note: the arm back-end handles only constant third argumnet. */
978 Iop_Extract64,
979
980 /* REVERSE the order of elements in each Half-words, Words,
981 Double-words */
982 /* Examples:
983 Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
984 Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
985 Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
986 Iop_Reverse16_8x8,
987 Iop_Reverse32_8x8, Iop_Reverse32_16x4,
988 Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2,
sewardjd166e282008-02-06 11:42:45 +0000989
990 /* PERMUTING -- copy src bytes to dst,
991 as indexed by control vector bytes:
992 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
993 argR[i] values may only be in the range 0 .. 7, else behaviour
994 is undefined. */
995 Iop_Perm8x8,
996
sewardje13074c2012-11-08 10:57:08 +0000997 /* MISC CONVERSION -- get high bits of each byte lane, a la
998 x86/amd64 pmovmskb */
999 Iop_GetMSBs8x8, /* I64 -> I8 */
1000
sewardj2fdd4162010-08-22 12:59:02 +00001001 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1002 See floating-point equiwalents for details. */
1003 Iop_Recip32x2, Iop_Rsqrte32x2,
1004
sewardjc6bbd472012-04-02 10:20:48 +00001005 /* ------------------ Decimal Floating Point ------------------ */
1006
1007 /* ARITHMETIC INSTRUCTIONS 64-bit
1008 ----------------------------------
florian79e5a482013-06-06 19:12:46 +00001009 IRRoundingMode(I32) X D64 X D64 -> D64
sewardjc6bbd472012-04-02 10:20:48 +00001010 */
1011 Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1012
1013 /* ARITHMETIC INSTRUCTIONS 128-bit
1014 ----------------------------------
florian79e5a482013-06-06 19:12:46 +00001015 IRRoundingMode(I32) X D128 X D128 -> D128
sewardjc6bbd472012-04-02 10:20:48 +00001016 */
1017 Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1018
sewardj26217b02012-04-12 17:19:48 +00001019 /* SHIFT SIGNIFICAND INSTRUCTIONS
1020 * The DFP significand is shifted by the number of digits specified
1021 * by the U8 operand. Digits shifted out of the leftmost digit are
1022 * lost. Zeros are supplied to the vacated positions on the right.
1023 * The sign of the result is the same as the sign of the original
1024 * operand.
sewardjcdc376d2012-04-23 11:21:12 +00001025 *
1026 * D64 x U8 -> D64 left shift and right shift respectively */
sewardj26217b02012-04-12 17:19:48 +00001027 Iop_ShlD64, Iop_ShrD64,
1028
1029 /* D128 x U8 -> D128 left shift and right shift respectively */
1030 Iop_ShlD128, Iop_ShrD128,
1031
1032
1033 /* FORMAT CONVERSION INSTRUCTIONS
1034 * D32 -> D64
1035 */
1036 Iop_D32toD64,
1037
1038 /* D64 -> D128 */
1039 Iop_D64toD128,
1040
florianb17e16f2013-01-12 22:02:07 +00001041 /* I32S -> D128 */
1042 Iop_I32StoD128,
1043
1044 /* I32U -> D128 */
1045 Iop_I32UtoD128,
1046
sewardj26217b02012-04-12 17:19:48 +00001047 /* I64S -> D128 */
1048 Iop_I64StoD128,
1049
florianb17e16f2013-01-12 22:02:07 +00001050 /* I64U -> D128 */
1051 Iop_I64UtoD128,
1052
florian79e5a482013-06-06 19:12:46 +00001053 /* IRRoundingMode(I32) x D64 -> D32 */
sewardj26217b02012-04-12 17:19:48 +00001054 Iop_D64toD32,
1055
florian79e5a482013-06-06 19:12:46 +00001056 /* IRRoundingMode(I32) x D128 -> D64 */
sewardj26217b02012-04-12 17:19:48 +00001057 Iop_D128toD64,
1058
florianb17e16f2013-01-12 22:02:07 +00001059 /* I32S -> D64 */
1060 Iop_I32StoD64,
1061
1062 /* I32U -> D64 */
1063 Iop_I32UtoD64,
1064
florian79e5a482013-06-06 19:12:46 +00001065 /* IRRoundingMode(I32) x I64 -> D64 */
sewardj26217b02012-04-12 17:19:48 +00001066 Iop_I64StoD64,
1067
florian79e5a482013-06-06 19:12:46 +00001068 /* IRRoundingMode(I32) x I64 -> D64 */
florianb17e16f2013-01-12 22:02:07 +00001069 Iop_I64UtoD64,
1070
florian79e5a482013-06-06 19:12:46 +00001071 /* IRRoundingMode(I32) x D64 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001072 Iop_D64toI32S,
1073
florian79e5a482013-06-06 19:12:46 +00001074 /* IRRoundingMode(I32) x D64 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001075 Iop_D64toI32U,
1076
florian79e5a482013-06-06 19:12:46 +00001077 /* IRRoundingMode(I32) x D64 -> I64 */
sewardj26217b02012-04-12 17:19:48 +00001078 Iop_D64toI64S,
1079
florian79e5a482013-06-06 19:12:46 +00001080 /* IRRoundingMode(I32) x D64 -> I64 */
florianb17e16f2013-01-12 22:02:07 +00001081 Iop_D64toI64U,
1082
florian79e5a482013-06-06 19:12:46 +00001083 /* IRRoundingMode(I32) x D128 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001084 Iop_D128toI32S,
1085
florian79e5a482013-06-06 19:12:46 +00001086 /* IRRoundingMode(I32) x D128 -> I32 */
florianb17e16f2013-01-12 22:02:07 +00001087 Iop_D128toI32U,
1088
florian79e5a482013-06-06 19:12:46 +00001089 /* IRRoundingMode(I32) x D128 -> I64 */
sewardj26217b02012-04-12 17:19:48 +00001090 Iop_D128toI64S,
1091
florian79e5a482013-06-06 19:12:46 +00001092 /* IRRoundingMode(I32) x D128 -> I64 */
florianb17e16f2013-01-12 22:02:07 +00001093 Iop_D128toI64U,
1094
florianb22838d2013-06-17 18:59:51 +00001095 /* IRRoundingMode(I32) x F32 -> D32 */
1096 Iop_F32toD32,
1097
1098 /* IRRoundingMode(I32) x F32 -> D64 */
1099 Iop_F32toD64,
1100
1101 /* IRRoundingMode(I32) x F32 -> D128 */
1102 Iop_F32toD128,
1103
1104 /* IRRoundingMode(I32) x F64 -> D32 */
1105 Iop_F64toD32,
1106
florian79e5a482013-06-06 19:12:46 +00001107 /* IRRoundingMode(I32) x F64 -> D64 */
florian37c57f32013-05-05 15:04:30 +00001108 Iop_F64toD64,
1109
florian79e5a482013-06-06 19:12:46 +00001110 /* IRRoundingMode(I32) x F64 -> D128 */
florian37c57f32013-05-05 15:04:30 +00001111 Iop_F64toD128,
1112
florianb22838d2013-06-17 18:59:51 +00001113 /* IRRoundingMode(I32) x F128 -> D32 */
1114 Iop_F128toD32,
1115
1116 /* IRRoundingMode(I32) x F128 -> D64 */
1117 Iop_F128toD64,
florian37c57f32013-05-05 15:04:30 +00001118
florian79e5a482013-06-06 19:12:46 +00001119 /* IRRoundingMode(I32) x F128 -> D128 */
florian37c57f32013-05-05 15:04:30 +00001120 Iop_F128toD128,
1121
florianb22838d2013-06-17 18:59:51 +00001122 /* IRRoundingMode(I32) x D32 -> F32 */
1123 Iop_D32toF32,
1124
1125 /* IRRoundingMode(I32) x D32 -> F64 */
1126 Iop_D32toF64,
1127
1128 /* IRRoundingMode(I32) x D32 -> F128 */
1129 Iop_D32toF128,
1130
1131 /* IRRoundingMode(I32) x D64 -> F32 */
1132 Iop_D64toF32,
1133
1134 /* IRRoundingMode(I32) x D64 -> F64 */
1135 Iop_D64toF64,
1136
1137 /* IRRoundingMode(I32) x D64 -> F128 */
1138 Iop_D64toF128,
1139
1140 /* IRRoundingMode(I32) x D128 -> F32 */
1141 Iop_D128toF32,
1142
1143 /* IRRoundingMode(I32) x D128 -> F64 */
1144 Iop_D128toF64,
1145
florian79e5a482013-06-06 19:12:46 +00001146 /* IRRoundingMode(I32) x D128 -> F128 */
florian37c57f32013-05-05 15:04:30 +00001147 Iop_D128toF128,
1148
sewardjcdc376d2012-04-23 11:21:12 +00001149 /* ROUNDING INSTRUCTIONS
1150 * IRRoundingMode(I32) x D64 -> D64
carllcea07cc2013-01-22 20:25:31 +00001151 * The D64 operand, if a finite number, it is rounded to a
1152 * floating point integer value, i.e. no fractional part.
sewardjcdc376d2012-04-23 11:21:12 +00001153 */
1154 Iop_RoundD64toInt,
1155
1156 /* IRRoundingMode(I32) x D128 -> D128 */
1157 Iop_RoundD128toInt,
1158
1159 /* COMPARE INSTRUCTIONS
1160 * D64 x D64 -> IRCmpD64Result(I32) */
1161 Iop_CmpD64,
1162
floriandaa40842012-12-21 20:24:24 +00001163 /* D128 x D128 -> IRCmpD128Result(I32) */
sewardjcdc376d2012-04-23 11:21:12 +00001164 Iop_CmpD128,
1165
florian20c6bca2012-12-26 17:47:19 +00001166 /* COMPARE BIASED EXPONENET INSTRUCTIONS
1167 * D64 x D64 -> IRCmpD64Result(I32) */
1168 Iop_CmpExpD64,
1169
1170 /* D128 x D128 -> IRCmpD128Result(I32) */
1171 Iop_CmpExpD128,
1172
sewardjcdc376d2012-04-23 11:21:12 +00001173 /* QUANTIZE AND ROUND INSTRUCTIONS
1174 * The source operand is converted and rounded to the form with the
1175 * immediate exponent specified by the rounding and exponent parameter.
1176 *
1177 * The second operand is converted and rounded to the form
1178 * of the first operand's exponent and the rounded based on the specified
1179 * rounding mode parameter.
1180 *
florian79e5a482013-06-06 19:12:46 +00001181 * IRRoundingMode(I32) x D64 x D64-> D64 */
sewardjcdc376d2012-04-23 11:21:12 +00001182 Iop_QuantizeD64,
1183
florian79e5a482013-06-06 19:12:46 +00001184 /* IRRoundingMode(I32) x D128 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001185 Iop_QuantizeD128,
1186
florian79e5a482013-06-06 19:12:46 +00001187 /* IRRoundingMode(I32) x I8 x D64 -> D64
sewardjcdc376d2012-04-23 11:21:12 +00001188 * The Decimal Floating point operand is rounded to the requested
1189 * significance given by the I8 operand as specified by the rounding
1190 * mode.
1191 */
1192 Iop_SignificanceRoundD64,
1193
florian79e5a482013-06-06 19:12:46 +00001194 /* IRRoundingMode(I32) x I8 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001195 Iop_SignificanceRoundD128,
1196
1197 /* EXTRACT AND INSERT INSTRUCTIONS
1198 * D64 -> I64
1199 * The exponent of the D32 or D64 operand is extracted. The
1200 * extracted exponent is converted to a 64-bit signed binary integer.
1201 */
1202 Iop_ExtractExpD64,
1203
1204 /* D128 -> I64 */
1205 Iop_ExtractExpD128,
1206
florian4bbd3ec2012-12-27 20:01:13 +00001207 /* D64 -> I64
1208 * The number of significand digits of the D64 operand is extracted.
1209 * The number is stored as a 64-bit signed binary integer.
1210 */
1211 Iop_ExtractSigD64,
1212
1213 /* D128 -> I64 */
1214 Iop_ExtractSigD128,
1215
carllcea07cc2013-01-22 20:25:31 +00001216 /* I64 x D64 -> D64
sewardjcdc376d2012-04-23 11:21:12 +00001217 * The exponent is specified by the first I64 operand the signed
1218 * significand is given by the second I64 value. The result is a D64
1219 * value consisting of the specified significand and exponent whose
1220 * sign is that of the specified significand.
1221 */
1222 Iop_InsertExpD64,
1223
carllcea07cc2013-01-22 20:25:31 +00001224 /* I64 x D128 -> D128 */
sewardjcdc376d2012-04-23 11:21:12 +00001225 Iop_InsertExpD128,
1226
sewardjc6bbd472012-04-02 10:20:48 +00001227 /* Support for 128-bit DFP type */
1228 Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1229
sewardj4c96e612012-06-02 23:47:02 +00001230 /* I64 -> I64
1231 * Convert 50-bit densely packed BCD string to 60 bit BCD string
1232 */
1233 Iop_DPBtoBCD,
1234
1235 /* I64 -> I64
1236 * Convert 60 bit BCD string to 50-bit densely packed BCD string
1237 */
1238 Iop_BCDtoDPB,
1239
sewardjcdc376d2012-04-23 11:21:12 +00001240 /* Conversion I64 -> D64 */
1241 Iop_ReinterpI64asD64,
1242
sewardj5eff1c52012-04-29 20:19:17 +00001243 /* Conversion D64 -> I64 */
1244 Iop_ReinterpD64asI64,
1245
sewardj164f9272004-12-09 00:39:32 +00001246 /* ------------------ 128-bit SIMD FP. ------------------ */
sewardjc9a43662004-11-30 18:51:59 +00001247
1248 /* --- 32x4 vector FP --- */
1249
1250 /* binary */
1251 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
1252 Iop_Max32Fx4, Iop_Min32Fx4,
sewardj2fdd4162010-08-22 12:59:02 +00001253 Iop_Add32Fx2, Iop_Sub32Fx2,
1254 /* Note: For the following compares, the ppc and arm front-ends assume a
cerionf294eb32005-11-16 17:21:10 +00001255 nan in a lane of either argument returns zero for that lane. */
sewardj2fdd4162010-08-22 12:59:02 +00001256 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
cerion206c3642005-11-14 00:35:59 +00001257 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
sewardjc9a43662004-11-30 18:51:59 +00001258
sewardj2fdd4162010-08-22 12:59:02 +00001259 /* Vector Absolute */
1260 Iop_Abs32Fx4,
1261
1262 /* Pairwise Max and Min. See integer pairwise operations for details. */
1263 Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1264
sewardjc9a43662004-11-30 18:51:59 +00001265 /* unary */
sewardj2fdd4162010-08-22 12:59:02 +00001266 Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
1267 Iop_Neg32Fx4,
1268
1269 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1270 element in the operand vector, and places the results in the destination
1271 vector. */
1272 Iop_Recip32Fx4,
1273
1274 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1275 Note, that if one of the arguments is zero and another one is infinity
1276 of arbitrary sign the result of the operation is 2.0. */
1277 Iop_Recps32Fx4,
1278
1279 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1280 square root of each element in the operand vector. */
1281 Iop_Rsqrte32Fx4,
1282
1283 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1284 Note, that of one of the arguments is zero and another one is infiinty
1285 of arbitrary sign the result of the operation is 1.5. */
1286 Iop_Rsqrts32Fx4,
1287
cerionf294eb32005-11-16 17:21:10 +00001288 /* --- Int to/from FP conversion --- */
1289 /* Unlike the standard fp conversions, these irops take no
1290 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1291 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
sewardj2fdd4162010-08-22 12:59:02 +00001292 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */
1293 Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */
1294 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (with saturation) */
cerionf294eb32005-11-16 17:21:10 +00001295 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
1296 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
sewardj2fdd4162010-08-22 12:59:02 +00001297 /* Fixed32 format is floating-point number with fixed number of fraction
1298 bits. The number of fraction bits is passed as a second argument of
1299 type I8. */
1300 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1301 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1302
1303 /* --- Single to/from half conversion --- */
sewardj5f438dd2011-06-16 11:36:23 +00001304 /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
sewardj2fdd4162010-08-22 12:59:02 +00001305 Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */
cerionf294eb32005-11-16 17:21:10 +00001306
sewardjc9a43662004-11-30 18:51:59 +00001307 /* --- 32x4 lowest-lane-only scalar FP --- */
1308
1309 /* In binary cases, upper 3/4 is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001310 unary cases, upper 3/4 is copied from the operand. */
sewardjc9a43662004-11-30 18:51:59 +00001311
1312 /* binary */
1313 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1314 Iop_Max32F0x4, Iop_Min32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001315 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
sewardjc9a43662004-11-30 18:51:59 +00001316
1317 /* unary */
1318 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
sewardj636ad762004-12-07 11:16:04 +00001319
1320 /* --- 64x2 vector FP --- */
1321
1322 /* binary */
1323 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
1324 Iop_Max64Fx2, Iop_Min64Fx2,
1325 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1326
1327 /* unary */
1328 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
1329
1330 /* --- 64x2 lowest-lane-only scalar FP --- */
1331
1332 /* In binary cases, upper half is copied from first operand. In
cerionb85e8bb2005-02-16 08:54:33 +00001333 unary cases, upper half is copied from the operand. */
sewardj636ad762004-12-07 11:16:04 +00001334
1335 /* binary */
1336 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1337 Iop_Max64F0x2, Iop_Min64F0x2,
1338 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1339
1340 /* unary */
1341 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
sewardjc9a43662004-11-30 18:51:59 +00001342
1343 /* --- pack / unpack --- */
1344
sewardjf0c1c582005-02-07 23:47:38 +00001345 /* 64 <-> 128 bit vector */
1346 Iop_V128to64, // :: V128 -> I64, low half
1347 Iop_V128HIto64, // :: V128 -> I64, high half
1348 Iop_64HLtoV128, // :: (I64,I64) -> V128
sewardjc9a43662004-11-30 18:51:59 +00001349
sewardjf0c1c582005-02-07 23:47:38 +00001350 Iop_64UtoV128,
1351 Iop_SetV128lo64,
sewardj164f9272004-12-09 00:39:32 +00001352
sewardjf0c1c582005-02-07 23:47:38 +00001353 /* 32 <-> 128 bit vector */
1354 Iop_32UtoV128,
1355 Iop_V128to32, // :: V128 -> I32, lowest lane
1356 Iop_SetV128lo32, // :: (V128,I32) -> V128
sewardj70f676d2004-12-10 14:59:57 +00001357
sewardj164f9272004-12-09 00:39:32 +00001358 /* ------------------ 128-bit SIMD Integer. ------------------ */
1359
1360 /* BITWISE OPS */
sewardjf0c1c582005-02-07 23:47:38 +00001361 Iop_NotV128,
1362 Iop_AndV128, Iop_OrV128, Iop_XorV128,
sewardj164f9272004-12-09 00:39:32 +00001363
cerionf887b3e2005-09-13 16:34:28 +00001364 /* VECTOR SHIFT (shift amt :: Ity_I8) */
1365 Iop_ShlV128, Iop_ShrV128,
1366
sewardj2e383862004-12-12 16:46:47 +00001367 /* MISC (vector integer cmp != 0) */
1368 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
sewardj70f676d2004-12-10 14:59:57 +00001369
sewardj164f9272004-12-09 00:39:32 +00001370 /* ADDITION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001371 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2,
1372 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1373 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001374
1375 /* SUBTRACTION (normal / unsigned sat / signed sat) */
sewardj2fdd4162010-08-22 12:59:02 +00001376 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2,
1377 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1378 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
sewardj164f9272004-12-09 00:39:32 +00001379
1380 /* MULTIPLICATION (normal / high half of signed/unsigned) */
sewardj2fdd4162010-08-22 12:59:02 +00001381 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4,
1382 Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1383 Iop_MulHi16Sx8, Iop_MulHi32Sx4,
cerion24d06f12005-11-09 21:34:20 +00001384 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
cerion1ac656a2005-11-04 19:44:48 +00001385 Iop_MullEven8Ux16, Iop_MullEven16Ux8,
1386 Iop_MullEven8Sx16, Iop_MullEven16Sx8,
sewardj2fdd4162010-08-22 12:59:02 +00001387 /* FIXME: document these */
1388 Iop_Mull8Ux8, Iop_Mull8Sx8,
1389 Iop_Mull16Ux4, Iop_Mull16Sx4,
1390 Iop_Mull32Ux2, Iop_Mull32Sx2,
1391 /* Vector Saturating Doubling Multiply Returning High Half and
1392 Vector Saturating Rounding Doubling Multiply Returning High Half */
1393 /* These IROp's multiply corresponding elements in two vectors, double
1394 the results, and place the most significant half of the final results
1395 in the destination vector. The results are truncated or rounded. If
1396 any of the results overflow, they are saturated. */
1397 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4,
1398 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4,
1399 /* Doubling saturating multiplication (long) (I64, I64) -> V128 */
1400 Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2,
1401 /* Plynomial multiplication treats it's arguments as coefficients of
1402 polynoms over {0, 1}. */
1403 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1404 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */
1405
1406 /* PAIRWISE operations */
1407 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1408 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1409 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1410 Iop_PwAdd32Fx2,
1411 /* Longening variant is unary. The resulting vector contains two times
1412 less elements than operand, but they are two times wider.
1413 Example:
1414 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1415 where a+b and c+d are unsigned 32-bit values. */
1416 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4,
1417 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1418
1419 /* ABSOLUTE VALUE */
1420 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4,
cerion1ac656a2005-11-04 19:44:48 +00001421
sewardj5ce5fd62005-04-19 23:06:11 +00001422 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
cerionf887b3e2005-09-13 16:34:28 +00001423 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
1424 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
sewardj164f9272004-12-09 00:39:32 +00001425
1426 /* MIN/MAX */
cerionf887b3e2005-09-13 16:34:28 +00001427 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
1428 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
1429 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
1430 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001431
1432 /* COMPARISON */
sewardjd8815622011-10-19 15:24:01 +00001433 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2,
sewardj69d98e32010-06-18 08:17:41 +00001434 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
cerionf887b3e2005-09-13 16:34:28 +00001435 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
sewardj164f9272004-12-09 00:39:32 +00001436
sewardj2fdd4162010-08-22 12:59:02 +00001437 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1438 bit) */
1439 Iop_Cnt8x16,
1440 Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4,
1441 Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4,
1442
sewardj164f9272004-12-09 00:39:32 +00001443 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
cerion2a4b8452005-09-15 16:28:36 +00001444 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1445 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001446 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
sewardj164f9272004-12-09 00:39:32 +00001447
cerionf887b3e2005-09-13 16:34:28 +00001448 /* VECTOR x VECTOR SHIFT / ROTATE */
sewardj2fdd4162010-08-22 12:59:02 +00001449 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1450 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1451 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1452 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
sewardj1bee5612005-11-10 18:10:58 +00001453 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
cerionf887b3e2005-09-13 16:34:28 +00001454
sewardj2fdd4162010-08-22 12:59:02 +00001455 /* VECTOR x VECTOR SATURATING SHIFT */
1456 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1457 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1458 /* VECTOR x INTEGER SATURATING SHIFT */
1459 Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2,
1460 Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2,
1461 Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2,
1462
sewardj5f438dd2011-06-16 11:36:23 +00001463 /* NARROWING (binary)
1464 -- narrow 2xV128 into 1xV128, hi half from left arg */
sewardjc9bff7d2011-06-15 15:09:37 +00001465 /* See comments above w.r.t. U vs S issues in saturated narrowing. */
sewardj5f438dd2011-06-16 11:36:23 +00001466 Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1467 Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1468 Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1469 Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
sewardj164f9272004-12-09 00:39:32 +00001470
sewardj5f438dd2011-06-16 11:36:23 +00001471 /* NARROWING (unary) -- narrow V128 into I64 */
1472 Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1473 /* Saturating narrowing from signed source to signed/unsigned destination */
1474 Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1475 Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1476 /* Saturating narrowing from unsigned source to unsigned destination */
1477 Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1478
1479 /* WIDENING -- sign or zero extend each element of the argument
1480 vector to the twice original size. The resulting vector consists of
sewardj2fdd4162010-08-22 12:59:02 +00001481 the same number of elements but each element and the vector itself
sewardj5f438dd2011-06-16 11:36:23 +00001482 are twice as wide.
sewardj2fdd4162010-08-22 12:59:02 +00001483 All operations are I64->V128.
1484 Example
sewardj5f438dd2011-06-16 11:36:23 +00001485 Iop_Widen32Sto64x2( [a, b] ) = [c, d]
sewardj2fdd4162010-08-22 12:59:02 +00001486 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
sewardj5f438dd2011-06-16 11:36:23 +00001487 Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1488 Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001489
1490 /* INTERLEAVING */
1491 /* Interleave lanes from low or high halves of
sewardj164f9272004-12-09 00:39:32 +00001492 operands. Most-significant result lane is from the left
1493 arg. */
1494 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1495 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001496 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
cerionf887b3e2005-09-13 16:34:28 +00001497 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
sewardj2fdd4162010-08-22 12:59:02 +00001498 /* Interleave odd/even lanes of operands. Most-significant result lane
1499 is from the left arg. */
1500 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1501 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1502 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1503
1504 /* CONCATENATION -- build a new value by concatenating either
1505 the even or odd lanes of both operands. */
1506 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1507 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1508
1509 /* GET elements of VECTOR
1510 GET is binop (V128, I8) -> I<elem_size> */
1511 /* Note: the arm back-end handles only constant second argument. */
1512 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
cerionf887b3e2005-09-13 16:34:28 +00001513
1514 /* DUPLICATING -- copy value to all lanes */
sewardj2fdd4162010-08-22 12:59:02 +00001515 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
1516
1517 /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes
1518 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of
1519 result.
1520 It is a triop: (V128, V128, I8) -> V128 */
1521 /* Note: the ARM back end handles only constant arg3 in this operation. */
1522 Iop_ExtractV128,
1523
1524 /* REVERSE the order of elements in each Half-words, Words,
1525 Double-words */
1526 /* Examples:
1527 Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1528 Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */
1529 Iop_Reverse16_8x16,
1530 Iop_Reverse32_8x16, Iop_Reverse32_16x8,
1531 Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4,
cerionf887b3e2005-09-13 16:34:28 +00001532
1533 /* PERMUTING -- copy src bytes to dst,
sewardjdc1f9132005-10-22 12:49:49 +00001534 as indexed by control vector bytes:
1535 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1536 argR[i] values may only be in the range 0 .. 15, else behaviour
1537 is undefined. */
sewardj2fdd4162010-08-22 12:59:02 +00001538 Iop_Perm8x16,
sewardjd8bca7e2012-06-20 11:46:19 +00001539 Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
sewardj2fdd4162010-08-22 12:59:02 +00001540
sewardj78a20592012-12-13 18:29:56 +00001541 /* MISC CONVERSION -- get high bits of each byte lane, a la
1542 x86/amd64 pmovmskb */
sewardj0e7d2802013-01-26 11:39:13 +00001543 Iop_GetMSBs8x16, /* V128 -> I16 */
sewardj78a20592012-12-13 18:29:56 +00001544
sewardj2fdd4162010-08-22 12:59:02 +00001545 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1546 See floating-point equiwalents for details. */
sewardjc4530ae2012-05-21 10:18:49 +00001547 Iop_Recip32x4, Iop_Rsqrte32x4,
1548
1549 /* ------------------ 256-bit SIMD Integer. ------------------ */
1550
1551 /* Pack/unpack */
sewardj4b1cc832012-06-13 11:10:20 +00001552 Iop_V256to64_0, // V256 -> I64, extract least significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001553 Iop_V256to64_1,
1554 Iop_V256to64_2,
sewardj4b1cc832012-06-13 11:10:20 +00001555 Iop_V256to64_3, // V256 -> I64, extract most significant lane
sewardjc4530ae2012-05-21 10:18:49 +00001556
sewardj56c30312012-06-12 08:45:39 +00001557 Iop_64x4toV256, // (I64,I64,I64,I64)->V256
sewardjc4530ae2012-05-21 10:18:49 +00001558 // first arg is most significant lane
sewardj56c30312012-06-12 08:45:39 +00001559
sewardj4b1cc832012-06-13 11:10:20 +00001560 Iop_V256toV128_0, // V256 -> V128, less significant lane
1561 Iop_V256toV128_1, // V256 -> V128, more significant lane
1562 Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1563
1564 Iop_AndV256,
sewardj2a2bda92012-06-14 23:32:02 +00001565 Iop_OrV256,
sewardj4b1cc832012-06-13 11:10:20 +00001566 Iop_XorV256,
sewardj2a2bda92012-06-14 23:32:02 +00001567 Iop_NotV256,
sewardj4b1cc832012-06-13 11:10:20 +00001568
sewardj23db8a02012-06-25 07:46:18 +00001569 /* MISC (vector integer cmp != 0) */
sewardjcc3d2192013-03-27 11:37:33 +00001570 Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
1571
1572 Iop_Add8x32, Iop_Add16x16, Iop_Add32x8, Iop_Add64x4,
1573 Iop_Sub8x32, Iop_Sub16x16, Iop_Sub32x8, Iop_Sub64x4,
1574
1575 Iop_CmpEQ8x32, Iop_CmpEQ16x16, Iop_CmpEQ32x8, Iop_CmpEQ64x4,
1576 Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4,
1577
1578 Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4,
1579 Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4,
1580 Iop_SarN16x16, Iop_SarN32x8,
1581
1582 Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8,
1583 Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8,
1584 Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8,
1585 Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8,
1586
1587 Iop_Mul16x16, Iop_Mul32x8,
1588 Iop_MulHi16Ux16, Iop_MulHi16Sx16,
1589
1590 Iop_QAdd8Ux32, Iop_QAdd16Ux16,
1591 Iop_QAdd8Sx32, Iop_QAdd16Sx16,
1592 Iop_QSub8Ux32, Iop_QSub16Ux16,
1593 Iop_QSub8Sx32, Iop_QSub16Sx16,
1594
1595 Iop_Avg8Ux32, Iop_Avg16Ux16,
1596
1597 Iop_Perm32x8,
sewardj23db8a02012-06-25 07:46:18 +00001598
sewardj56c30312012-06-12 08:45:39 +00001599 /* ------------------ 256-bit SIMD FP. ------------------ */
1600 Iop_Add64Fx4,
1601 Iop_Sub64Fx4,
1602 Iop_Mul64Fx4,
1603 Iop_Div64Fx4,
1604 Iop_Add32Fx8,
1605 Iop_Sub32Fx8,
1606 Iop_Mul32Fx8,
sewardjf0ad4f82012-06-19 06:57:59 +00001607 Iop_Div32Fx8,
1608
1609 Iop_Sqrt32Fx8,
1610 Iop_Sqrt64Fx4,
sewardj8eb7ae82012-06-24 14:00:27 +00001611 Iop_RSqrt32Fx8,
sewardj82096922012-06-24 14:57:59 +00001612 Iop_Recip32Fx8,
sewardj8eb7ae82012-06-24 14:00:27 +00001613
1614 Iop_Max32Fx8, Iop_Min32Fx8,
florian2245ce92012-08-28 16:49:30 +00001615 Iop_Max64Fx4, Iop_Min64Fx4,
1616 Iop_LAST /* must be the last enumerator */
sewardjac6b7122004-06-27 01:03:57 +00001617 }
1618 IROp;
sewardjec6ad592004-06-20 12:26:53 +00001619
sewardj57c10c82006-11-15 02:57:05 +00001620/* Pretty-print an op. */
sewardj35421a32004-07-05 13:12:34 +00001621extern void ppIROp ( IROp );
sewardjec6ad592004-06-20 12:26:53 +00001622
sewardje3d0d2e2004-06-27 10:42:44 +00001623
florian79e5a482013-06-06 19:12:46 +00001624/* Encoding of IEEE754-specified rounding modes.
sewardjf1b5b1a2006-02-03 22:54:17 +00001625 Note, various front and back ends rely on the actual numerical
1626 values of these, so do not change them. */
sewardjc9868d72004-09-12 19:19:17 +00001627typedef
sewardjf1b5b1a2006-02-03 22:54:17 +00001628 enum {
florian79e5a482013-06-06 19:12:46 +00001629 Irrm_NEAREST = 0, // Round to nearest, ties to even
1630 Irrm_NegINF = 1, // Round to negative infinity
1631 Irrm_PosINF = 2, // Round to positive infinity
1632 Irrm_ZERO = 3, // Round toward zero
1633 Irrm_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0
1634 Irrm_PREPARE_SHORTER = 5, // Round to prepare for storter
1635 // precision
1636 Irrm_AWAY_FROM_ZERO = 6, // Round to away from 0
1637 Irrm_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0
sewardjf1b5b1a2006-02-03 22:54:17 +00001638 }
sewardjc9868d72004-09-12 19:19:17 +00001639 IRRoundingMode;
1640
floriandaa40842012-12-21 20:24:24 +00001641/* Binary floating point comparison result values.
sewardjc9868d72004-09-12 19:19:17 +00001642 This is also derived from what IA32 does. */
1643typedef
1644 enum {
1645 Ircr_UN = 0x45,
1646 Ircr_LT = 0x01,
1647 Ircr_GT = 0x00,
1648 Ircr_EQ = 0x40
1649 }
floriandaa40842012-12-21 20:24:24 +00001650 IRCmpFResult;
sewardjc9868d72004-09-12 19:19:17 +00001651
floriandaa40842012-12-21 20:24:24 +00001652typedef IRCmpFResult IRCmpF32Result;
1653typedef IRCmpFResult IRCmpF64Result;
1654typedef IRCmpFResult IRCmpF128Result;
1655
1656/* Decimal floating point result values. */
1657typedef IRCmpFResult IRCmpDResult;
1658typedef IRCmpDResult IRCmpD64Result;
1659typedef IRCmpDResult IRCmpD128Result;
sewardjc9868d72004-09-12 19:19:17 +00001660
sewardjc97096c2004-06-30 09:28:04 +00001661/* ------------------ Expressions ------------------ */
sewardjd1725d12004-08-12 20:46:53 +00001662
florianeadea2e2012-06-06 12:53:14 +00001663typedef struct _IRQop IRQop; /* forward declaration */
1664typedef struct _IRTriop IRTriop; /* forward declaration */
florian96d7cc32012-06-01 20:41:24 +00001665
1666
sewardj57c10c82006-11-15 02:57:05 +00001667/* The different kinds of expressions. Their meaning is explained below
1668 in the comments for IRExpr. */
sewardje3d0d2e2004-06-27 10:42:44 +00001669typedef
sewardjb3bce0e2004-09-14 23:20:10 +00001670 enum {
sewardjcfe046e2013-01-17 14:23:53 +00001671 Iex_Binder=0x1900,
sewardj57c10c82006-11-15 02:57:05 +00001672 Iex_Get,
1673 Iex_GetI,
sewardjdd40fdf2006-12-24 02:20:24 +00001674 Iex_RdTmp,
sewardj57c10c82006-11-15 02:57:05 +00001675 Iex_Qop,
1676 Iex_Triop,
1677 Iex_Binop,
1678 Iex_Unop,
1679 Iex_Load,
1680 Iex_Const,
florian99dd03e2013-01-29 03:56:06 +00001681 Iex_ITE,
sewardj57c10c82006-11-15 02:57:05 +00001682 Iex_CCall
sewardjb3bce0e2004-09-14 23:20:10 +00001683 }
sewardje3d0d2e2004-06-27 10:42:44 +00001684 IRExprTag;
1685
sewardj57c10c82006-11-15 02:57:05 +00001686/* An expression. Stored as a tagged union. 'tag' indicates what kind
1687 of expression this is. 'Iex' is the union that holds the fields. If
1688 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
1689 expression, and the fields can be accessed with
1690 'e.Iex.Load.<fieldname>'.
1691
1692 For each kind of expression, we show what it looks like when
1693 pretty-printed with ppIRExpr().
1694*/
1695typedef
1696 struct _IRExpr
sewardje3d0d2e2004-06-27 10:42:44 +00001697 IRExpr;
1698
sewardj57c10c82006-11-15 02:57:05 +00001699struct _IRExpr {
1700 IRExprTag tag;
1701 union {
1702 /* Used only in pattern matching within Vex. Should not be seen
1703 outside of Vex. */
1704 struct {
1705 Int binder;
1706 } Binder;
1707
1708 /* Read a guest register, at a fixed offset in the guest state.
1709 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
1710 */
1711 struct {
1712 Int offset; /* Offset into the guest state */
1713 IRType ty; /* Type of the value being read */
1714 } Get;
1715
1716 /* Read a guest register at a non-fixed offset in the guest
1717 state. This allows circular indexing into parts of the guest
1718 state, which is essential for modelling situations where the
1719 identity of guest registers is not known until run time. One
1720 example is the x87 FP register stack.
1721
1722 The part of the guest state to be treated as a circular array
sewardjdd40fdf2006-12-24 02:20:24 +00001723 is described in the IRRegArray 'descr' field. It holds the
sewardj57c10c82006-11-15 02:57:05 +00001724 offset of the first element in the array, the type of each
1725 element, and the number of elements.
1726
1727 The array index is indicated rather indirectly, in a way
1728 which makes optimisation easy: as the sum of variable part
1729 (the 'ix' field) and a constant offset (the 'bias' field).
1730
1731 Since the indexing is circular, the actual array index to use
1732 is computed as (ix + bias) % num-of-elems-in-the-array.
1733
1734 Here's an example. The description
1735
1736 (96:8xF64)[t39,-7]
1737
1738 describes an array of 8 F64-typed values, the
1739 guest-state-offset of the first being 96. This array is
1740 being indexed at (t39 - 7) % 8.
1741
1742 It is important to get the array size/type exactly correct
1743 since IR optimisation looks closely at such info in order to
1744 establish aliasing/non-aliasing between seperate GetI and
1745 PutI events, which is used to establish when they can be
1746 reordered, etc. Putting incorrect info in will lead to
1747 obscure IR optimisation bugs.
1748
1749 ppIRExpr output: GETI<descr>[<ix>,<bias]
1750 eg. GETI(128:8xI8)[t1,0]
1751 */
1752 struct {
sewardjdd40fdf2006-12-24 02:20:24 +00001753 IRRegArray* descr; /* Part of guest state treated as circular */
1754 IRExpr* ix; /* Variable part of index into array */
1755 Int bias; /* Constant offset part of index into array */
sewardj57c10c82006-11-15 02:57:05 +00001756 } GetI;
1757
1758 /* The value held by a temporary.
1759 ppIRExpr output: t<tmp>, eg. t1
1760 */
1761 struct {
1762 IRTemp tmp; /* The temporary number */
sewardjdd40fdf2006-12-24 02:20:24 +00001763 } RdTmp;
sewardj57c10c82006-11-15 02:57:05 +00001764
1765 /* A quaternary operation.
1766 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1767 eg. MAddF64r32(t1, t2, t3, t4)
1768 */
1769 struct {
florian96d7cc32012-06-01 20:41:24 +00001770 IRQop* details;
sewardj57c10c82006-11-15 02:57:05 +00001771 } Qop;
1772
1773 /* A ternary operation.
1774 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1775 eg. MulF64(1, 2.0, 3.0)
1776 */
1777 struct {
florian420bfa92012-06-02 20:29:22 +00001778 IRTriop* details;
sewardj57c10c82006-11-15 02:57:05 +00001779 } Triop;
1780
1781 /* A binary operation.
1782 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1783 */
1784 struct {
1785 IROp op; /* op-code */
1786 IRExpr* arg1; /* operand 1 */
1787 IRExpr* arg2; /* operand 2 */
1788 } Binop;
1789
1790 /* A unary operation.
1791 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1792 */
1793 struct {
1794 IROp op; /* op-code */
1795 IRExpr* arg; /* operand */
1796 } Unop;
1797
sewardje768e922009-11-26 17:17:37 +00001798 /* A load from memory -- a normal load, not a load-linked.
1799 Load-Linkeds (and Store-Conditionals) are instead represented
1800 by IRStmt.LLSC since Load-Linkeds have side effects and so
1801 are not semantically valid IRExpr's.
sewardj57c10c82006-11-15 02:57:05 +00001802 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1803 */
1804 struct {
1805 IREndness end; /* Endian-ness of the load */
1806 IRType ty; /* Type of the loaded value */
1807 IRExpr* addr; /* Address being loaded from */
1808 } Load;
1809
1810 /* A constant-valued expression.
1811 ppIRExpr output: <con>, eg. 0x4:I32
1812 */
1813 struct {
1814 IRConst* con; /* The constant itself */
1815 } Const;
1816
1817 /* A call to a pure (no side-effects) helper C function.
1818
1819 With the 'cee' field, 'name' is the function's name. It is
1820 only used for pretty-printing purposes. The address to call
1821 (host address, of course) is stored in the 'addr' field
1822 inside 'cee'.
1823
1824 The 'args' field is a NULL-terminated array of arguments.
1825 The stated return IRType, and the implied argument types,
1826 must match that of the function being called well enough so
1827 that the back end can actually generate correct code for the
1828 call.
1829
1830 The called function **must** satisfy the following:
1831
1832 * no side effects -- must be a pure function, the result of
1833 which depends only on the passed parameters.
1834
1835 * it may not look at, nor modify, any of the guest state
1836 since that would hide guest state transitions from
1837 instrumenters
1838
1839 * it may not access guest memory, since that would hide
1840 guest memory transactions from the instrumenters
1841
florian52af7bc2012-05-12 03:44:49 +00001842 * it must not assume that arguments are being evaluated in a
1843 particular order. The oder of evaluation is unspecified.
1844
sewardj57c10c82006-11-15 02:57:05 +00001845 This is restrictive, but makes the semantics clean, and does
1846 not interfere with IR optimisation.
1847
1848 If you want to call a helper which can mess with guest state
1849 and/or memory, instead use Ist_Dirty. This is a lot more
1850 flexible, but you have to give a bunch of details about what
1851 the helper does (and you better be telling the truth,
1852 otherwise any derived instrumentation will be wrong). Also
1853 Ist_Dirty inhibits various IR optimisations and so can cause
1854 quite poor code to be generated. Try to avoid it.
1855
1856 ppIRExpr output: <cee>(<args>):<retty>
1857 eg. foo{0x80489304}(t1, t2):I32
1858 */
1859 struct {
1860 IRCallee* cee; /* Function to call. */
1861 IRType retty; /* Type of return value. */
1862 IRExpr** args; /* Vector of argument expressions. */
1863 } CCall;
1864
florian99dd03e2013-01-29 03:56:06 +00001865 /* A ternary if-then-else operator. It returns iftrue if cond is
1866 nonzero, iffalse otherwise. Note that it is STRICT, ie. both
1867 iftrue and iffalse are evaluated in all cases.
sewardj57c10c82006-11-15 02:57:05 +00001868
florian99dd03e2013-01-29 03:56:06 +00001869 ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>),
1870 eg. ITE(t6,t7,t8)
sewardj57c10c82006-11-15 02:57:05 +00001871 */
1872 struct {
1873 IRExpr* cond; /* Condition */
florian99dd03e2013-01-29 03:56:06 +00001874 IRExpr* iftrue; /* True expression */
1875 IRExpr* iffalse; /* False expression */
1876 } ITE;
sewardj57c10c82006-11-15 02:57:05 +00001877 } Iex;
1878};
1879
sewardjcfe046e2013-01-17 14:23:53 +00001880/* Expression auxiliaries: a ternary expression. */
florian420bfa92012-06-02 20:29:22 +00001881struct _IRTriop {
1882 IROp op; /* op-code */
1883 IRExpr* arg1; /* operand 1 */
1884 IRExpr* arg2; /* operand 2 */
1885 IRExpr* arg3; /* operand 3 */
1886};
1887
sewardjcfe046e2013-01-17 14:23:53 +00001888/* Expression auxiliaries: a quarternary expression. */
florian96d7cc32012-06-01 20:41:24 +00001889struct _IRQop {
1890 IROp op; /* op-code */
1891 IRExpr* arg1; /* operand 1 */
1892 IRExpr* arg2; /* operand 2 */
1893 IRExpr* arg3; /* operand 3 */
1894 IRExpr* arg4; /* operand 4 */
1895};
1896
sewardj57c10c82006-11-15 02:57:05 +00001897/* Expression constructors. */
sewardj443cd9d2004-07-18 23:06:45 +00001898extern IRExpr* IRExpr_Binder ( Int binder );
1899extern IRExpr* IRExpr_Get ( Int off, IRType ty );
sewardjdd40fdf2006-12-24 02:20:24 +00001900extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
1901extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
sewardj40c80262006-02-08 19:30:46 +00001902extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1903 IRExpr* arg3, IRExpr* arg4 );
sewardjb183b852006-02-03 16:08:03 +00001904extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1905 IRExpr* arg2, IRExpr* arg3 );
sewardj443cd9d2004-07-18 23:06:45 +00001906extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1907extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
sewardje768e922009-11-26 17:17:37 +00001908extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
sewardj443cd9d2004-07-18 23:06:45 +00001909extern IRExpr* IRExpr_Const ( IRConst* con );
sewardj8ea867b2004-10-30 19:03:02 +00001910extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
florian99dd03e2013-01-29 03:56:06 +00001911extern IRExpr* IRExpr_ITE ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse );
sewardje3d0d2e2004-06-27 10:42:44 +00001912
sewardj57c10c82006-11-15 02:57:05 +00001913/* Deep-copy an IRExpr. */
sewardjdd40fdf2006-12-24 02:20:24 +00001914extern IRExpr* deepCopyIRExpr ( IRExpr* );
sewardj695cff92004-10-13 14:50:14 +00001915
sewardj57c10c82006-11-15 02:57:05 +00001916/* Pretty-print an IRExpr. */
sewardj35421a32004-07-05 13:12:34 +00001917extern void ppIRExpr ( IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00001918
sewardj57c10c82006-11-15 02:57:05 +00001919/* NULL-terminated IRExpr vector constructors, suitable for
1920 use as arg lists in clean/dirty helper calls. */
sewardjc5fc7aa2004-10-27 23:00:55 +00001921extern IRExpr** mkIRExprVec_0 ( void );
sewardjf9655262004-10-31 20:02:16 +00001922extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1923extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1924extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1925extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
sewardj78ec32b2007-01-08 05:09:55 +00001926extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1927 IRExpr* );
1928extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1929 IRExpr*, IRExpr* );
1930extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
sewardjf32c67d2004-11-08 13:10:44 +00001931 IRExpr*, IRExpr*, IRExpr* );
sewardj2fdd4162010-08-22 12:59:02 +00001932extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1933 IRExpr*, IRExpr*, IRExpr*, IRExpr*);
sewardjc5fc7aa2004-10-27 23:00:55 +00001934
sewardj57c10c82006-11-15 02:57:05 +00001935/* IRExpr copiers:
sewardjdd40fdf2006-12-24 02:20:24 +00001936 - shallowCopy: shallow-copy (ie. create a new vector that shares the
sewardj57c10c82006-11-15 02:57:05 +00001937 elements with the original).
sewardjdd40fdf2006-12-24 02:20:24 +00001938 - deepCopy: deep-copy (ie. create a completely new vector). */
1939extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1940extern IRExpr** deepCopyIRExprVec ( IRExpr** );
sewardjc5fc7aa2004-10-27 23:00:55 +00001941
sewardjf9655262004-10-31 20:02:16 +00001942/* Make a constant expression from the given host word taking into
sewardj57c10c82006-11-15 02:57:05 +00001943 account (of course) the host word size. */
sewardj49651f42004-10-28 22:11:04 +00001944extern IRExpr* mkIRExpr_HWord ( HWord );
1945
sewardjf9655262004-10-31 20:02:16 +00001946/* Convenience function for constructing clean helper calls. */
1947extern
1948IRExpr* mkIRExprCCall ( IRType retty,
florian1ff47562012-10-21 02:09:51 +00001949 Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00001950 IRExpr** args );
1951
sewardj49651f42004-10-28 22:11:04 +00001952
sewardj57c10c82006-11-15 02:57:05 +00001953/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1954 * Iex_Const). */
sewardj496a58d2005-03-20 18:44:44 +00001955static inline Bool isIRAtom ( IRExpr* e ) {
sewardjdd40fdf2006-12-24 02:20:24 +00001956 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
sewardj49651f42004-10-28 22:11:04 +00001957}
1958
sewardj496a58d2005-03-20 18:44:44 +00001959/* Are these two IR atoms identical? Causes an assertion
1960 failure if they are passed non-atoms. */
1961extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1962
sewardje87b4842004-07-10 12:23:30 +00001963
sewardj893aada2004-11-29 19:57:54 +00001964/* ------------------ Jump kinds ------------------ */
1965
1966/* This describes hints which can be passed to the dispatcher at guest
1967 control-flow transfer points.
sewardj7ce9d152005-03-15 16:54:13 +00001968
sewardj57c10c82006-11-15 02:57:05 +00001969 Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1970 guest_TISTART and guest_TILEN, which specify the start and length
1971 of the region to be invalidated. These are both the size of a
1972 guest word. It is the responsibility of the relevant toIR.c to
1973 ensure that these are filled in with suitable values before issuing
1974 a jump of kind Ijk_TInval.
sewardj9dd9cf12006-01-20 14:13:55 +00001975
1976 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
florian6ef84be2012-08-26 03:20:07 +00001977 pseudo-register guest_EMNOTE, which is 32-bits regardless of the
1978 host or guest word size. That register should be made to hold a
1979 VexEmNote value to indicate the reason for the exit.
sewardj9dd9cf12006-01-20 14:13:55 +00001980
1981 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1982 cannot continue) and so the jump destination can be anything.
sewardje86310f2009-03-19 22:21:40 +00001983
1984 Re Ijk_Sys_ (syscall jumps): the guest state must have a
1985 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1986 word. Front ends should set this to be the IP at the most recently
1987 executed kernel-entering (system call) instruction. This makes it
1988 very much easier (viz, actually possible at all) to back up the
1989 guest to restart a syscall that has been interrupted by a signal.
sewardj893aada2004-11-29 19:57:54 +00001990*/
1991typedef
sewardjc6f970f2012-04-02 21:54:49 +00001992 enum {
sewardjcfe046e2013-01-17 14:23:53 +00001993 Ijk_INVALID=0x1A00,
sewardjc6f970f2012-04-02 21:54:49 +00001994 Ijk_Boring, /* not interesting; just goto next */
sewardj893aada2004-11-29 19:57:54 +00001995 Ijk_Call, /* guest is doing a call */
1996 Ijk_Ret, /* guest is doing a return */
1997 Ijk_ClientReq, /* do guest client req before continuing */
sewardj893aada2004-11-29 19:57:54 +00001998 Ijk_Yield, /* client is yielding to thread scheduler */
sewardj52444cb2004-12-13 14:09:01 +00001999 Ijk_EmWarn, /* report emulation warning before continuing */
sewardj9dd9cf12006-01-20 14:13:55 +00002000 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
florian0b390082012-08-25 02:01:25 +00002001 Ijk_NoDecode, /* current instruction cannot be decoded */
sewardj7ce9d152005-03-15 16:54:13 +00002002 Ijk_MapFail, /* Vex-provided address translation failed */
sewardjf07ed032005-08-07 14:48:03 +00002003 Ijk_TInval, /* Invalidate translations before continuing. */
sewardjce02aa72006-01-12 12:27:58 +00002004 Ijk_NoRedir, /* Jump to un-redirected guest addr */
sewardj0f500042007-08-29 09:09:17 +00002005 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
2006 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
sewardje9d8a262009-07-01 08:06:34 +00002007 Ijk_SigBUS, /* current instruction synths SIGBUS */
petarja6a19862012-10-19 14:55:58 +00002008 Ijk_SigFPE_IntDiv, /* current instruction synths SIGFPE - IntDiv */
2009 Ijk_SigFPE_IntOvf, /* current instruction synths SIGFPE - IntOvf */
sewardj4fa325a2005-11-03 13:27:24 +00002010 /* Unfortunately, various guest-dependent syscall kinds. They
2011 all mean: do a syscall before continuing. */
sewardj6c299f32009-12-31 18:00:12 +00002012 Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
sewardj4fa325a2005-11-03 13:27:24 +00002013 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
2014 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
sewardjd660d412008-12-03 21:29:59 +00002015 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
2016 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
sewardj4fa325a2005-11-03 13:27:24 +00002017 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes
2018 invalid at the point this happens. */
sewardj893aada2004-11-29 19:57:54 +00002019 }
2020 IRJumpKind;
2021
2022extern void ppIRJumpKind ( IRJumpKind );
2023
2024
sewardjb3bce0e2004-09-14 23:20:10 +00002025/* ------------------ Dirty helper calls ------------------ */
sewardje87b4842004-07-10 12:23:30 +00002026
sewardj57c10c82006-11-15 02:57:05 +00002027/* A dirty call is a flexible mechanism for calling (possibly
2028 conditionally) a helper function or procedure. The helper function
2029 may read, write or modify client memory, and may read, write or
2030 modify client state. It can take arguments and optionally return a
2031 value. It may return different results and/or do different things
2032 when called repeatedly with the same arguments, by means of storing
2033 private state.
sewardje87b4842004-07-10 12:23:30 +00002034
sewardjc5fc7aa2004-10-27 23:00:55 +00002035 If a value is returned, it is assigned to the nominated return
2036 temporary.
sewardjb3bce0e2004-09-14 23:20:10 +00002037
2038 Dirty calls are statements rather than expressions for obvious
sewardj57c10c82006-11-15 02:57:05 +00002039 reasons. If a dirty call is marked as writing guest state, any
sewardjcfe046e2013-01-17 14:23:53 +00002040 pre-existing values derived from the written parts of the guest
2041 state are invalid. Similarly, if the dirty call is stated as
2042 writing memory, any pre-existing loaded values are invalidated by
2043 it.
sewardjb3bce0e2004-09-14 23:20:10 +00002044
2045 In order that instrumentation is possible, the call must state, and
sewardj57c10c82006-11-15 02:57:05 +00002046 state correctly:
sewardjb3bce0e2004-09-14 23:20:10 +00002047
sewardjcfe046e2013-01-17 14:23:53 +00002048 * Whether it reads, writes or modifies memory, and if so where.
sewardjb3bce0e2004-09-14 23:20:10 +00002049
sewardjcfe046e2013-01-17 14:23:53 +00002050 * Whether it reads, writes or modifies guest state, and if so which
2051 pieces. Several pieces may be stated, and their extents must be
2052 known at translation-time. Each piece is allowed to repeat some
2053 number of times at a fixed interval, if required.
sewardjc5fc7aa2004-10-27 23:00:55 +00002054
2055 Normally, code is generated to pass just the args to the helper.
2056 However, if .needsBBP is set, then an extra first argument is
2057 passed, which is the baseblock pointer, so that the callee can
2058 access the guest state. It is invalid for .nFxState to be zero
2059 but .needsBBP to be True, since .nFxState==0 is a claim that the
2060 call does not access guest state.
sewardjb8385d82004-11-02 01:34:15 +00002061
2062 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
sewardjcfe046e2013-01-17 14:23:53 +00002063 arguments and 'mFx' are evaluated REGARDLESS of the guard value.
2064 The order of argument evaluation is unspecified. The guard
2065 expression is evaluated AFTER the arguments and 'mFx' have been
2066 evaluated. 'mFx' is expected (by Memcheck) to be a defined value
2067 even if the guard evaluates to false.
sewardje87b4842004-07-10 12:23:30 +00002068*/
sewardjc97096c2004-06-30 09:28:04 +00002069
sewardja0e83b02005-01-06 12:36:38 +00002070#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
sewardjb3bce0e2004-09-14 23:20:10 +00002071
sewardj57c10c82006-11-15 02:57:05 +00002072/* Effects on resources (eg. registers, memory locations) */
sewardjb3bce0e2004-09-14 23:20:10 +00002073typedef
2074 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002075 Ifx_None=0x1B00, /* no effect */
sewardj17442fe2004-09-20 14:54:28 +00002076 Ifx_Read, /* reads the resource */
2077 Ifx_Write, /* writes the resource */
2078 Ifx_Modify, /* modifies the resource */
sewardjb3bce0e2004-09-14 23:20:10 +00002079 }
2080 IREffect;
2081
sewardj57c10c82006-11-15 02:57:05 +00002082/* Pretty-print an IREffect */
sewardjb3bce0e2004-09-14 23:20:10 +00002083extern void ppIREffect ( IREffect );
2084
sewardjb3bce0e2004-09-14 23:20:10 +00002085typedef
sewardjc9069f22012-06-01 16:09:50 +00002086 struct _IRDirty {
sewardjf5dfa3b2012-07-10 16:41:46 +00002087 /* What to call, and details of args/results. .guard must be
sewardjcfe046e2013-01-17 14:23:53 +00002088 non-NULL. If .tmp is not IRTemp_INVALID, then the call
2089 returns a result which is placed in .tmp. If at runtime the
2090 guard evaluates to false, .tmp has an 0x555..555 bit pattern
2091 written to it. Hence conditional calls that assign .tmp are
sewardjf5dfa3b2012-07-10 16:41:46 +00002092 allowed. */
sewardj8ea867b2004-10-30 19:03:02 +00002093 IRCallee* cee; /* where to call */
sewardjb8385d82004-11-02 01:34:15 +00002094 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
sewardj8ea867b2004-10-30 19:03:02 +00002095 IRExpr** args; /* arg list, ends in NULL */
sewardj92d168d2004-11-15 14:22:12 +00002096 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
sewardjb3bce0e2004-09-14 23:20:10 +00002097
2098 /* Mem effects; we allow only one R/W/M region to be stated */
sewardj8ea867b2004-10-30 19:03:02 +00002099 IREffect mFx; /* indicates memory effects, if any */
2100 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
2101 Int mSize; /* of access, or zero if mFx==Ifx_None */
sewardjb3bce0e2004-09-14 23:20:10 +00002102
2103 /* Guest state effects; up to N allowed */
sewardjc5fc7aa2004-10-27 23:00:55 +00002104 Bool needsBBP; /* True => also pass guest state ptr to callee */
2105 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
sewardjb3bce0e2004-09-14 23:20:10 +00002106 struct {
sewardjc9069f22012-06-01 16:09:50 +00002107 IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
2108 UShort offset;
2109 UShort size;
2110 UChar nRepeats;
2111 UChar repeatLen;
sewardjb3bce0e2004-09-14 23:20:10 +00002112 } fxState[VEX_N_FXSTATE];
sewardjc9069f22012-06-01 16:09:50 +00002113 /* The access can be repeated, as specified by nRepeats and
2114 repeatLen. To describe only a single access, nRepeats and
2115 repeatLen should be zero. Otherwise, repeatLen must be a
2116 multiple of size and greater than size. */
2117 /* Overall, the parts of the guest state denoted by (offset,
2118 size, nRepeats, repeatLen) is
2119 [offset, +size)
2120 and, if nRepeats > 0,
2121 for (i = 1; i <= nRepeats; i++)
2122 [offset + i * repeatLen, +size)
2123 A convenient way to enumerate all segments is therefore
2124 for (i = 0; i < 1 + nRepeats; i++)
2125 [offset + i * repeatLen, +size)
2126 */
sewardjb3bce0e2004-09-14 23:20:10 +00002127 }
2128 IRDirty;
2129
sewardj57c10c82006-11-15 02:57:05 +00002130/* Pretty-print a dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00002131extern void ppIRDirty ( IRDirty* );
sewardj57c10c82006-11-15 02:57:05 +00002132
2133/* Allocate an uninitialised dirty call */
sewardjb3bce0e2004-09-14 23:20:10 +00002134extern IRDirty* emptyIRDirty ( void );
2135
sewardj57c10c82006-11-15 02:57:05 +00002136/* Deep-copy a dirty call */
sewardjdd40fdf2006-12-24 02:20:24 +00002137extern IRDirty* deepCopyIRDirty ( IRDirty* );
sewardj695cff92004-10-13 14:50:14 +00002138
sewardjc5fc7aa2004-10-27 23:00:55 +00002139/* A handy function which takes some of the tedium out of constructing
2140 dirty helper calls. The called function impliedly does not return
sewardjb8385d82004-11-02 01:34:15 +00002141 any value and has a constant-True guard. The call is marked as
2142 accessing neither guest state nor memory (hence the "unsafe"
sewardj57c10c82006-11-15 02:57:05 +00002143 designation) -- you can change this marking later if need be. A
sewardjb8385d82004-11-02 01:34:15 +00002144 suitable IRCallee is constructed from the supplied bits. */
sewardjf9655262004-10-31 20:02:16 +00002145extern
florian1ff47562012-10-21 02:09:51 +00002146IRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002147 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002148
2149/* Similarly, make a zero-annotation dirty call which returns a value,
2150 and assign that to the given temp. */
sewardjf9655262004-10-31 20:02:16 +00002151extern
2152IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
florian1ff47562012-10-21 02:09:51 +00002153 Int regparms, const HChar* name, void* addr,
sewardjf9655262004-10-31 20:02:16 +00002154 IRExpr** args );
sewardjc5fc7aa2004-10-27 23:00:55 +00002155
sewardjb3bce0e2004-09-14 23:20:10 +00002156
sewardjc4356f02007-11-09 21:15:04 +00002157/* --------------- Memory Bus Events --------------- */
2158
2159typedef
2160 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002161 Imbe_Fence=0x1C00,
sewardj6d615ba2011-09-26 16:19:43 +00002162 /* Needed only on ARM. It cancels a reservation made by a
2163 preceding Linked-Load, and needs to be handed through to the
2164 back end, just as LL and SC themselves are. */
2165 Imbe_CancelReservation
sewardjc4356f02007-11-09 21:15:04 +00002166 }
2167 IRMBusEvent;
2168
2169extern void ppIRMBusEvent ( IRMBusEvent );
2170
2171
sewardje9d8a262009-07-01 08:06:34 +00002172/* --------------- Compare and Swap --------------- */
2173
2174/* This denotes an atomic compare and swap operation, either
2175 a single-element one or a double-element one.
2176
2177 In the single-element case:
2178
2179 .addr is the memory address.
2180 .end is the endianness with which memory is accessed
2181
2182 If .addr contains the same value as .expdLo, then .dataLo is
2183 written there, else there is no write. In both cases, the
2184 original value at .addr is copied into .oldLo.
2185
2186 Types: .expdLo, .dataLo and .oldLo must all have the same type.
2187 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2188 guests, I64.
2189
2190 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2191 be NULL.
2192
2193 In the double-element case:
2194
2195 .addr is the memory address.
2196 .end is the endianness with which memory is accessed
2197
2198 The operation is the same:
2199
2200 If .addr contains the same value as .expdHi:.expdLo, then
2201 .dataHi:.dataLo is written there, else there is no write. In
2202 both cases the original value at .addr is copied into
2203 .oldHi:.oldLo.
2204
2205 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2206 all have the same type, which may be any integral type, viz: I8,
2207 I16, I32 or, for 64-bit guests, I64.
2208
2209 The double-element case is complicated by the issue of
2210 endianness. In all cases, the two elements are understood to be
2211 located adjacently in memory, starting at the address .addr.
2212
2213 If .end is Iend_LE, then the .xxxLo component is at the lower
2214 address and the .xxxHi component is at the higher address, and
2215 each component is itself stored little-endianly.
2216
2217 If .end is Iend_BE, then the .xxxHi component is at the lower
2218 address and the .xxxLo component is at the higher address, and
2219 each component is itself stored big-endianly.
2220
2221 This allows representing more cases than most architectures can
2222 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
2223
2224 How to know if the CAS succeeded?
2225
2226 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2227 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2228 stored at .addr, and the original value there was .oldLo (resp
2229 .oldHi:.oldLo).
2230
2231 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2232 then the CAS failed, and the original value at .addr was .oldLo
2233 (resp. .oldHi:.oldLo).
2234
2235 Hence it is easy to know whether or not the CAS succeeded.
2236*/
2237typedef
2238 struct {
2239 IRTemp oldHi; /* old value of *addr is written here */
2240 IRTemp oldLo;
2241 IREndness end; /* endianness of the data in memory */
2242 IRExpr* addr; /* store address */
2243 IRExpr* expdHi; /* expected old value at *addr */
2244 IRExpr* expdLo;
2245 IRExpr* dataHi; /* new value for *addr */
2246 IRExpr* dataLo;
2247 }
2248 IRCAS;
2249
2250extern void ppIRCAS ( IRCAS* cas );
2251
2252extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2253 IREndness end, IRExpr* addr,
2254 IRExpr* expdHi, IRExpr* expdLo,
2255 IRExpr* dataHi, IRExpr* dataLo );
2256
2257extern IRCAS* deepCopyIRCAS ( IRCAS* );
2258
floriand6f38b32012-05-31 15:46:18 +00002259
2260/* ------------------ Circular Array Put ------------------ */
sewardjcfe046e2013-01-17 14:23:53 +00002261
floriand6f38b32012-05-31 15:46:18 +00002262typedef
2263 struct {
2264 IRRegArray* descr; /* Part of guest state treated as circular */
2265 IRExpr* ix; /* Variable part of index into array */
2266 Int bias; /* Constant offset part of index into array */
2267 IRExpr* data; /* The value to write */
2268 } IRPutI;
2269
2270extern void ppIRPutI ( IRPutI* puti );
2271
2272extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2273 Int bias, IRExpr* data );
2274
2275extern IRPutI* deepCopyIRPutI ( IRPutI* );
2276
sewardjc9069f22012-06-01 16:09:50 +00002277
sewardjcfe046e2013-01-17 14:23:53 +00002278/* --------------- Guarded loads and stores --------------- */
2279
2280/* Conditional stores are straightforward. They are the same as
2281 normal stores, with an extra 'guard' field :: Ity_I1 that
2282 determines whether or not the store actually happens. If not,
2283 memory is unmodified.
2284
2285 The semantics of this is that 'addr' and 'data' are fully evaluated
2286 even in the case where 'guard' evaluates to zero (false).
2287*/
2288typedef
2289 struct {
2290 IREndness end; /* Endianness of the store */
2291 IRExpr* addr; /* store address */
2292 IRExpr* data; /* value to write */
2293 IRExpr* guard; /* Guarding value */
2294 }
2295 IRStoreG;
2296
2297/* Conditional loads are a little more complex. 'addr' is the
2298 address, 'guard' is the guarding condition. If the load takes
2299 place, the loaded value is placed in 'dst'. If it does not take
2300 place, 'alt' is copied to 'dst'. However, the loaded value is not
2301 placed directly in 'dst' -- it is first subjected to the conversion
2302 specified by 'cvt'.
2303
2304 For example, imagine doing a conditional 8-bit load, in which the
2305 loaded value is zero extended to 32 bits. Hence:
2306 * 'dst' and 'alt' must have type I32
2307 * 'cvt' must be a unary op which converts I8 to I32. In this
2308 example, it would be ILGop_8Uto32.
2309
2310 There is no explicit indication of the type at which the load is
2311 done, since that is inferrable from the arg type of 'cvt'. Note
2312 that the types of 'alt' and 'dst' and the result type of 'cvt' must
2313 all be the same.
2314
2315 Semantically, 'addr' is evaluated even in the case where 'guard'
2316 evaluates to zero (false), and 'alt' is evaluated even when 'guard'
2317 evaluates to one (true). That is, 'addr' and 'alt' are always
2318 evaluated.
2319*/
2320typedef
2321 enum {
2322 ILGop_INVALID=0x1D00,
2323 ILGop_Ident32, /* 32 bit, no conversion */
2324 ILGop_16Uto32, /* 16 bit load, Z-widen to 32 */
2325 ILGop_16Sto32, /* 16 bit load, S-widen to 32 */
2326 ILGop_8Uto32, /* 8 bit load, Z-widen to 32 */
2327 ILGop_8Sto32 /* 8 bit load, S-widen to 32 */
2328 }
2329 IRLoadGOp;
2330
2331typedef
2332 struct {
2333 IREndness end; /* Endianness of the load */
2334 IRLoadGOp cvt; /* Conversion to apply to the loaded value */
2335 IRTemp dst; /* Destination (LHS) of assignment */
2336 IRExpr* addr; /* Address being loaded from */
2337 IRExpr* alt; /* Value if load is not done. */
2338 IRExpr* guard; /* Guarding value */
2339 }
2340 IRLoadG;
2341
2342extern void ppIRStoreG ( IRStoreG* sg );
2343
2344extern void ppIRLoadGOp ( IRLoadGOp cvt );
2345
2346extern void ppIRLoadG ( IRLoadG* lg );
2347
2348extern IRStoreG* mkIRStoreG ( IREndness end,
2349 IRExpr* addr, IRExpr* data,
2350 IRExpr* guard );
2351
2352extern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
2353 IRTemp dst, IRExpr* addr, IRExpr* alt,
2354 IRExpr* guard );
2355
2356
sewardjc97096c2004-06-30 09:28:04 +00002357/* ------------------ Statements ------------------ */
sewardjb3bce0e2004-09-14 23:20:10 +00002358
sewardj57c10c82006-11-15 02:57:05 +00002359/* The different kinds of statements. Their meaning is explained
2360 below in the comments for IRStmt.
sewardj5a9ffab2005-05-12 17:55:01 +00002361
sewardj57c10c82006-11-15 02:57:05 +00002362 Those marked META do not represent code, but rather extra
2363 information about the code. These statements can be removed
2364 without affecting the functional behaviour of the code, however
2365 they are required by some IR consumers such as tools that
2366 instrument the code.
sewardj5a9ffab2005-05-12 17:55:01 +00002367*/
sewardjc4356f02007-11-09 21:15:04 +00002368
sewardjac6b7122004-06-27 01:03:57 +00002369typedef
sewardjd2445f62005-03-21 00:15:53 +00002370 enum {
sewardjcfe046e2013-01-17 14:23:53 +00002371 Ist_NoOp=0x1E00,
sewardj57c10c82006-11-15 02:57:05 +00002372 Ist_IMark, /* META */
2373 Ist_AbiHint, /* META */
2374 Ist_Put,
2375 Ist_PutI,
sewardjdd40fdf2006-12-24 02:20:24 +00002376 Ist_WrTmp,
sewardj57c10c82006-11-15 02:57:05 +00002377 Ist_Store,
sewardjcfe046e2013-01-17 14:23:53 +00002378 Ist_LoadG,
2379 Ist_StoreG,
sewardje9d8a262009-07-01 08:06:34 +00002380 Ist_CAS,
sewardje768e922009-11-26 17:17:37 +00002381 Ist_LLSC,
sewardj57c10c82006-11-15 02:57:05 +00002382 Ist_Dirty,
sewardjcfe046e2013-01-17 14:23:53 +00002383 Ist_MBE,
sewardj57c10c82006-11-15 02:57:05 +00002384 Ist_Exit
sewardjb3bce0e2004-09-14 23:20:10 +00002385 }
sewardjac6b7122004-06-27 01:03:57 +00002386 IRStmtTag;
2387
sewardj57c10c82006-11-15 02:57:05 +00002388/* A statement. Stored as a tagged union. 'tag' indicates what kind
2389 of expression this is. 'Ist' is the union that holds the fields.
2390 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2391 statement, and the fields can be accessed with
2392 'st.Ist.Store.<fieldname>'.
2393
2394 For each kind of statement, we show what it looks like when
sewardje9d8a262009-07-01 08:06:34 +00002395 pretty-printed with ppIRStmt().
sewardj57c10c82006-11-15 02:57:05 +00002396*/
sewardjac6b7122004-06-27 01:03:57 +00002397typedef
2398 struct _IRStmt {
2399 IRStmtTag tag;
2400 union {
sewardj57c10c82006-11-15 02:57:05 +00002401 /* A no-op (usually resulting from IR optimisation). Can be
2402 omitted without any effect.
2403
sewardje9d8a262009-07-01 08:06:34 +00002404 ppIRStmt output: IR-NoOp
sewardj57c10c82006-11-15 02:57:05 +00002405 */
sewardjac6b7122004-06-27 01:03:57 +00002406 struct {
sewardjd2445f62005-03-21 00:15:53 +00002407 } NoOp;
sewardj57c10c82006-11-15 02:57:05 +00002408
2409 /* META: instruction mark. Marks the start of the statements
2410 that represent a single machine instruction (the end of
2411 those statements is marked by the next IMark or the end of
sewardjdd40fdf2006-12-24 02:20:24 +00002412 the IRSB). Contains the address and length of the
sewardj57c10c82006-11-15 02:57:05 +00002413 instruction.
2414
sewardj2f10aa62011-05-27 13:20:56 +00002415 It also contains a delta value. The delta must be
2416 subtracted from a guest program counter value before
2417 attempting to establish, by comparison with the address
2418 and length values, whether or not that program counter
2419 value refers to this instruction. For x86, amd64, ppc32,
2420 ppc64 and arm, the delta value is zero. For Thumb
2421 instructions, the delta value is one. This is because, on
2422 Thumb, guest PC values (guest_R15T) are encoded using the
2423 top 31 bits of the instruction address and a 1 in the lsb;
2424 hence they appear to be (numerically) 1 past the start of
2425 the instruction they refer to. IOW, guest_R15T on ARM
2426 holds a standard ARM interworking address.
2427
2428 ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2429 eg. ------ IMark(0x4000792, 5, 0) ------,
sewardj57c10c82006-11-15 02:57:05 +00002430 */
sewardjd2445f62005-03-21 00:15:53 +00002431 struct {
sewardj57c10c82006-11-15 02:57:05 +00002432 Addr64 addr; /* instruction address */
2433 Int len; /* instruction length */
sewardj2f10aa62011-05-27 13:20:56 +00002434 UChar delta; /* addr = program counter as encoded in guest state
2435 - delta */
sewardjf1689312005-03-16 18:19:10 +00002436 } IMark;
sewardj57c10c82006-11-15 02:57:05 +00002437
2438 /* META: An ABI hint, which says something about this
2439 platform's ABI.
2440
2441 At the moment, the only AbiHint is one which indicates
2442 that a given chunk of address space, [base .. base+len-1],
2443 has become undefined. This is used on amd64-linux and
2444 some ppc variants to pass stack-redzoning hints to whoever
sewardj478646f2008-05-01 20:13:04 +00002445 wants to see them. It also indicates the address of the
2446 next (dynamic) instruction that will be executed. This is
2447 to help Memcheck to origin tracking.
sewardj57c10c82006-11-15 02:57:05 +00002448
sewardje9d8a262009-07-01 08:06:34 +00002449 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
sewardj478646f2008-05-01 20:13:04 +00002450 eg. ====== AbiHint(t1, 16, t2) ======
sewardj57c10c82006-11-15 02:57:05 +00002451 */
sewardjf1689312005-03-16 18:19:10 +00002452 struct {
sewardj57c10c82006-11-15 02:57:05 +00002453 IRExpr* base; /* Start of undefined chunk */
2454 Int len; /* Length of undefined chunk */
sewardj478646f2008-05-01 20:13:04 +00002455 IRExpr* nia; /* Address of next (guest) insn */
sewardj5a9ffab2005-05-12 17:55:01 +00002456 } AbiHint;
sewardj57c10c82006-11-15 02:57:05 +00002457
2458 /* Write a guest register, at a fixed offset in the guest state.
sewardje9d8a262009-07-01 08:06:34 +00002459 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
sewardj57c10c82006-11-15 02:57:05 +00002460 */
sewardj5a9ffab2005-05-12 17:55:01 +00002461 struct {
sewardj57c10c82006-11-15 02:57:05 +00002462 Int offset; /* Offset into the guest state */
2463 IRExpr* data; /* The value to write */
sewardjac6b7122004-06-27 01:03:57 +00002464 } Put;
sewardj57c10c82006-11-15 02:57:05 +00002465
2466 /* Write a guest register, at a non-fixed offset in the guest
2467 state. See the comment for GetI expressions for more
2468 information.
2469
sewardje9d8a262009-07-01 08:06:34 +00002470 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
sewardj57c10c82006-11-15 02:57:05 +00002471 eg. PUTI(64:8xF64)[t5,0] = t1
2472 */
sewardjac6b7122004-06-27 01:03:57 +00002473 struct {
floriand6f38b32012-05-31 15:46:18 +00002474 IRPutI* details;
sewardjd1725d12004-08-12 20:46:53 +00002475 } PutI;
sewardj57c10c82006-11-15 02:57:05 +00002476
sewardjdd40fdf2006-12-24 02:20:24 +00002477 /* Assign a value to a temporary. Note that SSA rules require
2478 each tmp is only assigned to once. IR sanity checking will
2479 reject any block containing a temporary which is not assigned
2480 to exactly once.
sewardj57c10c82006-11-15 02:57:05 +00002481
sewardje9d8a262009-07-01 08:06:34 +00002482 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
sewardj57c10c82006-11-15 02:57:05 +00002483 */
sewardjd1725d12004-08-12 20:46:53 +00002484 struct {
sewardj57c10c82006-11-15 02:57:05 +00002485 IRTemp tmp; /* Temporary (LHS of assignment) */
2486 IRExpr* data; /* Expression (RHS of assignment) */
sewardjdd40fdf2006-12-24 02:20:24 +00002487 } WrTmp;
sewardj57c10c82006-11-15 02:57:05 +00002488
sewardje768e922009-11-26 17:17:37 +00002489 /* Write a value to memory. This is a normal store, not a
2490 Store-Conditional. To represent a Store-Conditional,
2491 instead use IRStmt.LLSC.
sewardje9d8a262009-07-01 08:06:34 +00002492 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
sewardj57c10c82006-11-15 02:57:05 +00002493 */
sewardjac6b7122004-06-27 01:03:57 +00002494 struct {
sewardj57c10c82006-11-15 02:57:05 +00002495 IREndness end; /* Endianness of the store */
2496 IRExpr* addr; /* store address */
2497 IRExpr* data; /* value to write */
sewardjaf1ceca2005-06-30 23:31:27 +00002498 } Store;
sewardj57c10c82006-11-15 02:57:05 +00002499
sewardjcfe046e2013-01-17 14:23:53 +00002500 /* Guarded store. Note that this is defined to evaluate all
2501 expression fields (addr, data) even if the guard evaluates
2502 to false.
2503 ppIRStmt output:
2504 if (<guard>) ST<end>(<addr>) = <data> */
2505 struct {
2506 IRStoreG* details;
2507 } StoreG;
2508
2509 /* Guarded load. Note that this is defined to evaluate all
2510 expression fields (addr, alt) even if the guard evaluates
2511 to false.
2512 ppIRStmt output:
2513 t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */
2514 struct {
2515 IRLoadG* details;
2516 } LoadG;
2517
sewardje9d8a262009-07-01 08:06:34 +00002518 /* Do an atomic compare-and-swap operation. Semantics are
2519 described above on a comment at the definition of IRCAS.
2520
2521 ppIRStmt output:
2522 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
2523 eg
2524 t1 = CASle(t2 :: t3->Add32(t3,1))
2525 which denotes a 32-bit atomic increment
2526 of a value at address t2
2527
2528 A double-element CAS may also be denoted, in which case <tmp>,
2529 <expected> and <new> are all pairs of items, separated by
2530 commas.
2531 */
2532 struct {
2533 IRCAS* details;
2534 } CAS;
2535
sewardje768e922009-11-26 17:17:37 +00002536 /* Either Load-Linked or Store-Conditional, depending on
2537 STOREDATA.
2538
2539 If STOREDATA is NULL then this is a Load-Linked, meaning
2540 that data is loaded from memory as normal, but a
2541 'reservation' for the address is also lodged in the
2542 hardware.
2543
2544 result = Load-Linked(addr, end)
2545
2546 The data transfer type is the type of RESULT (I32, I64,
2547 etc). ppIRStmt output:
2548
2549 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
2550
2551 If STOREDATA is not NULL then this is a Store-Conditional,
2552 hence:
2553
2554 result = Store-Conditional(addr, storedata, end)
2555
2556 The data transfer type is the type of STOREDATA and RESULT
2557 has type Ity_I1. The store may fail or succeed depending
2558 on the state of a previously lodged reservation on this
2559 address. RESULT is written 1 if the store succeeds and 0
2560 if it fails. eg ppIRStmt output:
2561
2562 result = ( ST<end>-Cond(<addr>) = <storedata> )
2563 eg t3 = ( STbe-Cond(t1, t2) )
2564
2565 In all cases, the address must be naturally aligned for
2566 the transfer type -- any misaligned addresses should be
2567 caught by a dominating IR check and side exit. This
2568 alignment restriction exists because on at least some
2569 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
2570 misaligned addresses, and we have to actually generate
2571 stwcx. on the host, and we don't want it trapping on the
2572 host.
2573
2574 Summary of rules for transfer type:
2575 STOREDATA == NULL (LL):
2576 transfer type = type of RESULT
2577 STOREDATA != NULL (SC):
2578 transfer type = type of STOREDATA, and RESULT :: Ity_I1
2579 */
2580 struct {
2581 IREndness end;
2582 IRTemp result;
2583 IRExpr* addr;
2584 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
2585 } LLSC;
2586
sewardj57c10c82006-11-15 02:57:05 +00002587 /* Call (possibly conditionally) a C function that has side
2588 effects (ie. is "dirty"). See the comments above the
2589 IRDirty type declaration for more information.
2590
sewardje9d8a262009-07-01 08:06:34 +00002591 ppIRStmt output:
sewardj57c10c82006-11-15 02:57:05 +00002592 t<tmp> = DIRTY <guard> <effects>
2593 ::: <callee>(<args>)
2594 eg.
2595 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
2596 ::: foo{0x380035f4}(t2)
2597 */
sewardj64e1d652004-07-12 14:00:46 +00002598 struct {
sewardjb3bce0e2004-09-14 23:20:10 +00002599 IRDirty* details;
2600 } Dirty;
sewardj57c10c82006-11-15 02:57:05 +00002601
sewardjc4356f02007-11-09 21:15:04 +00002602 /* A memory bus event - a fence, or acquisition/release of the
2603 hardware bus lock. IR optimisation treats all these as fences
2604 across which no memory references may be moved.
sewardje9d8a262009-07-01 08:06:34 +00002605 ppIRStmt output: MBusEvent-Fence,
sewardjc4356f02007-11-09 21:15:04 +00002606 MBusEvent-BusLock, MBusEvent-BusUnlock.
sewardj57c10c82006-11-15 02:57:05 +00002607 */
sewardjb3bce0e2004-09-14 23:20:10 +00002608 struct {
sewardjc4356f02007-11-09 21:15:04 +00002609 IRMBusEvent event;
2610 } MBE;
sewardj57c10c82006-11-15 02:57:05 +00002611
sewardjdd40fdf2006-12-24 02:20:24 +00002612 /* Conditional exit from the middle of an IRSB.
sewardje9d8a262009-07-01 08:06:34 +00002613 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
sewardj57c10c82006-11-15 02:57:05 +00002614 eg. if (t69) goto {Boring} 0x4000AAA:I32
sewardjc6f970f2012-04-02 21:54:49 +00002615 If <guard> is true, the guest state is also updated by
2616 PUT-ing <dst> at <offsIP>. This is done because a
2617 taken exit must update the guest program counter.
sewardj57c10c82006-11-15 02:57:05 +00002618 */
sewardj3e838932005-01-07 12:09:15 +00002619 struct {
sewardj57c10c82006-11-15 02:57:05 +00002620 IRExpr* guard; /* Conditional expression */
sewardj57c10c82006-11-15 02:57:05 +00002621 IRConst* dst; /* Jump target (constant only) */
floriand6f38b32012-05-31 15:46:18 +00002622 IRJumpKind jk; /* Jump kind */
sewardjc6f970f2012-04-02 21:54:49 +00002623 Int offsIP; /* Guest state offset for IP */
sewardj64e1d652004-07-12 14:00:46 +00002624 } Exit;
sewardjac6b7122004-06-27 01:03:57 +00002625 } Ist;
sewardjac6b7122004-06-27 01:03:57 +00002626 }
2627 IRStmt;
sewardjec6ad592004-06-20 12:26:53 +00002628
sewardj57c10c82006-11-15 02:57:05 +00002629/* Statement constructors. */
sewardj5a9ffab2005-05-12 17:55:01 +00002630extern IRStmt* IRStmt_NoOp ( void );
sewardj2f10aa62011-05-27 13:20:56 +00002631extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len, UChar delta );
sewardj478646f2008-05-01 20:13:04 +00002632extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
sewardj5a9ffab2005-05-12 17:55:01 +00002633extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
floriand6f38b32012-05-31 15:46:18 +00002634extern IRStmt* IRStmt_PutI ( IRPutI* details );
sewardjdd40fdf2006-12-24 02:20:24 +00002635extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
sewardje768e922009-11-26 17:17:37 +00002636extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
sewardjcfe046e2013-01-17 14:23:53 +00002637extern IRStmt* IRStmt_StoreG ( IREndness end, IRExpr* addr, IRExpr* data,
2638 IRExpr* guard );
2639extern IRStmt* IRStmt_LoadG ( IREndness end, IRLoadGOp cvt, IRTemp dst,
2640 IRExpr* addr, IRExpr* alt, IRExpr* guard );
sewardje9d8a262009-07-01 08:06:34 +00002641extern IRStmt* IRStmt_CAS ( IRCAS* details );
sewardje768e922009-11-26 17:17:37 +00002642extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
2643 IRExpr* addr, IRExpr* storedata );
sewardj5a9ffab2005-05-12 17:55:01 +00002644extern IRStmt* IRStmt_Dirty ( IRDirty* details );
sewardjc4356f02007-11-09 21:15:04 +00002645extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
sewardjc6f970f2012-04-02 21:54:49 +00002646extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
2647 Int offsIP );
sewardjec6ad592004-06-20 12:26:53 +00002648
sewardj57c10c82006-11-15 02:57:05 +00002649/* Deep-copy an IRStmt. */
sewardjdd40fdf2006-12-24 02:20:24 +00002650extern IRStmt* deepCopyIRStmt ( IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002651
sewardj57c10c82006-11-15 02:57:05 +00002652/* Pretty-print an IRStmt. */
sewardj35421a32004-07-05 13:12:34 +00002653extern void ppIRStmt ( IRStmt* );
sewardjc97096c2004-06-30 09:28:04 +00002654
2655
sewardje539a402004-07-14 18:24:17 +00002656/* ------------------ Basic Blocks ------------------ */
sewardj78c19df2004-07-12 22:49:27 +00002657
sewardj57c10c82006-11-15 02:57:05 +00002658/* Type environments: a bunch of statements, expressions, etc, are
2659 incomplete without an environment indicating the type of each
2660 IRTemp. So this provides one. IR temporaries are really just
2661 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
2662 them.
sewardjc97096c2004-06-30 09:28:04 +00002663*/
2664typedef
sewardjc97096c2004-06-30 09:28:04 +00002665 struct {
sewardje539a402004-07-14 18:24:17 +00002666 IRType* types;
2667 Int types_size;
2668 Int types_used;
sewardjc97096c2004-06-30 09:28:04 +00002669 }
2670 IRTypeEnv;
2671
sewardj57c10c82006-11-15 02:57:05 +00002672/* Obtain a new IRTemp */
2673extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
2674
2675/* Deep-copy a type environment */
sewardjdd40fdf2006-12-24 02:20:24 +00002676extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
sewardj695cff92004-10-13 14:50:14 +00002677
sewardj57c10c82006-11-15 02:57:05 +00002678/* Pretty-print a type environment */
sewardj35421a32004-07-05 13:12:34 +00002679extern void ppIRTypeEnv ( IRTypeEnv* );
sewardjc97096c2004-06-30 09:28:04 +00002680
sewardjec6ad592004-06-20 12:26:53 +00002681
sewardjdd40fdf2006-12-24 02:20:24 +00002682/* Code blocks, which in proper compiler terminology are superblocks
2683 (single entry, multiple exit code sequences) contain:
2684
sewardj57c10c82006-11-15 02:57:05 +00002685 - A table giving a type for each temp (the "type environment")
sewardjd7cb8532004-08-17 23:59:23 +00002686 - An expandable array of statements
sewardje539a402004-07-14 18:24:17 +00002687 - An expression of type 32 or 64 bits, depending on the
sewardjdd40fdf2006-12-24 02:20:24 +00002688 guest's word size, indicating the next destination if the block
2689 executes all the way to the end, without a side exit
sewardjd7cb8532004-08-17 23:59:23 +00002690 - An indication of any special actions (JumpKind) needed
2691 for this final jump.
sewardjc6f970f2012-04-02 21:54:49 +00002692 - Offset of the IP field in the guest state. This will be
2693 updated before the final jump is done.
sewardj57c10c82006-11-15 02:57:05 +00002694
sewardjdd40fdf2006-12-24 02:20:24 +00002695 "IRSB" stands for "IR Super Block".
sewardjec6ad592004-06-20 12:26:53 +00002696*/
sewardjac6b7122004-06-27 01:03:57 +00002697typedef
sewardj57c10c82006-11-15 02:57:05 +00002698 struct {
sewardjc97096c2004-06-30 09:28:04 +00002699 IRTypeEnv* tyenv;
sewardjd7cb8532004-08-17 23:59:23 +00002700 IRStmt** stmts;
2701 Int stmts_size;
2702 Int stmts_used;
sewardje539a402004-07-14 18:24:17 +00002703 IRExpr* next;
2704 IRJumpKind jumpkind;
sewardjc6f970f2012-04-02 21:54:49 +00002705 Int offsIP;
sewardjac6b7122004-06-27 01:03:57 +00002706 }
sewardjdd40fdf2006-12-24 02:20:24 +00002707 IRSB;
sewardjec6ad592004-06-20 12:26:53 +00002708
sewardjdd40fdf2006-12-24 02:20:24 +00002709/* Allocate a new, uninitialised IRSB */
2710extern IRSB* emptyIRSB ( void );
sewardj695cff92004-10-13 14:50:14 +00002711
sewardjdd40fdf2006-12-24 02:20:24 +00002712/* Deep-copy an IRSB */
2713extern IRSB* deepCopyIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002714
sewardjdd40fdf2006-12-24 02:20:24 +00002715/* Deep-copy an IRSB, except for the statements list, which set to be
sewardj6f2f2832006-11-24 23:32:55 +00002716 a new, empty, list of statements. */
sewardjdd40fdf2006-12-24 02:20:24 +00002717extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
sewardj57c10c82006-11-15 02:57:05 +00002718
sewardjdd40fdf2006-12-24 02:20:24 +00002719/* Pretty-print an IRSB */
2720extern void ppIRSB ( IRSB* );
sewardjc97096c2004-06-30 09:28:04 +00002721
sewardjdd40fdf2006-12-24 02:20:24 +00002722/* Append an IRStmt to an IRSB */
2723extern void addStmtToIRSB ( IRSB*, IRStmt* );
sewardj695cff92004-10-13 14:50:14 +00002724
2725
sewardjec6ad592004-06-20 12:26:53 +00002726/*---------------------------------------------------------------*/
sewardjc97096c2004-06-30 09:28:04 +00002727/*--- Helper functions for the IR ---*/
sewardjec6ad592004-06-20 12:26:53 +00002728/*---------------------------------------------------------------*/
2729
sewardjc97096c2004-06-30 09:28:04 +00002730/* For messing with IR type environments */
sewardjd7cb8532004-08-17 23:59:23 +00002731extern IRTypeEnv* emptyIRTypeEnv ( void );
sewardjec6ad592004-06-20 12:26:53 +00002732
sewardjc97096c2004-06-30 09:28:04 +00002733/* What is the type of this expression? */
sewardj6efd4a12004-07-15 03:54:23 +00002734extern IRType typeOfIRConst ( IRConst* );
sewardj17442fe2004-09-20 14:54:28 +00002735extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp );
sewardj6efd4a12004-07-15 03:54:23 +00002736extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
sewardjec6ad592004-06-20 12:26:53 +00002737
sewardjcfe046e2013-01-17 14:23:53 +00002738/* What are the arg and result type for this IRLoadGOp? */
2739extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
2740 /*OUT*/IRType* t_res,
2741 /*OUT*/IRType* t_arg );
2742
sewardj35439212004-07-14 22:36:10 +00002743/* Sanity check a BB of IR */
sewardjdd40fdf2006-12-24 02:20:24 +00002744extern void sanityCheckIRSB ( IRSB* bb,
florian1ff47562012-10-21 02:09:51 +00002745 const HChar* caller,
sewardjb9230752004-12-29 19:25:06 +00002746 Bool require_flatness,
2747 IRType guest_word_size );
sewardjcf787902004-11-03 09:08:33 +00002748extern Bool isFlatIRStmt ( IRStmt* );
sewardjec6ad592004-06-20 12:26:53 +00002749
sewardj6d2638e2004-07-15 09:38:27 +00002750/* Is this any value actually in the enumeration 'IRType' ? */
sewardj496a58d2005-03-20 18:44:44 +00002751extern Bool isPlausibleIRType ( IRType ty );
sewardj6d2638e2004-07-15 09:38:27 +00002752
florian2245ce92012-08-28 16:49:30 +00002753
2754/*---------------------------------------------------------------*/
2755/*--- IR injection ---*/
2756/*---------------------------------------------------------------*/
2757void vex_inject_ir(IRSB *, IREndness);
2758
2759
sewardj887a11a2004-07-05 17:26:47 +00002760#endif /* ndef __LIBVEX_IR_H */
sewardjac9af022004-07-05 01:15:34 +00002761
2762
2763/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +00002764/*--- libvex_ir.h ---*/
sewardjac9af022004-07-05 01:15:34 +00002765/*---------------------------------------------------------------*/