non-linux regtest: update cmdline expecteds
[valgrind.git] / VEX / pub / libvex_ir.h
blob1b4efdc90e1e617f7e14cba2d0613d2ed3313fb3
2 /*---------------------------------------------------------------*/
3 /*--- begin libvex_ir.h ---*/
4 /*---------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2004-2017 OpenWorks LLP
11 info@open-works.net
13 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.
18 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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
28 Neither the names of the U.S. Department of Energy nor the
29 University of California nor the names of its contributors may be
30 used to endorse or promote products derived from this software
31 without prior written permission.
34 #ifndef __LIBVEX_IR_H
35 #define __LIBVEX_IR_H
37 #include "libvex_basictypes.h"
40 /*---------------------------------------------------------------*/
41 /*--- High-level IR description ---*/
42 /*---------------------------------------------------------------*/
44 /* Vex IR is an architecture-neutral intermediate representation.
45 Unlike some IRs in systems similar to Vex, it is not like assembly
46 language (ie. a list of instructions). Rather, it is more like the
47 IR that might be used in a compiler.
49 Code blocks
50 ~~~~~~~~~~~
51 The code is broken into small code blocks ("superblocks", type:
52 'IRSB'). Each code block typically represents from 1 to perhaps 50
53 instructions. IRSBs are single-entry, multiple-exit code blocks.
54 Each IRSB contains three things:
55 - a type environment, which indicates the type of each temporary
56 value present in the IRSB
57 - a list of statements, which represent code
58 - a jump that exits from the end the IRSB
59 Because the blocks are multiple-exit, there can be additional
60 conditional exit statements that cause control to leave the IRSB
61 before the final exit. Also because of this, IRSBs can cover
62 multiple non-consecutive sequences of code (up to 3). These are
63 recorded in the type VexGuestExtents (see libvex.h).
65 Statements and expressions
66 ~~~~~~~~~~~~~~~~~~~~~~~~~~
67 Statements (type 'IRStmt') represent operations with side-effects,
68 eg. guest register writes, stores, and assignments to temporaries.
69 Expressions (type 'IRExpr') represent operations without
70 side-effects, eg. arithmetic operations, loads, constants.
71 Expressions can contain sub-expressions, forming expression trees,
72 eg. (3 + (4 * load(addr1)).
74 Storage of guest state
75 ~~~~~~~~~~~~~~~~~~~~~~
76 The "guest state" contains the guest registers of the guest machine
77 (ie. the machine that we are simulating). It is stored by default
78 in a block of memory supplied by the user of the VEX library,
79 generally referred to as the guest state (area). To operate on
80 these registers, one must first read ("Get") them from the guest
81 state into a temporary value. Afterwards, one can write ("Put")
82 them back into the guest state.
84 Get and Put are characterised by a byte offset into the guest
85 state, a small integer which effectively gives the identity of the
86 referenced guest register, and a type, which indicates the size of
87 the value to be transferred.
89 The basic "Get" and "Put" operations are sufficient to model normal
90 fixed registers on the guest. Selected areas of the guest state
91 can be treated as a circular array of registers (type:
92 'IRRegArray'), which can be indexed at run-time. This is done with
93 the "GetI" and "PutI" primitives. This is necessary to describe
94 rotating register files, for example the x87 FPU stack, SPARC
95 register windows, and the Itanium register files.
97 Examples, and flattened vs. unflattened code
98 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 For example, consider this x86 instruction:
101 addl %eax, %ebx
103 One Vex IR translation for this code would be this:
105 ------ IMark(0x24F275, 7, 0) ------
106 t3 = GET:I32(0) # get %eax, a 32-bit integer
107 t2 = GET:I32(12) # get %ebx, a 32-bit integer
108 t1 = Add32(t3,t2) # addl
109 PUT(0) = t1 # put %eax
111 (For simplicity, this ignores the effects on the condition codes, and
112 the update of the instruction pointer.)
114 The "IMark" is an IR statement that doesn't represent actual code.
115 Instead it indicates the address and length of the original
116 instruction. The numbers 0 and 12 are offsets into the guest state
117 for %eax and %ebx. The full list of offsets for an architecture
118 <ARCH> can be found in the type VexGuest<ARCH>State in the file
119 VEX/pub/libvex_guest_<ARCH>.h.
121 The five statements in this example are:
122 - the IMark
123 - three assignments to temporaries
124 - one register write (put)
126 The six expressions in this example are:
127 - two register reads (gets)
128 - one arithmetic (add) operation
129 - three temporaries (two nested within the Add32, one in the PUT)
131 The above IR is "flattened", ie. all sub-expressions are "atoms",
132 either constants or temporaries. An equivalent, unflattened version
133 would be:
135 PUT(0) = Add32(GET:I32(0), GET:I32(12))
137 IR is guaranteed to be flattened at instrumentation-time. This makes
138 instrumentation easier. Equivalent flattened and unflattened IR
139 typically results in the same generated code.
141 Another example, this one showing loads and stores:
143 addl %edx,4(%eax)
145 This becomes (again ignoring condition code and instruction pointer
146 updates):
148 ------ IMark(0x4000ABA, 3, 0) ------
149 t3 = Add32(GET:I32(0),0x4:I32)
150 t2 = LDle:I32(t3)
151 t1 = GET:I32(8)
152 t0 = Add32(t2,t1)
153 STle(t3) = t0
155 The "le" in "LDle" and "STle" is short for "little-endian".
157 No need for deallocations
158 ~~~~~~~~~~~~~~~~~~~~~~~~~
159 Although there are allocation functions for various data structures
160 in this file, there are no deallocation functions. This is because
161 Vex uses a memory allocation scheme that automatically reclaims the
162 memory used by allocated structures once translation is completed.
163 This makes things easier for tools that instruments/transforms code
164 blocks.
166 SSAness and typing
167 ~~~~~~~~~~~~~~~~~~
168 The IR is fully typed. For every IRSB (IR block) it is possible to
169 say unambiguously whether or not it is correctly typed.
170 Incorrectly typed IR has no meaning and the VEX will refuse to
171 process it. At various points during processing VEX typechecks the
172 IR and aborts if any violations are found. This seems overkill but
173 makes it a great deal easier to build a reliable JIT.
175 IR also has the SSA property. SSA stands for Static Single
176 Assignment, and what it means is that each IR temporary may be
177 assigned to only once. This idea became widely used in compiler
178 construction in the mid to late 90s. It makes many IR-level
179 transformations/code improvements easier, simpler and faster.
180 Whenever it typechecks an IR block, VEX also checks the SSA
181 property holds, and will abort if not so. So SSAness is
182 mechanically and rigidly enforced.
185 /*---------------------------------------------------------------*/
186 /*--- Type definitions for the IR ---*/
187 /*---------------------------------------------------------------*/
189 /* General comments about naming schemes:
191 All publically visible functions contain the name of the primary
192 type on which they operate (IRFoo, IRBar, etc). Hence you should
193 be able to identify these functions by grepping for "IR[A-Z]".
195 For some type 'IRFoo':
197 - ppIRFoo is the printing method for IRFoo, printing it to the
198 output channel specified in the LibVEX_Initialise call.
200 - eqIRFoo is a structural equality predicate for IRFoos.
202 - deepCopyIRFoo is a deep copy constructor for IRFoos.
203 It recursively traverses the entire argument tree and
204 produces a complete new tree. All types have a deep copy
205 constructor.
207 - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
208 It creates a new top-level copy of the supplied object,
209 but does not copy any sub-objects. Only some types have a
210 shallow copy constructor.
213 /* ------------------ Types ------------------ */
215 /* A type indicates the size of a value, and whether it's an integer, a
216 float, or a vector (SIMD) value. */
217 typedef
218 enum {
219 Ity_INVALID=0x1100,
220 Ity_I1,
221 Ity_I8,
222 Ity_I16,
223 Ity_I32,
224 Ity_I64,
225 Ity_I128, /* 128-bit scalar */
226 Ity_F16, /* 16 bit float */
227 Ity_F32, /* IEEE 754 float */
228 Ity_F64, /* IEEE 754 double */
229 Ity_D32, /* 32-bit Decimal floating point */
230 Ity_D64, /* 64-bit Decimal floating point */
231 Ity_D128, /* 128-bit Decimal floating point */
232 Ity_F128, /* 128-bit floating point; implementation defined */
233 Ity_V128, /* 128-bit SIMD */
234 Ity_V256 /* 256-bit SIMD */
236 IRType;
238 /* Pretty-print an IRType */
239 extern void ppIRType ( IRType );
241 /* Get the size (in bytes) of an IRType */
242 extern Int sizeofIRType ( IRType );
244 /* Translate 1/2/4/8 into Ity_I{8,16,32,64} respectively. Asserts on
245 any other input. */
246 extern IRType integerIRTypeOfSize ( Int szB );
249 /* ------------------ Endianness ------------------ */
251 /* IREndness is used in load IRExprs and store IRStmts. */
252 typedef
253 enum {
254 Iend_LE=0x1200, /* little endian */
255 Iend_BE /* big endian */
257 IREndness;
260 /* ------------------ Constants ------------------ */
262 /* IRConsts are used within 'Const' and 'Exit' IRExprs. */
264 /* The various kinds of constant. */
265 typedef
266 enum {
267 Ico_U1=0x1300,
268 Ico_U8,
269 Ico_U16,
270 Ico_U32,
271 Ico_U64,
272 Ico_U128, /* 128-bit restricted integer constant,
273 same encoding scheme as V128 */
274 Ico_F32, /* 32-bit IEEE754 floating */
275 Ico_F32i, /* 32-bit unsigned int to be interpreted literally
276 as a IEEE754 single value. */
277 Ico_F64, /* 64-bit IEEE754 floating */
278 Ico_F64i, /* 64-bit unsigned int to be interpreted literally
279 as a IEEE754 double value. */
280 Ico_V128, /* 128-bit restricted vector constant, with 1 bit
281 (repeated 8 times) for each of the 16 x 1-byte lanes */
282 Ico_V256 /* 256-bit restricted vector constant, with 1 bit
283 (repeated 8 times) for each of the 32 x 1-byte lanes */
285 IRConstTag;
287 /* A constant. Stored as a tagged union. 'tag' indicates what kind of
288 constant this is. 'Ico' is the union that holds the fields. If an
289 IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
290 and its value can be accessed with 'c.Ico.U32'. */
291 typedef
292 struct _IRConst {
293 IRConstTag tag;
294 union {
295 Bool U1;
296 UChar U8;
297 UShort U16;
298 UInt U32;
299 ULong U64;
300 UShort U128;
301 Float F32;
302 UInt F32i;
303 Double F64;
304 ULong F64i;
305 UShort V128; /* 16-bit value; see Ico_V128 comment above */
306 UInt V256; /* 32-bit value; see Ico_V256 comment above */
307 } Ico;
309 IRConst;
311 /* IRConst constructors */
312 extern IRConst* IRConst_U1 ( Bool );
313 extern IRConst* IRConst_U8 ( UChar );
314 extern IRConst* IRConst_U16 ( UShort );
315 extern IRConst* IRConst_U32 ( UInt );
316 extern IRConst* IRConst_U64 ( ULong );
317 extern IRConst* IRConst_U128 ( UShort );
318 extern IRConst* IRConst_F32 ( Float );
319 extern IRConst* IRConst_F32i ( UInt );
320 extern IRConst* IRConst_F64 ( Double );
321 extern IRConst* IRConst_F64i ( ULong );
322 extern IRConst* IRConst_V128 ( UShort );
323 extern IRConst* IRConst_V256 ( UInt );
325 /* Deep-copy an IRConst */
326 extern IRConst* deepCopyIRConst ( const IRConst* );
328 /* Pretty-print an IRConst */
329 extern void ppIRConst ( const IRConst* );
331 /* Compare two IRConsts for equality */
332 extern Bool eqIRConst ( const IRConst*, const IRConst* );
335 /* ------------------ Call targets ------------------ */
337 /* Describes a helper function to call. The name part is purely for
338 pretty printing and not actually used. regparms=n tells the back
339 end that the callee has been declared
340 "__attribute__((regparm(n)))", although indirectly using the
341 VEX_REGPARM(n) macro. On some targets (x86) the back end will need
342 to construct a non-standard sequence to call a function declared
343 like this.
345 mcx_mask is a sop to Memcheck. It indicates which args should be
346 considered 'always defined' when lazily computing definedness of
347 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to
348 args[1], etc. If a bit is set, the corresponding arg is excluded
349 (hence "x" in "mcx") from definedness checking.
352 typedef
353 struct {
354 Int regparms;
355 const HChar* name;
356 void* addr;
357 UInt mcx_mask;
359 IRCallee;
361 /* Create an IRCallee. */
362 extern IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr );
364 /* Deep-copy an IRCallee. */
365 extern IRCallee* deepCopyIRCallee ( const IRCallee* );
367 /* Pretty-print an IRCallee. */
368 extern void ppIRCallee ( const IRCallee* );
371 /* ------------------ Guest state arrays ------------------ */
373 /* This describes a section of the guest state that we want to
374 be able to index at run time, so as to be able to describe
375 indexed or rotating register files on the guest. */
376 typedef
377 struct {
378 Int base; /* guest state offset of start of indexed area */
379 IRType elemTy; /* type of each element in the indexed area */
380 Int nElems; /* number of elements in the indexed area */
382 IRRegArray;
384 extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
386 extern IRRegArray* deepCopyIRRegArray ( const IRRegArray* );
388 extern void ppIRRegArray ( const IRRegArray* );
389 extern Bool eqIRRegArray ( const IRRegArray*, const IRRegArray* );
392 /* ------------------ Temporaries ------------------ */
394 /* This represents a temporary, eg. t1. The IR optimiser relies on the
395 fact that IRTemps are 32-bit ints. Do not change them to be ints of
396 any other size. */
397 typedef UInt IRTemp;
399 /* Pretty-print an IRTemp. */
400 extern void ppIRTemp ( IRTemp );
402 #define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
405 /* --------------- Primops (arity 1,2,3 and 4) --------------- */
407 /* Primitive operations that are used in Unop, Binop, Triop and Qop
408 IRExprs. Once we take into account integer, floating point and SIMD
409 operations of all the different sizes, there are quite a lot of them.
410 Most instructions supported by the architectures that Vex supports
411 (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid)
412 are not; they are instead handled with dirty helpers that emulate
413 their functionality. Such obscure ones are thus not directly visible
414 in the IR, but their effects on guest state (memory and registers)
415 are made visible via the annotations in IRDirty structures.
417 2018-Dec-27: some of int<->fp conversion operations have been renamed so as
418 to have a trailing _DEP, meaning "deprecated". This is because they don't
419 specify a rounding mode to be used for the conversion and so are
420 underspecified. Their use should be replaced with equivalents that do
421 specify a rounding mode, either as a first argument or using a suffix on the
422 name, that indicates the rounding mode to use.
424 typedef
425 enum {
426 /* -- Do not change this ordering. The IR generators rely on
427 (eg) Iop_Add64 == IopAdd8 + 3. -- */
429 Iop_INVALID=0x1400,
430 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
431 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
432 /* Signless mul. MullS/MullU is elsewhere. */
433 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
434 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
435 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
436 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
437 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
438 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
439 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
440 /* Integer comparisons. */
441 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
442 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
443 /* Tags for unary ops */
444 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
446 /* Exactly like CmpEQ8/16/32/64, but carrying the additional
447 hint that these compute the success/failure of a CAS
448 operation, and hence are almost certainly applied to two
449 copies of the same value, which in turn has implications for
450 Memcheck's instrumentation. */
451 Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
452 Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
454 /* Exactly like CmpNE8/16/32/64, but carrying the additional
455 hint that these needs expensive definedness tracking. */
456 Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
458 /* -- Ordering not important after here. -- */
460 /* Widening multiplies */
461 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
462 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
464 /* Counting bits */
465 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of zero.
466 You must ensure they are never given a zero argument. As of
467 2018-Nov-14 they are deprecated. Try to use the Nat variants
468 immediately below, if you can.
470 Iop_Clz64, Iop_Clz32, /* count leading zeroes */
471 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
472 /* Count leading/trailing zeroes, with "natural" semantics for the
473 case where the input is zero: then the result is the number of bits
474 in the word. */
475 Iop_ClzNat64, Iop_ClzNat32,
476 Iop_CtzNat64, Iop_CtzNat32,
477 /* Population count -- compute the number of 1 bits in the argument. */
478 Iop_PopCount64, Iop_PopCount32,
480 /* Standard integer comparisons */
481 Iop_CmpLT32S, Iop_CmpLT64S,
482 Iop_CmpLE32S, Iop_CmpLE64S,
483 Iop_CmpLT32U, Iop_CmpLT64U,
484 Iop_CmpLE32U, Iop_CmpLE64U,
486 /* As a sop to Valgrind-Memcheck, the following are useful. */
487 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
488 Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
489 Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
490 Iop_Max32U, /* unsigned max */
492 /* PowerPC-style 3-way integer comparisons. Without them it is
493 difficult to simulate PPC efficiently.
494 op(x,y) | x < y = 0x8 else
495 | x > y = 0x4 else
496 | x == y = 0x2
498 Iop_CmpORD32U, Iop_CmpORD64U,
499 Iop_CmpORD32S, Iop_CmpORD64S,
501 /* Division */
502 /* TODO: clarify semantics wrt rounding, negative values, whatever */
503 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod)
504 Iop_DivS32, // ditto, signed
505 Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod)
506 Iop_DivS64, // ditto, signed
507 Iop_DivU128, // :: I128,I128 -> I128 (simple div, no mod)
508 Iop_DivS128, // ditto, signed
510 Iop_DivU32E, // :: I32,I32 -> I32 (dividend is 32-bit arg (hi)
511 // concat with 32 0's (low))
512 Iop_DivS32E, // ditto, signed
513 Iop_DivU64E, // :: I64,I64 -> I64 (dividend is 64-bit arg (hi)
514 // concat with 64 0's (low))
515 Iop_DivS64E, // ditto, signed
516 Iop_DivU128E, // :: I128,I128 -> I128 (dividend is 128-bit arg (hi)
517 // concat with 128 0's (low))
518 Iop_DivS128E, // ditto, signed
520 Iop_DivModU64to32, // :: I64,I32 -> I64
521 // of which lo half is div and hi half is mod
522 Iop_DivModS64to32, // ditto, signed
524 Iop_DivModU128to64, // :: V128,I64 -> V128
525 // of which lo half is div and hi half is mod
526 Iop_DivModS128to64, // ditto, signed
528 Iop_DivModS64to64, // :: I64,I64 -> I128
529 // of which lo half is div and hi half is mod
530 Iop_DivModU64to64, // :: I64,I64 -> I128
531 // of which lo half is div and hi half is mod
532 Iop_DivModS32to32, // :: I32,I32 -> I64
533 // of which lo half is div and hi half is mod
534 Iop_DivModU32to32, // :: I32,I32 -> I64
535 // of which lo half is div and hi half is mod
537 Iop_ModU128, // :: I128,I128 -> I128 normal modulo operation
538 Iop_ModS128, // ditto, signed
540 /* Integer conversions. Some of these are redundant (eg
541 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
542 having a complete set reduces the typical dynamic size of IR
543 and makes the instruction selectors easier to write. */
545 /* Widening conversions */
546 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64,
547 Iop_16Uto32, Iop_16Uto64,
548 Iop_32Uto64,
549 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64,
550 Iop_16Sto32, Iop_16Sto64,
551 Iop_32Sto64,
553 /* Narrowing conversions */
554 Iop_64to8, Iop_32to8, Iop_64to16,
555 /* 8 <-> 16 bit conversions */
556 Iop_16to8, // :: I16 -> I8, low half
557 Iop_16HIto8, // :: I16 -> I8, high half
558 Iop_8HLto16, // :: (I8,I8) -> I16
559 /* 16 <-> 32 bit conversions */
560 Iop_32to16, // :: I32 -> I16, low half
561 Iop_32HIto16, // :: I32 -> I16, high half
562 Iop_16HLto32, // :: (I16,I16) -> I32
563 /* 32 <-> 64 bit conversions */
564 Iop_64to32, // :: I64 -> I32, low half
565 Iop_64HIto32, // :: I64 -> I32, high half
566 Iop_32HLto64, // :: (I32,I32) -> I64
567 /* 64 <-> 128 bit conversions */
568 Iop_128to64, // :: I128 -> I64, low half
569 Iop_128HIto64, // :: I128 -> I64, high half
570 Iop_64HLto128, // :: (I64,I64) -> I128
571 /* 1-bit stuff */
572 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */
573 Iop_And1, /* :: (Ity_Bit, Ity_Bit) -> Ity_Bit. Evaluates both args! */
574 Iop_Or1, /* :: (Ity_Bit, Ity_Bit) -> Ity_Bit. Evaluates both args! */
575 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
576 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
577 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
578 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
579 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
580 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */
581 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
582 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
583 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
585 /* ------ Floating point. We try to be IEEE754 compliant. ------ */
587 /* --- Simple stuff as mandated by 754. --- */
589 /* Binary operations, with rounding. */
590 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
591 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
593 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
594 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
596 /* Variants of the above which produce a 64-bit result but which
597 round their result to a IEEE float range first. */
598 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
599 Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
601 /* Unary operations, without rounding. */
602 /* :: F64 -> F64 */
603 Iop_NegF64, Iop_AbsF64,
605 /* :: F32 -> F32 */
606 Iop_NegF32, Iop_AbsF32,
608 /* :: F16 -> F16 */
609 Iop_NegF16, Iop_AbsF16,
611 /* Unary operations, with rounding. */
612 /* :: IRRoundingMode(I32) x F64 -> F64 */
613 Iop_SqrtF64,
615 /* :: IRRoundingMode(I32) x F32 -> F32 */
616 Iop_SqrtF32,
618 /* :: IRRoundingMode(I32) x F16 -> F16 */
619 Iop_SqrtF16,
621 /* :: IRRoundingMode(I32) x F16 x F16 -> F16 */
622 Iop_SubF16, Iop_AddF16,
624 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
625 0x45 Unordered
626 0x01 LT
627 0x00 GT
628 0x40 EQ
629 This just happens to be the Intel encoding. The values
630 are recorded in the type IRCmpF64Result.
632 /* :: F64 x F64 -> IRCmpF64Result(I32) */
633 Iop_CmpF64,
634 Iop_CmpF32,
635 Iop_CmpF16,
636 Iop_CmpF128,
638 /* --- Int to/from FP conversions. --- */
640 /* For the most part, these take a first argument :: Ity_I32 (as
641 IRRoundingMode) which is an indication of the rounding mode
642 to use, as per the following encoding ("the standard
643 encoding"):
644 00b to nearest (the default)
645 01b to -infinity
646 10b to +infinity
647 11b to zero
648 This just happens to be the Intel encoding. For reference only,
649 the PPC encoding is:
650 00b to nearest (the default)
651 01b to zero
652 10b to +infinity
653 11b to -infinity
654 Any PPC -> IR front end will have to translate these PPC
655 encodings, as encoded in the guest state, to the standard
656 encodings, to pass to the primops.
657 For reference only, the ARM VFP encoding is:
658 00b to nearest
659 01b to +infinity
660 10b to -infinity
661 11b to zero
662 Again, this will have to be converted to the standard encoding
663 to pass to primops.
665 If one of these conversions gets an out-of-range condition,
666 or a NaN, as an argument, the result is host-defined. On x86
667 the "integer indefinite" value 0x80..00 is produced. On PPC
668 it is either 0x80..00 or 0x7F..FF depending on the sign of
669 the argument.
671 On ARMvfp, when converting to a signed integer result, the
672 overflow result is 0x80..00 for negative args and 0x7F..FF
673 for positive args. For unsigned integer results it is
674 0x00..00 and 0xFF..FF respectively.
676 Rounding is required whenever the destination type cannot
677 represent exactly all values of the source type.
679 Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
680 Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
681 Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
682 Iop_F64toI64U, /* IRRoundingMode(I32) x F64 -> unsigned I64 */
684 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
686 Iop_I32StoF64, /* signed I32 -> F64 */
687 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
688 Iop_I64UtoF64, /* IRRoundingMode(I32) x unsigned I64 -> F64 */
689 Iop_I64UtoF32, /* IRRoundingMode(I32) x unsigned I64 -> F32 */
691 Iop_I32UtoF32, /* IRRoundingMode(I32) x unsigned I32 -> F32 */
692 Iop_I32UtoF64, /* unsigned I32 -> F64 */
694 Iop_F32toI32S, /* IRRoundingMode(I32) x F32 -> signed I32 */
695 Iop_F32toI64S, /* IRRoundingMode(I32) x F32 -> signed I64 */
696 Iop_F32toI32U, /* IRRoundingMode(I32) x F32 -> unsigned I32 */
697 Iop_F32toI64U, /* IRRoundingMode(I32) x F32 -> unsigned I64 */
699 Iop_I32StoF32, /* IRRoundingMode(I32) x signed I32 -> F32 */
700 Iop_I64StoF32, /* IRRoundingMode(I32) x signed I64 -> F32 */
702 /* Conversion between floating point formats */
703 Iop_F32toF64, /* F32 -> F64 */
704 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */
706 /* Reinterpretation. Take an F32/64/128 and produce an I32/64/128
707 with the same bit pattern, or vice versa. */
708 Iop_ReinterpV128asI128, Iop_ReinterpI128asV128,
709 Iop_ReinterpF128asI128, Iop_ReinterpI128asF128,
710 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
711 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
713 /* Support for 128-bit floating point */
714 Iop_F64HLtoF128,/* (high half of F128,low half of F128) -> F128 */
715 Iop_F128HItoF64,/* F128 -> high half of F128 into a F64 register */
716 Iop_F128LOtoF64,/* F128 -> low half of F128 into a F64 register */
718 /* :: IRRoundingMode(I32) x F128 x F128 -> F128 */
719 Iop_AddF128, Iop_SubF128, Iop_MulF128, Iop_DivF128,
720 Iop_MAddF128, // (A * B) + C
721 Iop_MSubF128, // (A * B) - C
722 Iop_NegMAddF128, // -((A * B) + C)
723 Iop_NegMSubF128, // -((A * B) - C)
725 /* :: F128 -> F128 */
726 Iop_NegF128, Iop_AbsF128,
728 /* :: IRRoundingMode(I32) x F128 -> F128 */
729 Iop_SqrtF128,
731 Iop_I32StoF128, /* signed I32 -> F128 */
732 Iop_I64StoF128, /* signed I64 -> F128 */
733 Iop_I32UtoF128, /* unsigned I32 -> F128 */
734 Iop_I64UtoF128, /* unsigned I64 -> F128 */
735 Iop_F32toF128, /* F32 -> F128 */
736 Iop_F64toF128, /* F64 -> F128 */
737 Iop_I128UtoF128, /* unsigned I128 -> F128 */
738 Iop_I128StoF128, /* signed I128 -> F128 */
740 Iop_F128toI32S, /* IRRoundingMode(I32) x F128 -> signed I32 */
741 Iop_F128toI64S, /* IRRoundingMode(I32) x F128 -> signed I64 */
742 Iop_F128toI32U, /* IRRoundingMode(I32) x F128 -> unsigned I32 */
743 Iop_F128toI64U, /* IRRoundingMode(I32) x F128 -> unsigned I64 */
744 Iop_F128toI128S,/* IRRoundingMode(I32) x F128 -> signed I128 */
745 Iop_F128toF64, /* IRRoundingMode(I32) x F128 -> F64 */
746 Iop_F128toF32, /* IRRoundingMode(I32) x F128 -> F32 */
747 Iop_RndF128, /* IRRoundingMode(I32) x F128 -> F128 */
749 /* Truncate to the specified value, source and result
750 * are stroed in a F128 register.
752 Iop_TruncF128toI32S, /* truncate F128 -> I32 */
753 Iop_TruncF128toI32U, /* truncate F128 -> I32 */
754 Iop_TruncF128toI64U, /* truncate F128 -> I64 */
755 Iop_TruncF128toI64S, /* truncate F128 -> I64 */
756 Iop_TruncF128toI128U, /* truncate F128 -> I128 */
757 Iop_TruncF128toI128S, /* truncate F128 -> I128 */
759 /* --- guest x86/amd64 specifics, not mandated by 754. --- */
761 /* Binary ops, with rounding. */
762 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
763 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
764 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
765 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
766 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */
767 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
768 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */
769 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
770 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
771 /* Note that on x86 guest, PRem1{C3210} has the same behaviour
772 as the IEEE mandated RemF64, except it is limited in the
773 range of its operand. Hence the partialness. */
775 /* Unary ops, with rounding. */
776 /* :: IRRoundingMode(I32) x F64 -> F64 */
777 Iop_SinF64, /* FSIN */
778 Iop_CosF64, /* FCOS */
779 Iop_TanF64, /* FTAN */
780 Iop_2xm1F64, /* (2^arg - 1.0) */
781 Iop_RoundF128toInt, /* F128 value to nearest integral value (still
782 as F128) */
783 Iop_RoundF64toInt, /* F64 value to nearest integral value (still
784 as F64) */
785 Iop_RoundF64toIntA0, /* As Iop_RoundF64toInt but ties to above zero*/
787 Iop_RoundF64toIntE, /* As Iop_RoundF64toInt but ties to even */
788 Iop_RoundF32toInt, /* F32 value to nearest integral value (still
789 as F32) */
790 Iop_RoundF32toIntA0, /* As Iop_RoundF32toInt but ties to above zero*/
791 Iop_RoundF32toIntE, /* As Iop_RoundF32toInt but ties to even */
793 /* --- guest s390 specifics, not mandated by 754. --- */
795 /* Fused multiply-add/sub */
796 /* :: IRRoundingMode(I32) x F32 x F32 x F32 -> F32
797 (computes arg2 * arg3 +/- arg4) */
798 Iop_MAddF32, Iop_MSubF32,
800 /* --- guest ppc32/64 specifics, not mandated by 754. --- */
802 /* Ternary operations, with rounding. */
803 /* Fused multiply-add/sub, with 112-bit intermediate
804 precision for ppc.
805 Also used to implement fused multiply-add/sub for s390. */
806 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
807 (computes arg2 * arg3 +/- arg4) */
808 Iop_MAddF64, Iop_MSubF64,
810 /* Variants of the above which produce a 64-bit result but which
811 round their result to a IEEE float range first. */
812 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
813 Iop_MAddF64r32, Iop_MSubF64r32,
815 /* :: F64 -> F64 */
816 Iop_RSqrtEst5GoodF64, /* reciprocal square root estimate, 5 good bits */
817 Iop_RoundF64toF64_NEAREST, /* frin */
818 Iop_RoundF64toF64_NegINF, /* frim */
819 Iop_RoundF64toF64_PosINF, /* frip */
820 Iop_RoundF64toF64_ZERO, /* friz */
822 /* :: F64 -> F32 */
823 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
825 /* :: IRRoundingMode(I32) x F64 -> F64 */
826 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
827 /* NB: pretty much the same as Iop_F64toF32, except no change
828 of type. */
830 /* --- guest arm64 specifics, not mandated by 754. --- */
832 Iop_RecpExpF64, /* FRECPX d :: IRRoundingMode(I32) x F64 -> F64 */
833 Iop_RecpExpF32, /* FRECPX s :: IRRoundingMode(I32) x F32 -> F32 */
835 /* --------- Possibly required by IEEE 754-2008. --------- */
837 Iop_MaxNumF64, /* max, F64, numerical operand if other is a qNaN */
838 Iop_MinNumF64, /* min, F64, ditto */
839 Iop_MaxNumF32, /* max, F32, ditto */
840 Iop_MinNumF32, /* min, F32, ditto */
842 /* ------------------ 16-bit scalar FP ------------------ */
844 Iop_F16toF64, /* F16 -> F64 */
845 Iop_F64toF16, /* IRRoundingMode(I32) x F64 -> F16 */
847 Iop_F16toF32, /* F16 -> F32 */
848 Iop_F32toF16, /* IRRoundingMode(I32) x F32 -> F16 */
850 /* ------------------ 32-bit SIMD Integer ------------------ */
852 /* 32x1 saturating add/sub (ok, well, not really SIMD :) */
853 Iop_QAdd32S,
854 Iop_QSub32S,
856 /* 16x2 add/sub, also signed/unsigned saturating variants */
857 Iop_Add16x2, Iop_Sub16x2,
858 Iop_QAdd16Sx2, Iop_QAdd16Ux2,
859 Iop_QSub16Sx2, Iop_QSub16Ux2,
861 /* 16x2 signed/unsigned halving add/sub. For each lane, these
862 compute bits 16:1 of (eg) sx(argL) + sx(argR),
863 or zx(argL) - zx(argR) etc. */
864 Iop_HAdd16Ux2, Iop_HAdd16Sx2,
865 Iop_HSub16Ux2, Iop_HSub16Sx2,
867 /* 8x4 add/sub, also signed/unsigned saturating variants */
868 Iop_Add8x4, Iop_Sub8x4,
869 Iop_QAdd8Sx4, Iop_QAdd8Ux4,
870 Iop_QSub8Sx4, Iop_QSub8Ux4,
872 /* 8x4 signed/unsigned halving add/sub. For each lane, these
873 compute bits 8:1 of (eg) sx(argL) + sx(argR),
874 or zx(argL) - zx(argR) etc. */
875 Iop_HAdd8Ux4, Iop_HAdd8Sx4,
876 Iop_HSub8Ux4, Iop_HSub8Sx4,
878 /* 8x4 sum of absolute unsigned differences. */
879 Iop_Sad8Ux4,
881 /* MISC (vector integer cmp != 0) */
882 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
884 /* Byte swap in a 32-bit word */
885 Iop_Reverse8sIn32_x1,
887 /* ------------------ 64-bit SIMD FP ------------------------ */
889 /* Conversion to/from int */
890 // Deprecated: these don't specify a rounding mode
891 Iop_I32UtoF32x2_DEP, Iop_I32StoF32x2_DEP, /* I32x2 -> F32x2 */
893 Iop_F32toI32Ux2_RZ, Iop_F32toI32Sx2_RZ, /* F32x2 -> I32x2 */
895 /* Fixed32 format is floating-point number with fixed number of fraction
896 bits. The number of fraction bits is passed as a second argument of
897 type I8. */
898 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */
899 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */
901 /* Binary operations */
902 Iop_Max32Fx2, Iop_Min32Fx2,
903 /* Pairwise Min and Max. See integer pairwise operations for more
904 details. */
905 Iop_PwMax32Fx2, Iop_PwMin32Fx2,
906 /* Note: For the following compares, the arm front-end assumes a
907 nan in a lane of either argument returns zero for that lane. */
908 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2,
910 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
911 element in the operand vector, and places the results in the destination
912 vector. */
913 Iop_RecipEst32Fx2,
915 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
916 Note, that if one of the arguments is zero and another one is infinity
917 of arbitrary sign the result of the operation is 2.0. */
918 Iop_RecipStep32Fx2,
920 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
921 square root of each element in the operand vector. */
922 Iop_RSqrtEst32Fx2,
924 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
925 Note, that of one of the arguments is zero and another one is infiinty
926 of arbitrary sign the result of the operation is 1.5. */
927 Iop_RSqrtStep32Fx2,
929 /* Unary */
930 Iop_Neg32Fx2, Iop_Abs32Fx2,
932 /* ------------------ 64-bit SIMD Integer. ------------------ */
934 /* MISC (vector integer cmp != 0) */
935 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
937 /* ADDITION (normal / unsigned sat / signed sat) */
938 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
939 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1,
940 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1,
942 /* PAIRWISE operations */
943 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
944 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
945 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2,
946 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2,
947 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2,
948 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2,
949 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2,
950 /* Longening variant is unary. The resulting vector contains two times
951 less elements than operand, but they are two times wider.
952 Example:
953 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
954 where a+b and c+d are unsigned 32-bit values. */
955 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2,
956 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2,
958 /* SUBTRACTION (normal / unsigned sat / signed sat) */
959 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
960 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1,
961 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1,
963 /* ABSOLUTE VALUE */
964 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2,
966 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */
967 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2,
968 Iop_Mul32Fx2,
969 Iop_MulHi16Ux4,
970 Iop_MulHi16Sx4,
971 /* Plynomial multiplication treats it's arguments as coefficients of
972 polynoms over {0, 1}. */
973 Iop_PolynomialMul8x8,
975 /* Vector Saturating Doubling Multiply Returning High Half and
976 Vector Saturating Rounding Doubling Multiply Returning High Half */
977 /* These IROp's multiply corresponding elements in two vectors, double
978 the results, and place the most significant half of the final results
979 in the destination vector. The results are truncated or rounded. If
980 any of the results overflow, they are saturated. */
981 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2,
982 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2,
984 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
985 Iop_Avg8Ux8,
986 Iop_Avg16Ux4,
988 /* MIN/MAX */
989 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2,
990 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2,
991 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2,
992 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2,
994 /* COMPARISON */
995 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
996 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2,
997 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
999 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1000 bit) */
1001 Iop_Cnt8x8,
1002 Iop_Clz8x8, Iop_Clz16x4, Iop_Clz32x2,
1003 Iop_Cls8x8, Iop_Cls16x4, Iop_Cls32x2,
1004 Iop_Clz64x2,
1006 /*Vector COUNT trailing zeros */
1007 Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2,
1009 /* VECTOR x VECTOR SHIFT / ROTATE */
1010 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2,
1011 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2,
1012 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2,
1013 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1,
1015 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1016 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
1017 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2,
1018 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
1020 /* VECTOR x VECTOR SATURATING SHIFT */
1021 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1,
1022 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1,
1023 /* VECTOR x INTEGER SATURATING SHIFT */
1024 Iop_QShlNsatSU8x8, Iop_QShlNsatSU16x4,
1025 Iop_QShlNsatSU32x2, Iop_QShlNsatSU64x1,
1026 Iop_QShlNsatUU8x8, Iop_QShlNsatUU16x4,
1027 Iop_QShlNsatUU32x2, Iop_QShlNsatUU64x1,
1028 Iop_QShlNsatSS8x8, Iop_QShlNsatSS16x4,
1029 Iop_QShlNsatSS32x2, Iop_QShlNsatSS64x1,
1031 /* NARROWING (binary)
1032 -- narrow 2xI64 into 1xI64, hi half from left arg */
1033 /* For saturated narrowing, I believe there are 4 variants of
1034 the basic arithmetic operation, depending on the signedness
1035 of argument and result. Here are examples that exemplify
1036 what I mean:
1038 QNarrow16Uto8U ( UShort x ) if (x >u 255) x = 255;
1039 return x[7:0];
1041 QNarrow16Sto8S ( Short x ) if (x <s -128) x = -128;
1042 if (x >s 127) x = 127;
1043 return x[7:0];
1045 QNarrow16Uto8S ( UShort x ) if (x >u 127) x = 127;
1046 return x[7:0];
1048 QNarrow16Sto8U ( Short x ) if (x <s 0) x = 0;
1049 if (x >s 255) x = 255;
1050 return x[7:0];
1052 Iop_QNarrowBin16Sto8Ux8,
1053 Iop_QNarrowBin16Sto8Sx8, Iop_QNarrowBin32Sto16Sx4,
1054 Iop_NarrowBin16to8x8, Iop_NarrowBin32to16x4,
1056 /* INTERLEAVING */
1057 /* Interleave lanes from low or high halves of
1058 operands. Most-significant result lane is from the left
1059 arg. */
1060 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
1061 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
1062 /* Interleave odd/even lanes of operands. Most-significant result lane
1063 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are
1064 identical to Interleave{HI,LO}32x2 and so are omitted.*/
1065 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8,
1066 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4,
1068 /* CONCATENATION -- build a new value by concatenating either
1069 the even or odd lanes of both operands. Note that
1070 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
1071 and so are omitted. */
1072 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4,
1073 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4,
1075 /* GET / SET elements of VECTOR
1076 GET is binop (I64, I8) -> I<elem_size>
1077 SET is triop (I64, I8, I<elem_size>) -> I64 */
1078 /* Note: the arm back-end handles only constant second argument */
1079 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2,
1080 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2,
1082 /* DUPLICATING -- copy value to all lanes */
1083 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2,
1085 /* SLICE -- produces the lowest 64 bits of (arg1:arg2) >> (8 * arg3).
1086 arg3 is a shift amount in bytes and may be between 0 and 8
1087 inclusive. When 0, the result is arg2; when 8, the result is arg1.
1088 Not all back ends handle all values. The arm32 and arm64 back
1089 ends handle only immediate arg3 values. */
1090 Iop_Slice64, // (I64, I64, I8) -> I64
1092 /* REVERSE the order of chunks in vector lanes. Chunks must be
1093 smaller than the vector lanes (obviously) and so may be 8-, 16- and
1094 32-bit in size. Note that the degenerate case,
1095 Iop_Reverse8sIn64_x1, is a simply a vanilla byte-swap. */
1096 /* Examples:
1097 Reverse8sIn16_x4([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
1098 Reverse8sIn32_x2([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]
1099 Reverse8sIn64_x1([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */
1100 Iop_Reverse8sIn16_x4,
1101 Iop_Reverse8sIn32_x2, Iop_Reverse16sIn32_x2,
1102 Iop_Reverse8sIn64_x1, Iop_Reverse16sIn64_x1, Iop_Reverse32sIn64_x1,
1104 /* PERMUTING -- copy src bytes to dst,
1105 as indexed by control vector bytes:
1106 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
1107 argR[i] values may only be in the range 0 .. 7, else behaviour
1108 is undefined. That is, argR[i][7:3] must be zero. */
1109 Iop_Perm8x8,
1111 /* PERMUTING with optional zeroing:
1112 for i in 0 .. 7 . result[i] = if argR[i] bit 7 is set
1113 then zero else argL[ argR[i] ]
1114 argR[i][6:3] must be zero, else behaviour is undefined.
1116 Iop_PermOrZero8x8,
1118 /* MISC CONVERSION -- get high bits of each byte lane, a la
1119 x86/amd64 pmovmskb */
1120 Iop_GetMSBs8x8, /* I64 -> I8 */
1122 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1123 See floating-point equivalents for details. */
1124 Iop_RecipEst32Ux2, Iop_RSqrtEst32Ux2,
1126 /* ------------------ Decimal Floating Point ------------------ */
1128 /* ARITHMETIC INSTRUCTIONS 64-bit
1129 ----------------------------------
1130 IRRoundingMode(I32) X D64 X D64 -> D64
1132 Iop_AddD64, Iop_SubD64, Iop_MulD64, Iop_DivD64,
1134 /* ARITHMETIC INSTRUCTIONS 128-bit
1135 ----------------------------------
1136 IRRoundingMode(I32) X D128 X D128 -> D128
1138 Iop_AddD128, Iop_SubD128, Iop_MulD128, Iop_DivD128,
1140 /* SHIFT SIGNIFICAND INSTRUCTIONS
1141 * The DFP significand is shifted by the number of digits specified
1142 * by the U8 operand. Digits shifted out of the leftmost digit are
1143 * lost. Zeros are supplied to the vacated positions on the right.
1144 * The sign of the result is the same as the sign of the original
1145 * operand.
1147 * D64 x U8 -> D64 left shift and right shift respectively */
1148 Iop_ShlD64, Iop_ShrD64,
1150 /* D128 x U8 -> D128 left shift and right shift respectively */
1151 Iop_ShlD128, Iop_ShrD128,
1154 /* FORMAT CONVERSION INSTRUCTIONS
1155 * D32 -> D64
1157 Iop_D32toD64,
1159 /* D64 -> D128 */
1160 Iop_D64toD128,
1162 /* I32S -> D128 */
1163 Iop_I32StoD128,
1165 /* I32U -> D128 */
1166 Iop_I32UtoD128,
1168 /* I64S -> D128 */
1169 Iop_I64StoD128,
1171 /* I64U -> D128 */
1172 Iop_I64UtoD128,
1174 /* IRRoundingMode(I32) x I128S -> D128 */
1175 Iop_I128StoD128,
1177 /* IRRoundingMode(I32) x D64 -> D32 */
1178 Iop_D64toD32,
1180 /* IRRoundingMode(I32) x D128 -> D64 */
1181 Iop_D128toD64,
1183 /* I32S -> D64 */
1184 Iop_I32StoD64,
1186 /* I32U -> D64 */
1187 Iop_I32UtoD64,
1189 /* IRRoundingMode(I32) x I64 -> D64 */
1190 Iop_I64StoD64,
1192 /* IRRoundingMode(I32) x I64 -> D64 */
1193 Iop_I64UtoD64,
1195 /* IRRoundingMode(I32) x D64 -> I32 */
1196 Iop_D64toI32S,
1198 /* IRRoundingMode(I32) x D64 -> I32 */
1199 Iop_D64toI32U,
1201 /* IRRoundingMode(I32) x D64 -> I64 */
1202 Iop_D64toI64S,
1204 /* IRRoundingMode(I32) x D64 -> I64 */
1205 Iop_D64toI64U,
1207 /* IRRoundingMode(I32) x D128 -> I32 */
1208 Iop_D128toI32S,
1210 /* IRRoundingMode(I32) x D128 -> I32 */
1211 Iop_D128toI32U,
1213 /* IRRoundingMode(I32) x D128 -> I64 */
1214 Iop_D128toI64S,
1216 /* IRRoundingMode(I32) x D128 -> I64 */
1217 Iop_D128toI64U,
1219 /* IRRoundingMode(I32) x D128 -> I128 */
1220 Iop_D128toI128S,
1222 /* IRRoundingMode(I32) x F32 -> D32 */
1223 Iop_F32toD32,
1225 /* IRRoundingMode(I32) x F32 -> D64 */
1226 Iop_F32toD64,
1228 /* IRRoundingMode(I32) x F32 -> D128 */
1229 Iop_F32toD128,
1231 /* IRRoundingMode(I32) x F64 -> D32 */
1232 Iop_F64toD32,
1234 /* IRRoundingMode(I32) x F64 -> D64 */
1235 Iop_F64toD64,
1237 /* IRRoundingMode(I32) x F64 -> D128 */
1238 Iop_F64toD128,
1240 /* IRRoundingMode(I32) x F128 -> D32 */
1241 Iop_F128toD32,
1243 /* IRRoundingMode(I32) x F128 -> D64 */
1244 Iop_F128toD64,
1246 /* IRRoundingMode(I32) x F128 -> D128 */
1247 Iop_F128toD128,
1249 /* IRRoundingMode(I32) x D32 -> F32 */
1250 Iop_D32toF32,
1252 /* IRRoundingMode(I32) x D32 -> F64 */
1253 Iop_D32toF64,
1255 /* IRRoundingMode(I32) x D32 -> F128 */
1256 Iop_D32toF128,
1258 /* IRRoundingMode(I32) x D64 -> F32 */
1259 Iop_D64toF32,
1261 /* IRRoundingMode(I32) x D64 -> F64 */
1262 Iop_D64toF64,
1264 /* IRRoundingMode(I32) x D64 -> F128 */
1265 Iop_D64toF128,
1267 /* IRRoundingMode(I32) x D128 -> F32 */
1268 Iop_D128toF32,
1270 /* IRRoundingMode(I32) x D128 -> F64 */
1271 Iop_D128toF64,
1273 /* IRRoundingMode(I32) x D128 -> F128 */
1274 Iop_D128toF128,
1276 /* ROUNDING INSTRUCTIONS
1277 * IRRoundingMode(I32) x D64 -> D64
1278 * The D64 operand, if a finite number, it is rounded to a
1279 * floating point integer value, i.e. no fractional part.
1281 Iop_RoundD64toInt,
1283 /* IRRoundingMode(I32) x D128 -> D128 */
1284 Iop_RoundD128toInt,
1286 /* COMPARE INSTRUCTIONS
1287 * D64 x D64 -> IRCmpD64Result(I32) */
1288 Iop_CmpD64,
1290 /* D128 x D128 -> IRCmpD128Result(I32) */
1291 Iop_CmpD128,
1293 /* COMPARE BIASED EXPONENET INSTRUCTIONS
1294 * D64 x D64 -> IRCmpD64Result(I32) */
1295 Iop_CmpExpD64,
1297 /* D128 x D128 -> IRCmpD128Result(I32) */
1298 Iop_CmpExpD128,
1300 /* QUANTIZE AND ROUND INSTRUCTIONS
1301 * The source operand is converted and rounded to the form with the
1302 * immediate exponent specified by the rounding and exponent parameter.
1304 * The second operand is converted and rounded to the form
1305 * of the first operand's exponent and the rounded based on the specified
1306 * rounding mode parameter.
1308 * IRRoundingMode(I32) x D64 x D64-> D64 */
1309 Iop_QuantizeD64,
1311 /* IRRoundingMode(I32) x D128 x D128 -> D128 */
1312 Iop_QuantizeD128,
1314 /* IRRoundingMode(I32) x I8 x D64 -> D64
1315 * The Decimal Floating point operand is rounded to the requested
1316 * significance given by the I8 operand as specified by the rounding
1317 * mode.
1319 Iop_SignificanceRoundD64,
1321 /* IRRoundingMode(I32) x I8 x D128 -> D128 */
1322 Iop_SignificanceRoundD128,
1324 /* EXTRACT AND INSERT INSTRUCTIONS
1325 * D64 -> I64
1326 * The exponent of the D32 or D64 operand is extracted. The
1327 * extracted exponent is converted to a 64-bit signed binary integer.
1329 Iop_ExtractExpD64,
1331 /* D128 -> I64 */
1332 Iop_ExtractExpD128,
1334 /* D64 -> I64
1335 * The number of significand digits of the D64 operand is extracted.
1336 * The number is stored as a 64-bit signed binary integer.
1338 Iop_ExtractSigD64,
1340 /* D128 -> I64 */
1341 Iop_ExtractSigD128,
1343 /* I64 x D64 -> D64
1344 * The exponent is specified by the first I64 operand the signed
1345 * significand is given by the second I64 value. The result is a D64
1346 * value consisting of the specified significand and exponent whose
1347 * sign is that of the specified significand.
1349 Iop_InsertExpD64,
1351 /* I64 x D128 -> D128 */
1352 Iop_InsertExpD128,
1354 /* Support for 128-bit DFP type */
1355 Iop_D64HLtoD128, Iop_D128HItoD64, Iop_D128LOtoD64,
1357 /* I64 -> I64
1358 * Convert 50-bit densely packed BCD string to 60 bit BCD string
1360 Iop_DPBtoBCD,
1362 /* I64 -> I64
1363 * Convert 60 bit BCD string to 50-bit densely packed BCD string
1365 Iop_BCDtoDPB,
1367 /* BCD arithmetic instructions, (V128, V128) -> V128
1368 * The BCD format is the same as that used in the BCD<->DPB conversion
1369 * routines, except using 124 digits (vs 60) plus the trailing 4-bit
1370 * signed code. */
1371 Iop_BCDAdd, Iop_BCDSub,
1373 /* Conversion signed 128-bit integer to signed BCD 128-bit */
1374 Iop_I128StoBCD128,
1376 /* Conversion signed BCD 128-bit to 128-bit integer */
1377 Iop_BCD128toI128S,
1379 /* Conversion I64 -> D64 */
1380 Iop_ReinterpI64asD64,
1382 /* Conversion D64 -> I64 */
1383 Iop_ReinterpD64asI64,
1385 /* ------------------ 128-bit SIMD FP. ------------------ */
1387 /* --- 16x8 vector FP --- */
1389 /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1390 Iop_Sqrt16Fx8,
1392 /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1393 Iop_Add16Fx8, Iop_Sub16Fx8,
1395 /* binary */
1396 Iop_CmpLT16Fx8, Iop_CmpLE16Fx8, Iop_CmpEQ16Fx8,
1398 /* unary */
1399 Iop_Abs16Fx8,
1400 Iop_Neg16Fx8,
1402 /* --- 32x4 vector FP --- */
1404 /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1405 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
1407 /* binary */
1408 Iop_Max32Fx4, Iop_Min32Fx4,
1409 Iop_Add32Fx2, Iop_Sub32Fx2,
1410 /* Note: For the following compares, the ppc and arm front-ends assume a
1411 nan in a lane of either argument returns zero for that lane. */
1412 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
1413 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
1415 /* Pairwise Max and Min. See integer pairwise operations for details. */
1416 Iop_PwMax32Fx4, Iop_PwMin32Fx4,
1418 /* unary */
1419 Iop_Abs32Fx4,
1420 Iop_Neg32Fx4,
1422 /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1423 Iop_Sqrt32Fx4,
1425 /* Vector Reciprocal Estimate finds an approximate reciprocal of each
1426 element in the operand vector, and places the results in the
1427 destination vector. */
1428 Iop_RecipEst32Fx4,
1430 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2).
1431 Note, that if one of the arguments is zero and another one is infinity
1432 of arbitrary sign the result of the operation is 2.0. */
1433 Iop_RecipStep32Fx4,
1435 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal
1436 square root of each element in the operand vector. */
1437 Iop_RSqrtEst32Fx4,
1439 /* Scaling of vector with a power of 2 (wd[i] <- ws[i] * 2^wt[i]) */
1440 Iop_Scale2_32Fx4,
1442 /* Vector floating-point base 2 logarithm */
1443 Iop_Log2_32Fx4,
1445 /* Vector floating-point exponential 2^x */
1446 Iop_Exp2_32Fx4,
1448 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0.
1449 Note, that of one of the arguments is zero and another one is infiinty
1450 of arbitrary sign the result of the operation is 1.5. */
1451 Iop_RSqrtStep32Fx4,
1453 /* --- Int to/from FP conversion --- */
1454 /* Unlike the standard fp conversions, these irops take no
1455 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
1456 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
1458 // These carry no rounding mode and are therefore deprecated
1459 Iop_I32UtoF32x4_DEP, Iop_I32StoF32x4_DEP, /* I32x4 -> F32x4 */
1461 Iop_I32StoF32x4, /* IRRoundingMode(I32) x V128 -> V128 */
1462 Iop_F32toI32Sx4, /* IRRoundingMode(I32) x V128 -> V128 */
1464 Iop_F32toI32Ux4_RZ, Iop_F32toI32Sx4_RZ, /* F32x4 -> I32x4 */
1465 Iop_QF32toI32Ux4_RZ, Iop_QF32toI32Sx4_RZ, /* F32x4 -> I32x4 (saturating) */
1466 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
1467 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
1468 /* Fixed32 format is floating-point number with fixed number of fraction
1469 bits. The number of fraction bits is passed as a second argument of
1470 type I8. */
1471 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */
1472 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */
1474 /* --- Single to/from half conversion --- */
1475 /* FIXME: what kind of rounding in F32x4 -> F16x4 case? */
1476 // FIXME these carry no rounding mode
1477 Iop_F32toF16x4_DEP, /* F32x4(==V128) -> F16x4(==I64), NO ROUNDING MODE */
1478 Iop_F32toF16x4, /* IRRoundingMode(I32) x V128 -> I64 */
1479 Iop_F16toF32x4, /* F16x4 -> F32x4 */
1481 /* -- Double to/from half conversion -- */
1482 Iop_F64toF16x2_DEP, // F64x2 -> F16x2, NO ROUNDING MODE
1483 Iop_F16toF64x2,
1485 /* Values from two registers converted in smaller type and put in one
1486 IRRoundingMode(I32) x (F32x4 | F32x4) -> Q16x8 */
1487 Iop_F32x4_2toQ16x8,
1490 /* --- 32x4 lowest-lane-only scalar FP --- */
1492 /* In binary cases, upper 3/4 is copied from first operand. In
1493 unary cases, upper 3/4 is copied from the operand. */
1495 /* binary */
1496 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
1497 Iop_Max32F0x4, Iop_Min32F0x4,
1498 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
1500 /* unary */
1501 Iop_RecipEst32F0x4, Iop_Sqrt32F0x4, Iop_RSqrtEst32F0x4,
1503 /* --- 64x2 vector FP --- */
1505 /* ternary :: IRRoundingMode(I32) x V128 x V128 -> V128 */
1506 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
1508 /* binary */
1509 Iop_Max64Fx2, Iop_Min64Fx2,
1510 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
1512 /* unary */
1513 Iop_Abs64Fx2,
1514 Iop_Neg64Fx2,
1516 /* binary :: IRRoundingMode(I32) x V128 -> V128 */
1517 Iop_Sqrt64Fx2,
1519 /* Scaling of vector with a power of 2 (wd[i] <- ws[i] * 2^wt[i]) */
1520 Iop_Scale2_64Fx2,
1522 /* Vector floating-point base 2 logarithm */
1523 Iop_Log2_64Fx2,
1525 /* see 32Fx4 variants for description */
1526 Iop_RecipEst64Fx2, // unary
1527 Iop_RecipStep64Fx2, // binary
1528 Iop_RSqrtEst64Fx2, // unary
1529 Iop_RSqrtStep64Fx2, // binary
1532 /* Values from two registers converted in smaller type and put in one
1533 IRRoundingMode(I32) x (F64x2 | F64x2) -> Q32x4 */
1534 Iop_F64x2_2toQ32x4,
1536 /* --- 64x2 lowest-lane-only scalar FP --- */
1538 /* In binary cases, upper half is copied from first operand. In
1539 unary cases, upper half is copied from the operand. */
1541 /* binary */
1542 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
1543 Iop_Max64F0x2, Iop_Min64F0x2,
1544 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
1546 /* unary */
1547 Iop_Sqrt64F0x2,
1549 /* --- pack / unpack --- */
1551 /* 64 <-> 128 bit vector */
1552 Iop_V128to64, // :: V128 -> I64, low half
1553 Iop_V128HIto64, // :: V128 -> I64, high half
1554 Iop_64HLtoV128, // :: (I64,I64) -> V128
1556 Iop_64UtoV128,
1557 Iop_SetV128lo64,
1559 /* Copies lower 64/32/16/8 bits, zeroes out the rest. */
1560 Iop_ZeroHI64ofV128, // :: V128 -> V128
1561 Iop_ZeroHI96ofV128, // :: V128 -> V128
1562 Iop_ZeroHI112ofV128, // :: V128 -> V128
1563 Iop_ZeroHI120ofV128, // :: V128 -> V128
1565 /* 32 <-> 128 bit vector */
1566 Iop_32UtoV128,
1567 Iop_V128to32, // :: V128 -> I32, lowest lane
1568 Iop_SetV128lo32, // :: (V128,I32) -> V128
1570 /* ------------------ 128-bit SIMD Integer. ------------------ */
1572 /* BITWISE OPS */
1573 Iop_NotV128,
1574 Iop_AndV128, Iop_OrV128, Iop_XorV128,
1576 /* VECTOR SHIFT (shift amt :: Ity_I8) */
1577 Iop_ShlV128, Iop_ShrV128, Iop_SarV128,
1579 /* MISC (vector integer cmp != 0) */
1580 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
1581 Iop_CmpNEZ128x1,
1583 /* ADDITION (normal / U->U sat / S->S sat) */
1584 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2, Iop_Add128x1,
1585 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2,
1586 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2,
1588 /* ADDITION, ARM64 specific saturating variants. */
1589 /* Unsigned widen left arg, signed widen right arg, add, saturate S->S.
1590 This corresponds to SUQADD. */
1591 Iop_QAddExtUSsatSS8x16, Iop_QAddExtUSsatSS16x8,
1592 Iop_QAddExtUSsatSS32x4, Iop_QAddExtUSsatSS64x2,
1593 /* Signed widen left arg, unsigned widen right arg, add, saturate U->U.
1594 This corresponds to USQADD. */
1595 Iop_QAddExtSUsatUU8x16, Iop_QAddExtSUsatUU16x8,
1596 Iop_QAddExtSUsatUU32x4, Iop_QAddExtSUsatUU64x2,
1598 /* SUBTRACTION (normal / unsigned sat / signed sat) */
1599 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2, Iop_Sub128x1,
1600 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2,
1601 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2,
1603 /* MULTIPLICATION (normal / high half of signed/unsigned) */
1604 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4,
1605 Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4,
1606 Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4,
1607 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
1608 Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4,
1609 Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4,
1611 /* Widening multiplies, all of the form (I64, I64) -> V128 */
1612 Iop_Mull8Ux8, Iop_Mull8Sx8,
1613 Iop_Mull16Ux4, Iop_Mull16Sx4,
1614 Iop_Mull32Ux2, Iop_Mull32Sx2,
1616 /* Signed doubling saturating widening multiplies, (I64, I64) -> V128 */
1617 Iop_QDMull16Sx4, Iop_QDMull32Sx2,
1619 /* Vector Saturating Doubling Multiply Returning High Half and
1620 Vector Saturating Rounding Doubling Multiply Returning High Half.
1621 These IROps multiply corresponding elements in two vectors, double
1622 the results, and place the most significant half of the final results
1623 in the destination vector. The results are truncated or rounded. If
1624 any of the results overflow, they are saturated. To be more precise,
1625 for each lane, the computed result is:
1626 QDMulHi:
1627 hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2 )
1628 QRDMulHi:
1629 hi-half( sign-extend(laneL) *q sign-extend(laneR) *q 2
1630 +q (1 << (lane-width-in-bits - 1)) )
1632 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4, /* (V128, V128) -> V128 */
1633 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, /* (V128, V128) -> V128 */
1635 /* Polynomial multiplication treats its arguments as
1636 coefficients of polynomials over {0, 1}. */
1637 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */
1638 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */
1640 /* Vector Polynomial multiplication add. (V128, V128) -> V128
1642 *** Below is the algorithm for the instructions. These Iops could
1643 be emulated to get this functionality, but the emulation would
1644 be long and messy.
1646 Example for polynomial multiply add for vector of bytes
1647 do i = 0 to 15
1648 prod[i].bit[0:14] <- 0
1649 srcA <- VR[argL].byte[i]
1650 srcB <- VR[argR].byte[i]
1651 do j = 0 to 7
1652 do k = 0 to j
1653 gbit <- srcA.bit[k] & srcB.bit[j-k]
1654 prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1658 do j = 8 to 14
1659 do k = j-7 to 7
1660 gbit <- (srcA.bit[k] & srcB.bit[j-k])
1661 prod[i].bit[j] <- prod[i].bit[j] ^ gbit
1666 do i = 0 to 7
1667 VR[dst].hword[i] <- 0b0 || (prod[2×i] ^ prod[2×i+1])
1670 Iop_PolynomialMulAdd8x16, Iop_PolynomialMulAdd16x8,
1671 Iop_PolynomialMulAdd32x4, Iop_PolynomialMulAdd64x2,
1673 /* PAIRWISE operations */
1674 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) =
1675 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */
1676 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4,
1677 Iop_PwAdd32Fx2,
1679 /* Longening variant is unary. The resulting vector contains two times
1680 less elements than operand, but they are two times wider.
1681 Example:
1682 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d]
1683 where a+b and c+d are unsigned 32-bit values. */
1684 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4, Iop_PwAddL64Ux2,
1685 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4,
1687 /* This is amd64 PMADDUBSW, (V128, V128) -> V128. For each adjacent pair
1688 of bytes [a,b] in the first arg and [c,d] in the second, computes:
1689 signed/signed sat to 16 bits ( zxTo16(a) * sxTo16(b)
1690 + zxTo16(c) * sxTo16(d) )
1691 This exists because it's frequently used and there's no reasonably
1692 concise way to express it using other IROps.
1694 Iop_PwExtUSMulQAdd8x16,
1696 /* Other unary pairwise ops */
1698 /* Vector bit matrix transpose. (V128) -> V128 */
1699 /* For each doubleword element of the source vector, an 8-bit x 8-bit
1700 * matrix transpose is performed. */
1701 Iop_PwBitMtxXpose64x2,
1703 /* ABSOLUTE VALUE */
1704 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2,
1706 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
1707 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2,
1708 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2,
1710 /* MIN/MAX */
1711 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2,
1712 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2,
1713 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2,
1714 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2,
1716 /* COMPARISON */
1717 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, Iop_CmpEQ64x2,
1718 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2,
1719 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, Iop_CmpGT64Ux2,
1721 /* COUNT ones / leading zeroes / leading sign bits (not including topmost
1722 bit) */
1723 Iop_Cnt8x16,
1724 Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4,
1725 Iop_Cls8x16, Iop_Cls16x8, Iop_Cls32x4,
1727 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
1728 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
1729 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
1730 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2,
1732 /* VECTOR x VECTOR SHIFT / ROTATE */
1733 /* FIXME: I'm pretty sure the ARM32 front/back ends interpret these
1734 differently from all other targets. The intention is that
1735 the shift amount (2nd arg) is interpreted as unsigned and
1736 only the lowest log2(lane-bits) bits are relevant. But the
1737 ARM32 versions treat the shift amount as an 8 bit signed
1738 number. The ARM32 uses should be replaced by the relevant
1739 vector x vector bidirectional shifts instead. */
1740 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2,
1741 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2,
1742 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2,
1743 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2,
1744 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2,
1746 /* VECTOR x VECTOR SATURATING SHIFT */
1747 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2,
1748 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2,
1749 /* VECTOR x INTEGER SATURATING SHIFT */
1750 Iop_QShlNsatSU8x16, Iop_QShlNsatSU16x8,
1751 Iop_QShlNsatSU32x4, Iop_QShlNsatSU64x2,
1752 Iop_QShlNsatUU8x16, Iop_QShlNsatUU16x8,
1753 Iop_QShlNsatUU32x4, Iop_QShlNsatUU64x2,
1754 Iop_QShlNsatSS8x16, Iop_QShlNsatSS16x8,
1755 Iop_QShlNsatSS32x4, Iop_QShlNsatSS64x2,
1757 /* VECTOR x VECTOR BIDIRECTIONAL SATURATING (& MAYBE ROUNDING) SHIFT */
1758 /* All of type (V128, V128) -> V256. */
1759 /* The least significant 8 bits of each lane of the second
1760 operand are used as the shift amount, and interpreted signedly.
1761 Positive values mean a shift left, negative a shift right. The
1762 result is signedly or unsignedly saturated. There are also
1763 rounding variants, which add 2^(shift_amount-1) to the value before
1764 shifting, but only in the shift-right case. Vacated positions
1765 are filled with zeroes. IOW, it's either SHR or SHL, but not SAR.
1767 These operations return 129 bits: one bit ("Q") indicating whether
1768 saturation occurred, and the shift result. The result type is V256,
1769 of which the lower V128 is the shift result, and Q occupies the
1770 least significant bit of the upper V128. All other bits of the
1771 upper V128 are zero. */
1772 // Unsigned saturation, no rounding
1773 Iop_QandUQsh8x16, Iop_QandUQsh16x8,
1774 Iop_QandUQsh32x4, Iop_QandUQsh64x2,
1775 // Signed saturation, no rounding
1776 Iop_QandSQsh8x16, Iop_QandSQsh16x8,
1777 Iop_QandSQsh32x4, Iop_QandSQsh64x2,
1779 // Unsigned saturation, rounding
1780 Iop_QandUQRsh8x16, Iop_QandUQRsh16x8,
1781 Iop_QandUQRsh32x4, Iop_QandUQRsh64x2,
1782 // Signed saturation, rounding
1783 Iop_QandSQRsh8x16, Iop_QandSQRsh16x8,
1784 Iop_QandSQRsh32x4, Iop_QandSQRsh64x2,
1786 /* VECTOR x VECTOR BIDIRECTIONAL (& MAYBE ROUNDING) SHIFT */
1787 /* All of type (V128, V128) -> V128 */
1788 /* The least significant 8 bits of each lane of the second
1789 operand are used as the shift amount, and interpreted signedly.
1790 Positive values mean a shift left, negative a shift right.
1791 There are also rounding variants, which add 2^(shift_amount-1)
1792 to the value before shifting, but only in the shift-right case.
1794 For left shifts, the vacated places are filled with zeroes.
1795 For right shifts, the vacated places are filled with zeroes
1796 for the U variants and sign bits for the S variants. */
1797 // Signed and unsigned, non-rounding
1798 Iop_Sh8Sx16, Iop_Sh16Sx8, Iop_Sh32Sx4, Iop_Sh64Sx2,
1799 Iop_Sh8Ux16, Iop_Sh16Ux8, Iop_Sh32Ux4, Iop_Sh64Ux2,
1801 // Signed and unsigned, rounding
1802 Iop_Rsh8Sx16, Iop_Rsh16Sx8, Iop_Rsh32Sx4, Iop_Rsh64Sx2,
1803 Iop_Rsh8Ux16, Iop_Rsh16Ux8, Iop_Rsh32Ux4, Iop_Rsh64Ux2,
1805 /* The least significant 8 bits of each lane of the second
1806 operand are used as the shift amount, and interpreted signedly.
1807 Positive values mean a shift left, negative a shift right. The
1808 result is signedly or unsignedly saturated. There are also
1809 rounding variants, which add 2^(shift_amount-1) to the value before
1810 shifting, but only in the shift-right case. Vacated positions
1811 are filled with zeroes. IOW, it's either SHR or SHL, but not SAR.
1814 /* VECTOR x SCALAR SATURATING (& MAYBE ROUNDING) NARROWING SHIFT RIGHT */
1815 /* All of type (V128, I8) -> V128 */
1816 /* The first argument is shifted right, then narrowed to half the width
1817 by saturating it. The second argument is a scalar shift amount that
1818 applies to all lanes, and must be a value in the range 1 to lane_width.
1819 The shift may be done signedly (Sar variants) or unsignedly (Shr
1820 variants). The saturation is done according to the two signedness
1821 indicators at the end of the name. For example 64Sto32U means a
1822 signed 64 bit value is saturated into an unsigned 32 bit value.
1823 Additionally, the QRS variants do rounding, that is, they add the
1824 value (1 << (shift_amount-1)) to each source lane before shifting.
1826 These operations return 65 bits: one bit ("Q") indicating whether
1827 saturation occurred, and the shift result. The result type is V128,
1828 of which the lower half is the shift result, and Q occupies the
1829 least significant bit of the upper half. All other bits of the
1830 upper half are zero. */
1831 // No rounding, sat U->U
1832 Iop_QandQShrNnarrow16Uto8Ux8,
1833 Iop_QandQShrNnarrow32Uto16Ux4, Iop_QandQShrNnarrow64Uto32Ux2,
1834 // No rounding, sat S->S
1835 Iop_QandQSarNnarrow16Sto8Sx8,
1836 Iop_QandQSarNnarrow32Sto16Sx4, Iop_QandQSarNnarrow64Sto32Sx2,
1837 // No rounding, sat S->U
1838 Iop_QandQSarNnarrow16Sto8Ux8,
1839 Iop_QandQSarNnarrow32Sto16Ux4, Iop_QandQSarNnarrow64Sto32Ux2,
1841 // Rounding, sat U->U
1842 Iop_QandQRShrNnarrow16Uto8Ux8,
1843 Iop_QandQRShrNnarrow32Uto16Ux4, Iop_QandQRShrNnarrow64Uto32Ux2,
1844 // Rounding, sat S->S
1845 Iop_QandQRSarNnarrow16Sto8Sx8,
1846 Iop_QandQRSarNnarrow32Sto16Sx4, Iop_QandQRSarNnarrow64Sto32Sx2,
1847 // Rounding, sat S->U
1848 Iop_QandQRSarNnarrow16Sto8Ux8,
1849 Iop_QandQRSarNnarrow32Sto16Ux4, Iop_QandQRSarNnarrow64Sto32Ux2,
1851 /* NARROWING (binary)
1852 -- narrow 2xV128 into 1xV128, hi half from left arg */
1853 /* See comments above w.r.t. U vs S issues in saturated narrowing. */
1854 Iop_QNarrowBin16Sto8Ux16, Iop_QNarrowBin32Sto16Ux8,
1855 Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
1856 Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
1857 Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
1858 Iop_QNarrowBin64Sto32Sx4, Iop_QNarrowBin64Uto32Ux4,
1859 Iop_NarrowBin64to32x4,
1861 /* NARROWING (unary) -- narrow V128 into I64 */
1862 Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2,
1863 /* Saturating narrowing from signed source to signed/unsigned
1864 destination */
1865 Iop_QNarrowUn16Sto8Sx8, Iop_QNarrowUn32Sto16Sx4, Iop_QNarrowUn64Sto32Sx2,
1866 Iop_QNarrowUn16Sto8Ux8, Iop_QNarrowUn32Sto16Ux4, Iop_QNarrowUn64Sto32Ux2,
1867 /* Saturating narrowing from unsigned source to unsigned destination */
1868 Iop_QNarrowUn16Uto8Ux8, Iop_QNarrowUn32Uto16Ux4, Iop_QNarrowUn64Uto32Ux2,
1870 /* WIDENING -- sign or zero extend each element of the argument
1871 vector to the twice original size. The resulting vector consists of
1872 the same number of elements but each element and the vector itself
1873 are twice as wide.
1874 All operations are I64->V128.
1875 Example
1876 Iop_Widen32Sto64x2( [a, b] ) = [c, d]
1877 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */
1878 Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2,
1879 Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2,
1881 /* INTERLEAVING */
1882 /* Interleave lanes from low or high halves of
1883 operands. Most-significant result lane is from the left
1884 arg. */
1885 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
1886 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
1887 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
1888 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
1889 /* Interleave odd/even lanes of operands. Most-significant result lane
1890 is from the left arg. */
1891 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16,
1892 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8,
1893 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4,
1895 /* Pack even/odd lanes. */
1896 Iop_PackOddLanes8x16, Iop_PackEvenLanes8x16,
1897 Iop_PackOddLanes16x8, Iop_PackEvenLanes16x8,
1898 Iop_PackOddLanes32x4, Iop_PackEvenLanes32x4,
1900 /* CONCATENATION -- build a new value by concatenating either
1901 the even or odd lanes of both operands. Note that
1902 Cat{Odd,Even}Lanes64x2 are identical to Interleave{HI,LO}64x2
1903 and so are omitted. */
1904 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4,
1905 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4,
1907 /* GET elements of VECTOR
1908 GET is binop (V128, I8) -> I<elem_size>
1909 SET is triop (V128, I8, I<elem_size>) -> V128 */
1910 /* Note: the arm back-end handles only constant second argument. */
1911 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2,
1912 Iop_SetElem8x16, Iop_SetElem16x8, Iop_SetElem32x4, Iop_SetElem64x2,
1914 /* DUPLICATING -- copy value to all lanes */
1915 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
1917 /* SLICE -- produces the lowest 128 bits of (arg1:arg2) >> (8 * arg3).
1918 arg3 is a shift amount in bytes and may be between 0 and 16
1919 inclusive. When 0, the result is arg2; when 16, the result is arg1.
1920 Not all back ends handle all values. The arm64 back
1921 end handles only immediate arg3 values. */
1922 Iop_SliceV128, // (V128, V128, I8) -> V128
1924 /* REVERSE the order of chunks in vector lanes. Chunks must be
1925 smaller than the vector lanes (obviously) and so may be 8-,
1926 16- and 32-bit in size. See definitions of 64-bit SIMD
1927 versions above for examples. */
1928 Iop_Reverse8sIn16_x8,
1929 Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
1930 Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
1931 Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
1933 /* PERMUTING -- copy src bytes to dst,
1934 as indexed by control vector bytes:
1935 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
1936 argR[i] values may only be in the range 0 .. 15, else behaviour
1937 is undefined. That is, argR[i][7:4] must be zero. */
1938 Iop_Perm8x16,
1939 Iop_Perm32x4, /* ditto, except argR values are restricted to 0 .. 3 */
1941 /* PERMUTING with optional zeroing:
1942 for i in 0 .. 15 . result[i] = if argR[i] bit 7 is set
1943 then zero else argL[ argR[i] ]
1944 argR[i][6:4] must be zero, else behaviour is undefined.
1946 Iop_PermOrZero8x16,
1948 /* same, but Triop (argL consists of two 128-bit parts) */
1949 /* correct range for argR values is 0..31 */
1950 /* (V128, V128, V128) -> V128 */
1951 /* (ArgL_first, ArgL_second, ArgR) -> result */
1952 Iop_Perm8x16x2,
1954 /* MISC CONVERSION -- get high bits of each byte lane, a la
1955 x86/amd64 pmovmskb */
1956 Iop_GetMSBs8x16, /* V128 -> I16 */
1958 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate
1959 See floating-point equivalents for details. */
1960 Iop_RecipEst32Ux4, Iop_RSqrtEst32Ux4,
1962 /* 128-bit multipy by 10 instruction, result is lower 128-bits */
1963 Iop_MulI128by10,
1965 /* 128-bit multipy by 10 instruction, result is carry out from the MSB */
1966 Iop_MulI128by10Carry,
1968 /* 128-bit multipy by 10 instruction, result is lower 128-bits of the
1969 * source times 10 plus the carry in
1971 Iop_MulI128by10E,
1973 /* 128-bit multipy by 10 instruction, result is carry out from the MSB
1974 * of the source times 10 plus the carry in
1976 Iop_MulI128by10ECarry,
1978 /* 128-bit carry out from ((U64 * U64 -> U128) + (U64 * U64 -> U128)) */
1979 Iop_2xMultU64Add128CarryOut,
1981 /* ------------------ 256-bit SIMD Integer. ------------------ */
1983 /* Pack/unpack */
1984 Iop_V256to64_0, // V256 -> I64, extract least significant lane
1985 Iop_V256to64_1,
1986 Iop_V256to64_2,
1987 Iop_V256to64_3, // V256 -> I64, extract most significant lane
1989 Iop_64x4toV256, // (I64,I64,I64,I64)->V256
1990 // first arg is most significant lane
1992 Iop_V256toV128_0, // V256 -> V128, less significant lane
1993 Iop_V256toV128_1, // V256 -> V128, more significant lane
1994 Iop_V128HLtoV256, // (V128,V128)->V256, first arg is most signif
1996 Iop_AndV256,
1997 Iop_OrV256,
1998 Iop_XorV256,
1999 Iop_NotV256,
2001 /* MISC (vector integer cmp != 0) */
2002 Iop_CmpNEZ8x32, Iop_CmpNEZ16x16, Iop_CmpNEZ32x8, Iop_CmpNEZ64x4,
2004 Iop_Add8x32, Iop_Add16x16, Iop_Add32x8, Iop_Add64x4,
2005 Iop_Sub8x32, Iop_Sub16x16, Iop_Sub32x8, Iop_Sub64x4,
2007 Iop_CmpEQ8x32, Iop_CmpEQ16x16, Iop_CmpEQ32x8, Iop_CmpEQ64x4,
2008 Iop_CmpGT8Sx32, Iop_CmpGT16Sx16, Iop_CmpGT32Sx8, Iop_CmpGT64Sx4,
2010 Iop_ShlN16x16, Iop_ShlN32x8, Iop_ShlN64x4,
2011 Iop_ShrN16x16, Iop_ShrN32x8, Iop_ShrN64x4,
2012 Iop_SarN16x16, Iop_SarN32x8,
2014 Iop_Max8Sx32, Iop_Max16Sx16, Iop_Max32Sx8,
2015 Iop_Max8Ux32, Iop_Max16Ux16, Iop_Max32Ux8,
2016 Iop_Min8Sx32, Iop_Min16Sx16, Iop_Min32Sx8,
2017 Iop_Min8Ux32, Iop_Min16Ux16, Iop_Min32Ux8,
2019 Iop_Mul16x16, Iop_Mul32x8,
2020 Iop_MulHi16Ux16, Iop_MulHi16Sx16,
2022 Iop_QAdd8Ux32, Iop_QAdd16Ux16,
2023 Iop_QAdd8Sx32, Iop_QAdd16Sx16,
2024 Iop_QSub8Ux32, Iop_QSub16Ux16,
2025 Iop_QSub8Sx32, Iop_QSub16Sx16,
2027 Iop_Avg8Ux32, Iop_Avg16Ux16,
2029 Iop_Perm32x8,
2031 /* (V128, V128) -> V128 */
2032 Iop_CipherV128, Iop_CipherLV128, Iop_CipherSV128,
2033 Iop_NCipherV128, Iop_NCipherLV128,
2035 /* Hash instructions, Federal Information Processing Standards
2036 * Publication 180-3 Secure Hash Standard. */
2037 /* (V128, I8) -> V128; The I8 input arg is (ST | SIX), where ST and
2038 * SIX are fields from the insn. See ISA 2.07 description of
2039 * vshasigmad and vshasigmaw insns.*/
2040 Iop_SHA512, Iop_SHA256,
2042 /* ------------------ 256-bit SIMD FP. ------------------ */
2044 /* ternary :: IRRoundingMode(I32) x V256 x V256 -> V256 */
2045 Iop_Add64Fx4, Iop_Sub64Fx4, Iop_Mul64Fx4, Iop_Div64Fx4,
2046 Iop_Add32Fx8, Iop_Sub32Fx8, Iop_Mul32Fx8, Iop_Div32Fx8,
2048 Iop_I32StoF32x8, /* IRRoundingMode(I32) x V256 -> V256 */
2049 Iop_F32toI32Sx8, /* IRRoundingMode(I32) x V256 -> V256 */
2051 Iop_F32toF16x8, /* IRRoundingMode(I32) x V256 -> V128 */
2052 Iop_F16toF32x8, /* F16x8(==V128) -> F32x8(==V256) */
2054 Iop_Sqrt32Fx8,
2055 Iop_Sqrt64Fx4,
2056 Iop_RSqrtEst32Fx8,
2057 Iop_RecipEst32Fx8,
2059 Iop_Max32Fx8, Iop_Min32Fx8,
2060 Iop_Max64Fx4, Iop_Min64Fx4,
2061 Iop_Rotx32, Iop_Rotx64,
2062 Iop_LAST /* must be the last enumerator */
2064 IROp;
2066 /* Pretty-print an op. */
2067 extern void ppIROp ( IROp );
2069 /* For a given operand return the types of its arguments and its result. */
2070 extern void typeOfPrimop ( IROp op,
2071 /*OUTs*/ IRType* t_dst, IRType* t_arg1,
2072 IRType* t_arg2, IRType* t_arg3, IRType* t_arg4 );
2074 /* Might the given primop trap (eg, attempt integer division by zero)? If in
2075 doubt returns True. However, the vast majority of primops will never
2076 trap. */
2077 extern Bool primopMightTrap ( IROp op );
2079 /* Encoding of IEEE754-specified rounding modes.
2080 Note, various front and back ends rely on the actual numerical
2081 values of these, so do not change them. */
2082 typedef
2083 enum {
2084 Irrm_NEAREST = 0, // Round to nearest, ties to even
2085 Irrm_NegINF = 1, // Round to negative infinity
2086 Irrm_PosINF = 2, // Round to positive infinity
2087 Irrm_ZERO = 3, // Round toward zero
2088 Irrm_NEAREST_TIE_AWAY_0 = 4, // Round to nearest, ties away from 0
2089 Irrm_PREPARE_SHORTER = 5, // Round to prepare for shorter
2090 // precision
2091 Irrm_AWAY_FROM_ZERO = 6, // Round to away from 0
2092 Irrm_NEAREST_TIE_TOWARD_0 = 7 // Round to nearest, ties towards 0
2094 IRRoundingMode;
2096 /* Binary floating point comparison result values.
2097 This is also derived from what IA32 does. */
2098 typedef
2099 enum {
2100 Ircr_UN = 0x45,
2101 Ircr_LT = 0x01,
2102 Ircr_GT = 0x00,
2103 Ircr_EQ = 0x40
2105 IRCmpFResult;
2107 typedef IRCmpFResult IRCmpF32Result;
2108 typedef IRCmpFResult IRCmpF64Result;
2109 typedef IRCmpFResult IRCmpF128Result;
2111 /* Decimal floating point result values. */
2112 typedef IRCmpFResult IRCmpDResult;
2113 typedef IRCmpDResult IRCmpD64Result;
2114 typedef IRCmpDResult IRCmpD128Result;
2116 /* ------------------ Expressions ------------------ */
2118 typedef struct _IRQop IRQop; /* forward declaration */
2119 typedef struct _IRTriop IRTriop; /* forward declaration */
2122 /* The different kinds of expressions. Their meaning is explained below
2123 in the comments for IRExpr. */
2124 typedef
2125 enum {
2126 Iex_Binder=0x1900,
2127 Iex_Get,
2128 Iex_GetI,
2129 Iex_RdTmp,
2130 Iex_Qop,
2131 Iex_Triop,
2132 Iex_Binop,
2133 Iex_Unop,
2134 Iex_Load,
2135 Iex_Const,
2136 Iex_ITE,
2137 Iex_CCall,
2138 Iex_VECRET,
2139 Iex_GSPTR
2141 IRExprTag;
2143 /* An expression. Stored as a tagged union. 'tag' indicates what kind
2144 of expression this is. 'Iex' is the union that holds the fields. If
2145 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
2146 expression, and the fields can be accessed with
2147 'e.Iex.Load.<fieldname>'.
2149 For each kind of expression, we show what it looks like when
2150 pretty-printed with ppIRExpr().
2152 typedef
2153 struct _IRExpr
2154 IRExpr;
2156 struct _IRExpr {
2157 IRExprTag tag;
2158 union {
2159 /* Used only in pattern matching within Vex. Should not be seen
2160 outside of Vex. */
2161 struct {
2162 Int binder;
2163 } Binder;
2165 /* Read a guest register, at a fixed offset in the guest state.
2166 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
2168 struct {
2169 Int offset; /* Offset into the guest state */
2170 IRType ty; /* Type of the value being read */
2171 } Get;
2173 /* Read a guest register at a non-fixed offset in the guest
2174 state. This allows circular indexing into parts of the guest
2175 state, which is essential for modelling situations where the
2176 identity of guest registers is not known until run time. One
2177 example is the x87 FP register stack.
2179 The part of the guest state to be treated as a circular array
2180 is described in the IRRegArray 'descr' field. It holds the
2181 offset of the first element in the array, the type of each
2182 element, and the number of elements.
2184 The array index is indicated rather indirectly, in a way
2185 which makes optimisation easy: as the sum of variable part
2186 (the 'ix' field) and a constant offset (the 'bias' field).
2188 Since the indexing is circular, the actual array index to use
2189 is computed as (ix + bias) % num-of-elems-in-the-array.
2191 Here's an example. The description
2193 (96:8xF64)[t39,-7]
2195 describes an array of 8 F64-typed values, the
2196 guest-state-offset of the first being 96. This array is
2197 being indexed at (t39 - 7) % 8.
2199 It is important to get the array size/type exactly correct
2200 since IR optimisation looks closely at such info in order to
2201 establish aliasing/non-aliasing between seperate GetI and
2202 PutI events, which is used to establish when they can be
2203 reordered, etc. Putting incorrect info in will lead to
2204 obscure IR optimisation bugs.
2206 ppIRExpr output: GETI<descr>[<ix>,<bias]
2207 eg. GETI(128:8xI8)[t1,0]
2209 struct {
2210 IRRegArray* descr; /* Part of guest state treated as circular */
2211 IRExpr* ix; /* Variable part of index into array */
2212 Int bias; /* Constant offset part of index into array */
2213 } GetI;
2215 /* The value held by a temporary.
2216 ppIRExpr output: t<tmp>, eg. t1
2218 struct {
2219 IRTemp tmp; /* The temporary number */
2220 } RdTmp;
2222 /* A quaternary operation.
2223 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
2224 eg. MAddF64r32(t1, t2, t3, t4)
2226 struct {
2227 IRQop* details;
2228 } Qop;
2230 /* A ternary operation.
2231 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
2232 eg. MulF64(1, 2.0, 3.0)
2234 struct {
2235 IRTriop* details;
2236 } Triop;
2238 /* A binary operation.
2239 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
2241 struct {
2242 IROp op; /* op-code */
2243 IRExpr* arg1; /* operand 1 */
2244 IRExpr* arg2; /* operand 2 */
2245 } Binop;
2247 /* A unary operation.
2248 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
2250 struct {
2251 IROp op; /* op-code */
2252 IRExpr* arg; /* operand */
2253 } Unop;
2255 /* A load from memory -- a normal load, not a load-linked.
2256 Load-Linkeds (and Store-Conditionals) are instead represented
2257 by IRStmt.LLSC since Load-Linkeds have side effects and so
2258 are not semantically valid IRExpr's.
2259 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
2261 struct {
2262 IREndness end; /* Endian-ness of the load */
2263 IRType ty; /* Type of the loaded value */
2264 IRExpr* addr; /* Address being loaded from */
2265 } Load;
2267 /* A constant-valued expression.
2268 ppIRExpr output: <con>, eg. 0x4:I32
2270 struct {
2271 IRConst* con; /* The constant itself */
2272 } Const;
2274 /* A call to a pure (no side-effects) helper C function.
2276 With the 'cee' field, 'name' is the function's name. It is
2277 only used for pretty-printing purposes. The address to call
2278 (host address, of course) is stored in the 'addr' field
2279 inside 'cee'.
2281 The 'args' field is a NULL-terminated array of arguments.
2282 The stated return IRType, and the implied argument types,
2283 must match that of the function being called well enough so
2284 that the back end can actually generate correct code for the
2285 call.
2287 The called function **must** satisfy the following:
2289 * no side effects -- must be a pure function, the result of
2290 which depends only on the passed parameters.
2292 * it may not look at, nor modify, any of the guest state
2293 since that would hide guest state transitions from
2294 instrumenters
2296 * it may not access guest memory, since that would hide
2297 guest memory transactions from the instrumenters
2299 * it must not assume that arguments are being evaluated in a
2300 particular order. The oder of evaluation is unspecified.
2302 This is restrictive, but makes the semantics clean, and does
2303 not interfere with IR optimisation.
2305 If you want to call a helper which can mess with guest state
2306 and/or memory, instead use Ist_Dirty. This is a lot more
2307 flexible, but you have to give a bunch of details about what
2308 the helper does (and you better be telling the truth,
2309 otherwise any derived instrumentation will be wrong). Also
2310 Ist_Dirty inhibits various IR optimisations and so can cause
2311 quite poor code to be generated. Try to avoid it.
2313 In principle it would be allowable to have the arg vector
2314 contain an IRExpr_VECRET(), although not IRExpr_GSPTR(). However,
2315 at the moment there is no requirement for clean helper calls to
2316 be able to return V128 or V256 values. Hence this is not allowed.
2318 ppIRExpr output: <cee>(<args>):<retty>
2319 eg. foo{0x80489304}(t1, t2):I32
2321 struct {
2322 IRCallee* cee; /* Function to call. */
2323 IRType retty; /* Type of return value. */
2324 IRExpr** args; /* Vector of argument expressions. */
2325 } CCall;
2327 /* A ternary if-then-else operator. It returns iftrue if cond is
2328 nonzero, iffalse otherwise. Note that it is STRICT, ie. both
2329 iftrue and iffalse are evaluated in all cases.
2331 ppIRExpr output: ITE(<cond>,<iftrue>,<iffalse>),
2332 eg. ITE(t6,t7,t8)
2334 struct {
2335 IRExpr* cond; /* Condition */
2336 IRExpr* iftrue; /* True expression */
2337 IRExpr* iffalse; /* False expression */
2338 } ITE;
2339 } Iex;
2342 /* Expression auxiliaries: a ternary expression. */
2343 struct _IRTriop {
2344 IROp op; /* op-code */
2345 IRExpr* arg1; /* operand 1 */
2346 IRExpr* arg2; /* operand 2 */
2347 IRExpr* arg3; /* operand 3 */
2350 /* Expression auxiliaries: a quarternary expression. */
2351 struct _IRQop {
2352 IROp op; /* op-code */
2353 IRExpr* arg1; /* operand 1 */
2354 IRExpr* arg2; /* operand 2 */
2355 IRExpr* arg3; /* operand 3 */
2356 IRExpr* arg4; /* operand 4 */
2360 /* Two special kinds of IRExpr, which can ONLY be used in
2361 argument lists for dirty helper calls (IRDirty.args) and in NO
2362 OTHER PLACES. And then only in very limited ways. */
2364 /* Denotes an argument which (in the helper) takes a pointer to a
2365 (naturally aligned) V128 or V256, into which the helper is expected
2366 to write its result. Use of IRExpr_VECRET() is strictly
2367 controlled. If the helper returns a V128 or V256 value then
2368 IRExpr_VECRET() must appear exactly once in the arg list, although
2369 it can appear anywhere, and the helper must have a C 'void' return
2370 type. If the helper returns any other type, IRExpr_VECRET() may
2371 not appear in the argument list. */
2373 /* Denotes an void* argument which is passed to the helper, which at
2374 run time will point to the thread's guest state area. This can
2375 only appear at most once in an argument list, and it may not appear
2376 at all in argument lists for clean helper calls. */
2378 static inline Bool is_IRExpr_VECRET_or_GSPTR ( const IRExpr* e ) {
2379 return e->tag == Iex_VECRET || e->tag == Iex_GSPTR;
2383 /* Expression constructors. */
2384 extern IRExpr* IRExpr_Binder ( Int binder );
2385 extern IRExpr* IRExpr_Get ( Int off, IRType ty );
2386 extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
2387 extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
2388 extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
2389 IRExpr* arg3, IRExpr* arg4 );
2390 extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
2391 IRExpr* arg2, IRExpr* arg3 );
2392 extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
2393 extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
2394 extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
2395 extern IRExpr* IRExpr_Const ( IRConst* con );
2396 extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
2397 extern IRExpr* IRExpr_ITE ( IRExpr* cond, IRExpr* iftrue, IRExpr* iffalse );
2398 extern IRExpr* IRExpr_VECRET ( void );
2399 extern IRExpr* IRExpr_GSPTR ( void );
2401 /* Deep-copy an IRExpr. */
2402 extern IRExpr* deepCopyIRExpr ( const IRExpr* );
2404 /* Pretty-print an IRExpr. */
2405 extern void ppIRExpr ( const IRExpr* );
2407 /* NULL-terminated IRExpr vector constructors, suitable for
2408 use as arg lists in clean/dirty helper calls. */
2409 extern IRExpr** mkIRExprVec_0 ( void );
2410 extern IRExpr** mkIRExprVec_1 ( IRExpr* );
2411 extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
2412 extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
2413 extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2414 extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2415 IRExpr* );
2416 extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2417 IRExpr*, IRExpr* );
2418 extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2419 IRExpr*, IRExpr*, IRExpr* );
2420 extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2421 IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2422 extern IRExpr** mkIRExprVec_9 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2423 IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2424 extern IRExpr** mkIRExprVec_13 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2425 IRExpr*, IRExpr*, IRExpr*, IRExpr*,
2426 IRExpr*, IRExpr*, IRExpr*, IRExpr*, IRExpr* );
2428 /* IRExpr copiers:
2429 - shallowCopy: shallow-copy (ie. create a new vector that shares the
2430 elements with the original).
2431 - deepCopy: deep-copy (ie. create a completely new vector). */
2432 extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
2433 extern IRExpr** deepCopyIRExprVec ( IRExpr *const * );
2435 /* Make a constant expression from the given host word taking into
2436 account (of course) the host word size. */
2437 extern IRExpr* mkIRExpr_HWord ( HWord );
2439 /* Convenience function for constructing clean helper calls. */
2440 extern
2441 IRExpr* mkIRExprCCall ( IRType retty,
2442 Int regparms, const HChar* name, void* addr,
2443 IRExpr** args );
2446 /* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
2447 * Iex_Const). */
2448 static inline Bool isIRAtom ( const IRExpr* e ) {
2449 return e->tag == Iex_RdTmp || e->tag == Iex_Const;
2452 /* Are these two IR atoms identical? Causes an assertion
2453 failure if they are passed non-atoms. */
2454 extern Bool eqIRAtom ( const IRExpr*, const IRExpr* );
2457 /* ------------------ Jump kinds ------------------ */
2459 /* This describes hints which can be passed to the dispatcher at guest
2460 control-flow transfer points.
2462 Re Ijk_InvalICache and Ijk_FlushDCache: the guest state _must_ have
2463 two pseudo-registers, guest_CMSTART and guest_CMLEN, which specify
2464 the start and length of the region to be invalidated. CM stands
2465 for "Cache Management". These are both the size of a guest word.
2466 It is the responsibility of the relevant toIR.c to ensure that
2467 these are filled in with suitable values before issuing a jump of
2468 kind Ijk_InvalICache or Ijk_FlushDCache.
2470 Ijk_InvalICache requests invalidation of translations taken from
2471 the requested range. Ijk_FlushDCache requests flushing of the D
2472 cache for the specified range.
2474 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
2475 pseudo-register guest_EMNOTE, which is 32-bits regardless of the
2476 host or guest word size. That register should be made to hold a
2477 VexEmNote value to indicate the reason for the exit.
2479 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
2480 cannot continue) and so the jump destination can be anything.
2482 Re Ijk_Sys_ (syscall jumps): the guest state must have a
2483 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
2484 word. Front ends should set this to be the IP at the most recently
2485 executed kernel-entering (system call) instruction. This makes it
2486 very much easier (viz, actually possible at all) to back up the
2487 guest to restart a syscall that has been interrupted by a signal.
2489 typedef
2490 enum {
2491 Ijk_INVALID=0x1A00,
2492 Ijk_Boring, /* not interesting; just goto next */
2493 Ijk_Call, /* guest is doing a call */
2494 Ijk_Ret, /* guest is doing a return */
2495 Ijk_ClientReq, /* do guest client req before continuing */
2496 Ijk_Yield, /* client is yielding to thread scheduler */
2497 Ijk_EmWarn, /* report emulation warning before continuing */
2498 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
2499 Ijk_NoDecode, /* current instruction cannot be decoded */
2500 Ijk_MapFail, /* Vex-provided address translation failed */
2501 Ijk_InvalICache, /* Inval icache for range [CMSTART, +CMLEN) */
2502 Ijk_FlushDCache, /* Flush dcache for range [CMSTART, +CMLEN) */
2503 Ijk_NoRedir, /* Jump to un-redirected guest addr */
2504 Ijk_SigILL, /* current instruction synths SIGILL */
2505 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
2506 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
2507 Ijk_SigBUS, /* current instruction synths SIGBUS */
2508 Ijk_SigFPE, /* current instruction synths generic SIGFPE */
2509 Ijk_SigFPE_IntDiv, /* current instruction synths SIGFPE - IntDiv */
2510 Ijk_SigFPE_IntOvf, /* current instruction synths SIGFPE - IntOvf */
2511 /* Unfortunately, various guest-dependent syscall kinds. They
2512 all mean: do a syscall before continuing. */
2513 Ijk_Sys_syscall, /* amd64/x86 'syscall', ppc 'sc', arm 'svc #0' */
2514 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
2515 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
2516 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
2517 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
2518 Ijk_Sys_int145, /* amd64/x86 'int $0x91' */
2519 Ijk_Sys_int210, /* amd64/x86 'int $0xD2' */
2520 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes
2521 invalid at the point this happens. */
2523 IRJumpKind;
2525 extern void ppIRJumpKind ( IRJumpKind );
2528 /* ------------------ Dirty helper calls ------------------ */
2530 /* A dirty call is a flexible mechanism for calling (possibly
2531 conditionally) a helper function or procedure. The helper function
2532 may read, write or modify client memory, and may read, write or
2533 modify client state. It can take arguments and optionally return a
2534 value. It may return different results and/or do different things
2535 when called repeatedly with the same arguments, by means of storing
2536 private state.
2538 If a value is returned, it is assigned to the nominated return
2539 temporary.
2541 Dirty calls are statements rather than expressions for obvious
2542 reasons. If a dirty call is marked as writing guest state, any
2543 pre-existing values derived from the written parts of the guest
2544 state are invalid. Similarly, if the dirty call is stated as
2545 writing memory, any pre-existing loaded values are invalidated by
2548 In order that instrumentation is possible, the call must state, and
2549 state correctly:
2551 * Whether it reads, writes or modifies memory, and if so where.
2553 * Whether it reads, writes or modifies guest state, and if so which
2554 pieces. Several pieces may be stated, and their extents must be
2555 known at translation-time. Each piece is allowed to repeat some
2556 number of times at a fixed interval, if required.
2558 Normally, code is generated to pass just the args to the helper.
2559 However, if IRExpr_GSPTR() is present in the argument list (at most
2560 one instance is allowed), then the guest state pointer is passed for
2561 that arg, so that the callee can access the guest state. It is
2562 invalid for .nFxState to be zero but IRExpr_GSPTR() to be present,
2563 since .nFxState==0 is a claim that the call does not access guest
2564 state.
2566 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
2567 arguments and 'mFx' are evaluated REGARDLESS of the guard value.
2568 The order of argument evaluation is unspecified. The guard
2569 expression is evaluated AFTER the arguments and 'mFx' have been
2570 evaluated. 'mFx' is expected (by Memcheck) to be a defined value
2571 even if the guard evaluates to false.
2574 #define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
2576 /* Effects on resources (eg. registers, memory locations) */
2577 typedef
2578 enum {
2579 Ifx_None=0x1B00, /* no effect */
2580 Ifx_Read, /* reads the resource */
2581 Ifx_Write, /* writes the resource */
2582 Ifx_Modify, /* modifies the resource */
2584 IREffect;
2586 /* Pretty-print an IREffect */
2587 extern void ppIREffect ( IREffect );
2589 typedef
2590 struct _IRDirty {
2591 /* What to call, and details of args/results. .guard must be
2592 non-NULL. If .tmp is not IRTemp_INVALID, then the call
2593 returns a result which is placed in .tmp. If at runtime the
2594 guard evaluates to false, .tmp has an 0x555..555 bit pattern
2595 written to it. Hence conditional calls that assign .tmp are
2596 allowed. */
2597 IRCallee* cee; /* where to call */
2598 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
2599 /* The args vector may contain IRExpr_GSPTR() and/or
2600 IRExpr_VECRET(), in both cases, at most once. */
2601 IRExpr** args; /* arg vector, ends in NULL. */
2602 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
2604 /* Mem effects; we allow only one R/W/M region to be stated */
2605 IREffect mFx; /* indicates memory effects, if any */
2606 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
2607 Int mSize; /* of access, or zero if mFx==Ifx_None */
2609 /* Guest state effects; up to N allowed */
2610 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
2611 struct {
2612 IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
2613 UShort offset;
2614 UShort size;
2615 UChar nRepeats;
2616 UChar repeatLen;
2617 } fxState[VEX_N_FXSTATE];
2618 /* The access can be repeated, as specified by nRepeats and
2619 repeatLen. To describe only a single access, nRepeats and
2620 repeatLen should be zero. Otherwise, repeatLen must be a
2621 multiple of size and greater than size. */
2622 /* Overall, the parts of the guest state denoted by (offset,
2623 size, nRepeats, repeatLen) is
2624 [offset, +size)
2625 and, if nRepeats > 0,
2626 for (i = 1; i <= nRepeats; i++)
2627 [offset + i * repeatLen, +size)
2628 A convenient way to enumerate all segments is therefore
2629 for (i = 0; i < 1 + nRepeats; i++)
2630 [offset + i * repeatLen, +size)
2633 IRDirty;
2635 /* Pretty-print a dirty call */
2636 extern void ppIRDirty ( const IRDirty* );
2638 /* Allocate an uninitialised dirty call */
2639 extern IRDirty* emptyIRDirty ( void );
2641 /* Deep-copy a dirty call */
2642 extern IRDirty* deepCopyIRDirty ( const IRDirty* );
2644 /* A handy function which takes some of the tedium out of constructing
2645 dirty helper calls. The called function impliedly does not return
2646 any value and has a constant-True guard. The call is marked as
2647 accessing neither guest state nor memory (hence the "unsafe"
2648 designation) -- you can change this marking later if need be. A
2649 suitable IRCallee is constructed from the supplied bits. */
2650 extern
2651 IRDirty* unsafeIRDirty_0_N ( Int regparms, const HChar* name, void* addr,
2652 IRExpr** args );
2654 /* Similarly, make a zero-annotation dirty call which returns a value,
2655 and assign that to the given temp. */
2656 extern
2657 IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
2658 Int regparms, const HChar* name, void* addr,
2659 IRExpr** args );
2662 /* --------------- Memory Bus Events --------------- */
2664 typedef
2665 enum {
2666 Imbe_Fence=0x1C00,
2667 /* Needed only on ARM. It cancels a reservation made by a
2668 preceding Linked-Load, and needs to be handed through to the
2669 back end, just as LL and SC themselves are. */
2670 Imbe_CancelReservation
2672 IRMBusEvent;
2674 extern void ppIRMBusEvent ( IRMBusEvent );
2677 /* --------------- Compare and Swap --------------- */
2679 /* This denotes an atomic compare and swap operation, either
2680 a single-element one or a double-element one.
2682 In the single-element case:
2684 .addr is the memory address.
2685 .end is the endianness with which memory is accessed
2687 If .addr contains the same value as .expdLo, then .dataLo is
2688 written there, else there is no write. In both cases, the
2689 original value at .addr is copied into .oldLo.
2691 Types: .expdLo, .dataLo and .oldLo must all have the same type.
2692 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
2693 guests, I64.
2695 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
2696 be NULL.
2698 In the double-element case:
2700 .addr is the memory address.
2701 .end is the endianness with which memory is accessed
2703 The operation is the same:
2705 If .addr contains the same value as .expdHi:.expdLo, then
2706 .dataHi:.dataLo is written there, else there is no write. In
2707 both cases the original value at .addr is copied into
2708 .oldHi:.oldLo.
2710 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
2711 all have the same type, which may be any integral type, viz: I8,
2712 I16, I32 or, for 64-bit guests, I64.
2714 The double-element case is complicated by the issue of
2715 endianness. In all cases, the two elements are understood to be
2716 located adjacently in memory, starting at the address .addr.
2718 If .end is Iend_LE, then the .xxxLo component is at the lower
2719 address and the .xxxHi component is at the higher address, and
2720 each component is itself stored little-endianly.
2722 If .end is Iend_BE, then the .xxxHi component is at the lower
2723 address and the .xxxLo component is at the higher address, and
2724 each component is itself stored big-endianly.
2726 This allows representing more cases than most architectures can
2727 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
2729 How to know if the CAS succeeded?
2731 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
2732 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
2733 stored at .addr, and the original value there was .oldLo (resp
2734 .oldHi:.oldLo).
2736 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
2737 then the CAS failed, and the original value at .addr was .oldLo
2738 (resp. .oldHi:.oldLo).
2740 Hence it is easy to know whether or not the CAS succeeded.
2742 typedef
2743 struct {
2744 IRTemp oldHi; /* old value of *addr is written here */
2745 IRTemp oldLo;
2746 IREndness end; /* endianness of the data in memory */
2747 IRExpr* addr; /* store address */
2748 IRExpr* expdHi; /* expected old value at *addr */
2749 IRExpr* expdLo;
2750 IRExpr* dataHi; /* new value for *addr */
2751 IRExpr* dataLo;
2753 IRCAS;
2755 extern void ppIRCAS ( const IRCAS* cas );
2757 extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
2758 IREndness end, IRExpr* addr,
2759 IRExpr* expdHi, IRExpr* expdLo,
2760 IRExpr* dataHi, IRExpr* dataLo );
2762 extern IRCAS* deepCopyIRCAS ( const IRCAS* );
2765 /* ------------------ Circular Array Put ------------------ */
2767 typedef
2768 struct {
2769 IRRegArray* descr; /* Part of guest state treated as circular */
2770 IRExpr* ix; /* Variable part of index into array */
2771 Int bias; /* Constant offset part of index into array */
2772 IRExpr* data; /* The value to write */
2773 } IRPutI;
2775 extern void ppIRPutI ( const IRPutI* puti );
2777 extern IRPutI* mkIRPutI ( IRRegArray* descr, IRExpr* ix,
2778 Int bias, IRExpr* data );
2780 extern IRPutI* deepCopyIRPutI ( const IRPutI* );
2783 /* --------------- Guarded loads and stores --------------- */
2785 /* Conditional stores are straightforward. They are the same as
2786 normal stores, with an extra 'guard' field :: Ity_I1 that
2787 determines whether or not the store actually happens. If not,
2788 memory is unmodified.
2790 The semantics of this is that 'addr' and 'data' are fully evaluated
2791 even in the case where 'guard' evaluates to zero (false).
2793 typedef
2794 struct {
2795 IREndness end; /* Endianness of the store */
2796 IRExpr* addr; /* store address */
2797 IRExpr* data; /* value to write */
2798 IRExpr* guard; /* Guarding value */
2800 IRStoreG;
2802 /* Conditional loads are a little more complex. 'addr' is the
2803 address, 'guard' is the guarding condition. If the load takes
2804 place, the loaded value is placed in 'dst'. If it does not take
2805 place, 'alt' is copied to 'dst'. However, the loaded value is not
2806 placed directly in 'dst' -- it is first subjected to the conversion
2807 specified by 'cvt'.
2809 For example, imagine doing a conditional 8-bit load, in which the
2810 loaded value is zero extended to 32 bits. Hence:
2811 * 'dst' and 'alt' must have type I32
2812 * 'cvt' must be a unary op which converts I8 to I32. In this
2813 example, it would be ILGop_8Uto32.
2815 There is no explicit indication of the type at which the load is
2816 done, since that is inferrable from the arg type of 'cvt'. Note
2817 that the types of 'alt' and 'dst' and the result type of 'cvt' must
2818 all be the same.
2820 Semantically, 'addr' is evaluated even in the case where 'guard'
2821 evaluates to zero (false), and 'alt' is evaluated even when 'guard'
2822 evaluates to one (true). That is, 'addr' and 'alt' are always
2823 evaluated.
2825 typedef
2826 enum {
2827 ILGop_INVALID=0x1D00,
2828 ILGop_IdentV128, /* 128 bit vector, no conversion */
2829 ILGop_Ident64, /* 64 bit, no conversion */
2830 ILGop_Ident32, /* 32 bit, no conversion */
2831 ILGop_16Uto32, /* 16 bit load, Z-widen to 32 */
2832 ILGop_16Sto32, /* 16 bit load, S-widen to 32 */
2833 ILGop_8Uto32, /* 8 bit load, Z-widen to 32 */
2834 ILGop_8Sto32 /* 8 bit load, S-widen to 32 */
2836 IRLoadGOp;
2838 typedef
2839 struct {
2840 IREndness end; /* Endianness of the load */
2841 IRLoadGOp cvt; /* Conversion to apply to the loaded value */
2842 IRTemp dst; /* Destination (LHS) of assignment */
2843 IRExpr* addr; /* Address being loaded from */
2844 IRExpr* alt; /* Value if load is not done. */
2845 IRExpr* guard; /* Guarding value */
2847 IRLoadG;
2849 extern void ppIRStoreG ( const IRStoreG* sg );
2851 extern void ppIRLoadGOp ( IRLoadGOp cvt );
2853 extern void ppIRLoadG ( const IRLoadG* lg );
2855 extern IRStoreG* mkIRStoreG ( IREndness end,
2856 IRExpr* addr, IRExpr* data,
2857 IRExpr* guard );
2859 extern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
2860 IRTemp dst, IRExpr* addr, IRExpr* alt,
2861 IRExpr* guard );
2864 /* ------------------ Statements ------------------ */
2866 /* The different kinds of statements. Their meaning is explained
2867 below in the comments for IRStmt.
2869 Those marked META do not represent code, but rather extra
2870 information about the code. These statements can be removed
2871 without affecting the functional behaviour of the code, however
2872 they are required by some IR consumers such as tools that
2873 instrument the code.
2876 typedef
2877 enum {
2878 Ist_NoOp=0x1E00,
2879 Ist_IMark, /* META */
2880 Ist_AbiHint, /* META */
2881 Ist_Put,
2882 Ist_PutI,
2883 Ist_WrTmp,
2884 Ist_Store,
2885 Ist_LoadG,
2886 Ist_StoreG,
2887 Ist_CAS,
2888 Ist_LLSC,
2889 Ist_Dirty,
2890 Ist_MBE,
2891 Ist_Exit
2893 IRStmtTag;
2895 /* A statement. Stored as a tagged union. 'tag' indicates what kind
2896 of expression this is. 'Ist' is the union that holds the fields.
2897 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
2898 statement, and the fields can be accessed with
2899 'st.Ist.Store.<fieldname>'.
2901 For each kind of statement, we show what it looks like when
2902 pretty-printed with ppIRStmt().
2904 typedef
2905 struct _IRStmt {
2906 IRStmtTag tag;
2907 union {
2908 /* A no-op (usually resulting from IR optimisation). Can be
2909 omitted without any effect.
2911 ppIRStmt output: IR-NoOp
2913 struct {
2914 } NoOp;
2916 /* META: instruction mark. Marks the start of the statements
2917 that represent a single machine instruction (the end of
2918 those statements is marked by the next IMark or the end of
2919 the IRSB). Contains the address and length of the
2920 instruction.
2922 It also contains a delta value. The delta must be
2923 subtracted from a guest program counter value before
2924 attempting to establish, by comparison with the address
2925 and length values, whether or not that program counter
2926 value refers to this instruction. For x86, amd64, ppc32,
2927 ppc64 and arm, the delta value is zero. For Thumb
2928 instructions, the delta value is one. This is because, on
2929 Thumb, guest PC values (guest_R15T) are encoded using the
2930 top 31 bits of the instruction address and a 1 in the lsb;
2931 hence they appear to be (numerically) 1 past the start of
2932 the instruction they refer to. IOW, guest_R15T on ARM
2933 holds a standard ARM interworking address.
2935 ppIRStmt output: ------ IMark(<addr>, <len>, <delta>) ------,
2936 eg. ------ IMark(0x4000792, 5, 0) ------,
2938 struct {
2939 Addr addr; /* instruction address */
2940 UInt len; /* instruction length */
2941 UChar delta; /* addr = program counter as encoded in guest state
2942 - delta */
2943 } IMark;
2945 /* META: An ABI hint, which says something about this
2946 platform's ABI.
2948 At the moment, the only AbiHint is one which indicates
2949 that a given chunk of address space, [base .. base+len-1],
2950 has become undefined. This is used on amd64-linux and
2951 some ppc variants to pass stack-redzoning hints to whoever
2952 wants to see them. It also indicates the address of the
2953 next (dynamic) instruction that will be executed. This is
2954 to help Memcheck to origin tracking.
2956 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
2957 eg. ====== AbiHint(t1, 16, t2) ======
2959 struct {
2960 IRExpr* base; /* Start of undefined chunk */
2961 Int len; /* Length of undefined chunk */
2962 IRExpr* nia; /* Address of next (guest) insn */
2963 } AbiHint;
2965 /* Write a guest register, at a fixed offset in the guest state.
2966 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
2968 struct {
2969 Int offset; /* Offset into the guest state */
2970 IRExpr* data; /* The value to write */
2971 } Put;
2973 /* Write a guest register, at a non-fixed offset in the guest
2974 state. See the comment for GetI expressions for more
2975 information.
2977 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
2978 eg. PUTI(64:8xF64)[t5,0] = t1
2980 struct {
2981 IRPutI* details;
2982 } PutI;
2984 /* Assign a value to a temporary. Note that SSA rules require
2985 each tmp is only assigned to once. IR sanity checking will
2986 reject any block containing a temporary which is not assigned
2987 to exactly once.
2989 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
2991 struct {
2992 IRTemp tmp; /* Temporary (LHS of assignment) */
2993 IRExpr* data; /* Expression (RHS of assignment) */
2994 } WrTmp;
2996 /* Write a value to memory. This is a normal store, not a
2997 Store-Conditional. To represent a Store-Conditional,
2998 instead use IRStmt.LLSC.
2999 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
3001 struct {
3002 IREndness end; /* Endianness of the store */
3003 IRExpr* addr; /* store address */
3004 IRExpr* data; /* value to write */
3005 } Store;
3007 /* Guarded store. Note that this is defined to evaluate all
3008 expression fields (addr, data) even if the guard evaluates
3009 to false.
3010 ppIRStmt output:
3011 if (<guard>) ST<end>(<addr>) = <data> */
3012 struct {
3013 IRStoreG* details;
3014 } StoreG;
3016 /* Guarded load. Note that this is defined to evaluate all
3017 expression fields (addr, alt) even if the guard evaluates
3018 to false.
3019 ppIRStmt output:
3020 t<tmp> = if (<guard>) <cvt>(LD<end>(<addr>)) else <alt> */
3021 struct {
3022 IRLoadG* details;
3023 } LoadG;
3025 /* Do an atomic compare-and-swap operation. Semantics are
3026 described above on a comment at the definition of IRCAS.
3028 ppIRStmt output:
3029 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
3031 t1 = CASle(t2 :: t3->Add32(t3,1))
3032 which denotes a 32-bit atomic increment
3033 of a value at address t2
3035 A double-element CAS may also be denoted, in which case <tmp>,
3036 <expected> and <new> are all pairs of items, separated by
3037 commas.
3039 struct {
3040 IRCAS* details;
3041 } CAS;
3043 /* Either Load-Linked or Store-Conditional, depending on
3044 STOREDATA.
3046 If STOREDATA is NULL then this is a Load-Linked, meaning
3047 that data is loaded from memory as normal, but a
3048 'reservation' for the address is also lodged in the
3049 hardware.
3051 result = Load-Linked(addr, end)
3053 The data transfer type is the type of RESULT (I32, I64,
3054 etc). ppIRStmt output:
3056 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
3058 If STOREDATA is not NULL then this is a Store-Conditional,
3059 hence:
3061 result = Store-Conditional(addr, storedata, end)
3063 The data transfer type is the type of STOREDATA and RESULT
3064 has type Ity_I1. The store may fail or succeed depending
3065 on the state of a previously lodged reservation on this
3066 address. RESULT is written 1 if the store succeeds and 0
3067 if it fails. eg ppIRStmt output:
3069 result = ( ST<end>-Cond(<addr>) = <storedata> )
3070 eg t3 = ( STbe-Cond(t1, t2) )
3072 In all cases, the address must be naturally aligned for
3073 the transfer type -- any misaligned addresses should be
3074 caught by a dominating IR check and side exit. This
3075 alignment restriction exists because on at least some
3076 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
3077 misaligned addresses, and we have to actually generate
3078 stwcx. on the host, and we don't want it trapping on the
3079 host.
3081 Summary of rules for transfer type:
3082 STOREDATA == NULL (LL):
3083 transfer type = type of RESULT
3084 STOREDATA != NULL (SC):
3085 transfer type = type of STOREDATA, and RESULT :: Ity_I1
3087 struct {
3088 IREndness end;
3089 IRTemp result;
3090 IRExpr* addr;
3091 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
3092 } LLSC;
3094 /* Call (possibly conditionally) a C function that has side
3095 effects (ie. is "dirty"). See the comments above the
3096 IRDirty type declaration for more information.
3098 ppIRStmt output:
3099 t<tmp> = DIRTY <guard> <effects>
3100 ::: <callee>(<args>)
3102 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
3103 ::: foo{0x380035f4}(t2)
3105 struct {
3106 IRDirty* details;
3107 } Dirty;
3109 /* A memory bus event - a fence, or acquisition/release of the
3110 hardware bus lock. IR optimisation treats all these as fences
3111 across which no memory references may be moved.
3112 ppIRStmt output: MBusEvent-Fence,
3113 MBusEvent-BusLock, MBusEvent-BusUnlock.
3115 struct {
3116 IRMBusEvent event;
3117 } MBE;
3119 /* Conditional exit from the middle of an IRSB.
3120 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
3121 eg. if (t69) goto {Boring} 0x4000AAA:I32
3122 If <guard> is true, the guest state is also updated by
3123 PUT-ing <dst> at <offsIP>. This is done because a
3124 taken exit must update the guest program counter.
3126 struct {
3127 IRExpr* guard; /* Conditional expression */
3128 IRConst* dst; /* Jump target (constant only) */
3129 IRJumpKind jk; /* Jump kind */
3130 Int offsIP; /* Guest state offset for IP */
3131 } Exit;
3132 } Ist;
3134 IRStmt;
3136 /* Statement constructors. */
3137 extern IRStmt* IRStmt_NoOp ( void );
3138 extern IRStmt* IRStmt_IMark ( Addr addr, UInt len, UChar delta );
3139 extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
3140 extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
3141 extern IRStmt* IRStmt_PutI ( IRPutI* details );
3142 extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
3143 extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
3144 extern IRStmt* IRStmt_StoreG ( IREndness end, IRExpr* addr, IRExpr* data,
3145 IRExpr* guard );
3146 extern IRStmt* IRStmt_LoadG ( IREndness end, IRLoadGOp cvt, IRTemp dst,
3147 IRExpr* addr, IRExpr* alt, IRExpr* guard );
3148 extern IRStmt* IRStmt_CAS ( IRCAS* details );
3149 extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
3150 IRExpr* addr, IRExpr* storedata );
3151 extern IRStmt* IRStmt_Dirty ( IRDirty* details );
3152 extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
3153 extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
3154 Int offsIP );
3156 /* Deep-copy an IRStmt. */
3157 extern IRStmt* deepCopyIRStmt ( const IRStmt* );
3159 /* Pretty-print an IRStmt. */
3160 extern void ppIRStmt ( const IRStmt* );
3163 /* ------------------ Basic Blocks ------------------ */
3165 /* Type environments: a bunch of statements, expressions, etc, are
3166 incomplete without an environment indicating the type of each
3167 IRTemp. So this provides one. IR temporaries are really just
3168 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
3169 them.
3171 typedef
3172 struct {
3173 IRType* types;
3174 Int types_size;
3175 Int types_used;
3177 IRTypeEnv;
3179 /* Obtain a new IRTemp */
3180 extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
3182 /* Deep-copy a type environment */
3183 extern IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* );
3185 /* Pretty-print a type environment */
3186 extern void ppIRTypeEnv ( const IRTypeEnv* );
3189 /* Code blocks, which in proper compiler terminology are superblocks
3190 (single entry, multiple exit code sequences) contain:
3192 - A table giving a type for each temp (the "type environment")
3193 - An expandable array of statements
3194 - An expression of type 32 or 64 bits, depending on the
3195 guest's word size, indicating the next destination if the block
3196 executes all the way to the end, without a side exit
3197 - An indication of any special actions (JumpKind) needed
3198 for this final jump.
3199 - Offset of the IP field in the guest state. This will be
3200 updated before the final jump is done.
3202 "IRSB" stands for "IR Super Block".
3204 typedef
3205 struct {
3206 IRTypeEnv* tyenv;
3207 IRStmt** stmts;
3208 Int stmts_size;
3209 Int stmts_used;
3210 IRExpr* next;
3211 IRJumpKind jumpkind;
3212 Int offsIP;
3214 IRSB;
3216 /* Allocate a new, uninitialised IRSB */
3217 extern IRSB* emptyIRSB ( void );
3219 /* Deep-copy an IRSB */
3220 extern IRSB* deepCopyIRSB ( const IRSB* );
3222 /* Deep-copy an IRSB, except for the statements list, which set to be
3223 a new, empty, list of statements. */
3224 extern IRSB* deepCopyIRSBExceptStmts ( const IRSB* );
3226 /* Pretty-print an IRSB */
3227 extern void ppIRSB ( const IRSB* );
3229 /* Append an IRStmt to an IRSB */
3230 extern void addStmtToIRSB ( IRSB*, IRStmt* );
3233 /*---------------------------------------------------------------*/
3234 /*--- Helper functions for the IR ---*/
3235 /*---------------------------------------------------------------*/
3237 /* For messing with IR type environments */
3238 extern IRTypeEnv* emptyIRTypeEnv ( void );
3240 /* What is the type of this expression? */
3241 extern IRType typeOfIRConst ( const IRConst* );
3242 extern IRType typeOfIRTemp ( const IRTypeEnv*, IRTemp );
3243 extern IRType typeOfIRExpr ( const IRTypeEnv*, const IRExpr* );
3245 /* What are the arg and result type for this IRLoadGOp? */
3246 extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
3247 /*OUT*/IRType* t_res,
3248 /*OUT*/IRType* t_arg );
3250 /* Sanity check a BB of IR */
3251 extern void sanityCheckIRSB ( const IRSB* bb,
3252 const HChar* caller,
3253 Bool require_flatness,
3254 IRType guest_word_size );
3255 extern Bool isFlatIRStmt ( const IRStmt* );
3256 extern Bool isFlatIRSB ( const IRSB* );
3258 /* Is this any value actually in the enumeration 'IRType' ? */
3259 extern Bool isPlausibleIRType ( IRType ty );
3262 /*---------------------------------------------------------------*/
3263 /*--- IR injection ---*/
3264 /*---------------------------------------------------------------*/
3266 void vex_inject_ir(IRSB *, IREndness);
3269 #endif /* ndef __LIBVEX_IR_H */
3271 /*---------------------------------------------------------------*/
3272 /*--- libvex_ir.h ---*/
3273 /*---------------------------------------------------------------*/