2 /*---------------------------------------------------------------*/
3 /*--- begin libvex_ir.h ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2004-2010 OpenWorks LLP
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, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
39 #include "libvex_basictypes.h"
42 /*---------------------------------------------------------------*/
43 /*--- High-level IR description ---*/
44 /*---------------------------------------------------------------*/
46 /* Vex IR is an architecture-neutral intermediate representation.
47 Unlike some IRs in systems similar to Vex, it is not like assembly
48 language (ie. a list of instructions). Rather, it is more like the
49 IR that might be used in a compiler.
53 The code is broken into small code blocks ("superblocks", type:
54 'IRSB'). Each code block typically represents from 1 to perhaps 50
55 instructions. IRSBs are single-entry, multiple-exit code blocks.
56 Each IRSB contains three things:
57 - a type environment, which indicates the type of each temporary
58 value present in the IRSB
59 - a list of statements, which represent code
60 - a jump that exits from the end the IRSB
61 Because the blocks are multiple-exit, there can be additional
62 conditional exit statements that cause control to leave the IRSB
63 before the final exit. Also because of this, IRSBs can cover
64 multiple non-consecutive sequences of code (up to 3). These are
65 recorded in the type VexGuestExtents (see libvex.h).
67 Statements and expressions
68 ~~~~~~~~~~~~~~~~~~~~~~~~~~
69 Statements (type 'IRStmt') represent operations with side-effects,
70 eg. guest register writes, stores, and assignments to temporaries.
71 Expressions (type 'IRExpr') represent operations without
72 side-effects, eg. arithmetic operations, loads, constants.
73 Expressions can contain sub-expressions, forming expression trees,
74 eg. (3 + (4 * load(addr1)).
76 Storage of guest state
77 ~~~~~~~~~~~~~~~~~~~~~~
78 The "guest state" contains the guest registers of the guest machine
79 (ie. the machine that we are simulating). It is stored by default
80 in a block of memory supplied by the user of the VEX library,
81 generally referred to as the guest state (area). To operate on
82 these registers, one must first read ("Get") them from the guest
83 state into a temporary value. Afterwards, one can write ("Put")
84 them back into the guest state.
86 Get and Put are characterised by a byte offset into the guest
87 state, a small integer which effectively gives the identity of the
88 referenced guest register, and a type, which indicates the size of
89 the value to be transferred.
91 The basic "Get" and "Put" operations are sufficient to model normal
92 fixed registers on the guest. Selected areas of the guest state
93 can be treated as a circular array of registers (type:
94 'IRRegArray'), which can be indexed at run-time. This is done with
95 the "GetI" and "PutI" primitives. This is necessary to describe
96 rotating register files, for example the x87 FPU stack, SPARC
97 register windows, and the Itanium register files.
99 Examples, and flattened vs. unflattened code
100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101 For example, consider this x86 instruction:
105 One Vex IR translation for this code would be this:
107 ------ IMark(0x24F275, 7) ------
108 t3 = GET:I32(0) # get %eax, a 32-bit integer
109 t2 = GET:I32(12) # get %ebx, a 32-bit integer
110 t1 = Add32(t3,t2) # addl
111 PUT(0) = t1 # put %eax
113 (For simplicity, this ignores the effects on the condition codes, and
114 the update of the instruction pointer.)
116 The "IMark" is an IR statement that doesn't represent actual code.
117 Instead it indicates the address and length of the original
118 instruction. The numbers 0 and 12 are offsets into the guest state
119 for %eax and %ebx. The full list of offsets for an architecture
120 <ARCH> can be found in the type VexGuest<ARCH>State in the file
121 VEX/pub/libvex_guest_<ARCH>.h.
123 The five statements in this example are:
125 - three assignments to temporaries
126 - one register write (put)
128 The six expressions in this example are:
129 - two register reads (gets)
130 - one arithmetic (add) operation
131 - three temporaries (two nested within the Add32, one in the PUT)
133 The above IR is "flattened", ie. all sub-expressions are "atoms",
134 either constants or temporaries. An equivalent, unflattened version
137 PUT(0) = Add32(GET:I32(0), GET:I32(12))
139 IR is guaranteed to be flattened at instrumentation-time. This makes
140 instrumentation easier. Equivalent flattened and unflattened IR
141 typically results in the same generated code.
143 Another example, this one showing loads and stores:
147 This becomes (again ignoring condition code and instruction pointer
150 ------ IMark(0x4000ABA, 3) ------
151 t3 = Add32(GET:I32(0),0x4:I32)
157 The "le" in "LDle" and "STle" is short for "little-endian".
159 No need for deallocations
160 ~~~~~~~~~~~~~~~~~~~~~~~~~
161 Although there are allocation functions for various data structures
162 in this file, there are no deallocation functions. This is because
163 Vex uses a memory allocation scheme that automatically reclaims the
164 memory used by allocated structures once translation is completed.
165 This makes things easier for tools that instruments/transforms code
170 The IR is fully typed. For every IRSB (IR block) it is possible to
171 say unambiguously whether or not it is correctly typed.
172 Incorrectly typed IR has no meaning and the VEX will refuse to
173 process it. At various points during processing VEX typechecks the
174 IR and aborts if any violations are found. This seems overkill but
175 makes it a great deal easier to build a reliable JIT.
177 IR also has the SSA property. SSA stands for Static Single
178 Assignment, and what it means is that each IR temporary may be
179 assigned to only once. This idea became widely used in compiler
180 construction in the mid to late 90s. It makes many IR-level
181 transformations/code improvements easier, simpler and faster.
182 Whenever it typechecks an IR block, VEX also checks the SSA
183 property holds, and will abort if not so. So SSAness is
184 mechanically and rigidly enforced.
187 /*---------------------------------------------------------------*/
188 /*--- Type definitions for the IR ---*/
189 /*---------------------------------------------------------------*/
191 /* General comments about naming schemes:
193 All publically visible functions contain the name of the primary
194 type on which they operate (IRFoo, IRBar, etc). Hence you should
195 be able to identify these functions by grepping for "IR[A-Z]".
197 For some type 'IRFoo':
199 - ppIRFoo is the printing method for IRFoo, printing it to the
200 output channel specified in the LibVEX_Initialise call.
202 - eqIRFoo is a structural equality predicate for IRFoos.
204 - deepCopyIRFoo is a deep copy constructor for IRFoos.
205 It recursively traverses the entire argument tree and
206 produces a complete new tree. All types have a deep copy
209 - shallowCopyIRFoo is the shallow copy constructor for IRFoos.
210 It creates a new top-level copy of the supplied object,
211 but does not copy any sub-objects. Only some types have a
212 shallow copy constructor.
215 /* ------------------ Types ------------------ */
217 /* A type indicates the size of a value, and whether it's an integer, a
218 float, or a vector (SIMD) value. */
227 Ity_I128, /* 128-bit scalar */
228 Ity_F32, /* IEEE 754 float */
229 Ity_F64, /* IEEE 754 double */
230 Ity_V128 /* 128-bit SIMD */
234 /* Pretty-print an IRType */
235 extern void ppIRType ( IRType );
237 /* Get the size (in bytes) of an IRType */
238 extern Int sizeofIRType ( IRType );
241 /* ------------------ Endianness ------------------ */
243 /* IREndness is used in load IRExprs and store IRStmts. */
246 Iend_LE=0x12000, /* little endian */
247 Iend_BE /* big endian */
252 /* ------------------ Constants ------------------ */
254 /* IRConsts are used within 'Const' and 'Exit' IRExprs. */
256 /* The various kinds of constant. */
264 Ico_F64, /* 64-bit IEEE754 floating */
265 Ico_F64i, /* 64-bit unsigned int to be interpreted literally
266 as a IEEE754 double value. */
267 Ico_V128 /* 128-bit restricted vector constant, with 1 bit
268 (repeated 8 times) for each of the 16 x 1-byte lanes */
272 /* A constant. Stored as a tagged union. 'tag' indicates what kind of
273 constant this is. 'Ico' is the union that holds the fields. If an
274 IRConst 'c' has c.tag equal to Ico_U32, then it's a 32-bit constant,
275 and its value can be accessed with 'c.Ico.U32'. */
287 UShort V128; /* 16-bit value; see Ico_V128 comment above */
292 /* IRConst constructors */
293 extern IRConst* IRConst_U1 ( Bool );
294 extern IRConst* IRConst_U8 ( UChar );
295 extern IRConst* IRConst_U16 ( UShort );
296 extern IRConst* IRConst_U32 ( UInt );
297 extern IRConst* IRConst_U64 ( ULong );
298 extern IRConst* IRConst_F64 ( Double );
299 extern IRConst* IRConst_F64i ( ULong );
300 extern IRConst* IRConst_V128 ( UShort );
302 /* Deep-copy an IRConst */
303 extern IRConst* deepCopyIRConst ( IRConst* );
305 /* Pretty-print an IRConst */
306 extern void ppIRConst ( IRConst* );
308 /* Compare two IRConsts for equality */
309 extern Bool eqIRConst ( IRConst*, IRConst* );
312 /* ------------------ Call targets ------------------ */
314 /* Describes a helper function to call. The name part is purely for
315 pretty printing and not actually used. regparms=n tells the back
316 end that the callee has been declared
317 "__attribute__((regparm(n)))". On some targets (x86) the back end
318 will need to construct a non-standard sequence to call a function
321 mcx_mask is a sop to Memcheck. It indicates which args should be
322 considered 'always defined' when lazily computing definedness of
323 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to
324 args[1], etc. If a bit is set, the corresponding arg is excluded
325 (hence "x" in "mcx") from definedness checking.
337 /* Create an IRCallee. */
338 extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
340 /* Deep-copy an IRCallee. */
341 extern IRCallee* deepCopyIRCallee ( IRCallee* );
343 /* Pretty-print an IRCallee. */
344 extern void ppIRCallee ( IRCallee* );
347 /* ------------------ Guest state arrays ------------------ */
349 /* This describes a section of the guest state that we want to
350 be able to index at run time, so as to be able to describe
351 indexed or rotating register files on the guest. */
354 Int base; /* guest state offset of start of indexed area */
355 IRType elemTy; /* type of each element in the indexed area */
356 Int nElems; /* number of elements in the indexed area */
360 extern IRRegArray* mkIRRegArray ( Int, IRType, Int );
362 extern IRRegArray* deepCopyIRRegArray ( IRRegArray* );
364 extern void ppIRRegArray ( IRRegArray* );
365 extern Bool eqIRRegArray ( IRRegArray*, IRRegArray* );
368 /* ------------------ Temporaries ------------------ */
370 /* This represents a temporary, eg. t1. The IR optimiser relies on the
371 fact that IRTemps are 32-bit ints. Do not change them to be ints of
375 /* Pretty-print an IRTemp. */
376 extern void ppIRTemp ( IRTemp );
378 #define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
381 /* --------------- Primops (arity 1,2,3 and 4) --------------- */
383 /* Primitive operations that are used in Unop, Binop, Triop and Qop
384 IRExprs. Once we take into account integer, floating point and SIMD
385 operations of all the different sizes, there are quite a lot of them.
386 Most instructions supported by the architectures that Vex supports
387 (x86, PPC, etc) are represented. Some more obscure ones (eg. cpuid)
388 are not; they are instead handled with dirty helpers that emulate
389 their functionality. Such obscure ones are thus not directly visible
390 in the IR, but their effects on guest state (memory and registers)
391 are made visible via the annotations in IRDirty structures.
395 /* -- Do not change this ordering. The IR generators rely on
396 (eg) Iop_Add64 == IopAdd8 + 3. -- */
399 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
400 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
401 /* Signless mul. MullS/MullU is elsewhere. */
402 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
403 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
404 Iop_And8, Iop_And16, Iop_And32, Iop_And64,
405 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
406 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
407 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
408 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
409 /* Integer comparisons. */
410 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64,
411 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64,
412 /* Tags for unary ops */
413 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
415 /* Exactly like CmpEQ8/16/32/64, but carrying the additional
416 hint that these compute the success/failure of a CAS
417 operation, and hence are almost certainly applied to two
418 copies of the same value, which in turn has implications for
419 Memcheck's instrumentation. */
420 Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
421 Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
423 /* -- Ordering not important after here. -- */
425 /* Widening multiplies */
426 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
427 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
429 /* Wierdo integer stuff */
430 Iop_Clz64, Iop_Clz32, /* count leading zeroes */
431 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
432 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
433 zero. You must ensure they are never given a zero argument.
436 /* Standard integer comparisons */
437 Iop_CmpLT32S, Iop_CmpLT64S,
438 Iop_CmpLE32S, Iop_CmpLE64S,
439 Iop_CmpLT32U, Iop_CmpLT64U,
440 Iop_CmpLE32U, Iop_CmpLE64U,
442 /* As a sop to Valgrind-Memcheck, the following are useful. */
443 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
444 Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
445 Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
446 Iop_Max32U, /* unsigned max */
448 /* PowerPC-style 3-way integer comparisons. Without them it is
449 difficult to simulate PPC efficiently.
450 op(x,y) | x < y = 0x8 else
454 Iop_CmpORD32U, Iop_CmpORD64U,
455 Iop_CmpORD32S, Iop_CmpORD64S,
458 /* TODO: clarify semantics wrt rounding, negative values, whatever */
459 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod)
460 Iop_DivS32, // ditto, signed
461 Iop_DivU64, // :: I64,I64 -> I64 (simple div, no mod)
462 Iop_DivS64, // ditto, signed
464 Iop_DivModU64to32, // :: I64,I32 -> I64
465 // of which lo half is div and hi half is mod
466 Iop_DivModS64to32, // ditto, signed
468 Iop_DivModU128to64, // :: V128,I64 -> V128
469 // of which lo half is div and hi half is mod
470 Iop_DivModS128to64, // ditto, signed
472 /* Integer conversions. Some of these are redundant (eg
473 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
474 having a complete set reduces the typical dynamic size of IR
475 and makes the instruction selectors easier to write. */
477 /* Widening conversions */
478 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64,
479 Iop_16Uto32, Iop_16Uto64,
481 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64,
482 Iop_16Sto32, Iop_16Sto64,
485 /* Narrowing conversions */
486 Iop_64to8, Iop_32to8, Iop_64to16,
487 /* 8 <-> 16 bit conversions */
488 Iop_16to8, // :: I16 -> I8, low half
489 Iop_16HIto8, // :: I16 -> I8, high half
490 Iop_8HLto16, // :: (I8,I8) -> I16
491 /* 16 <-> 32 bit conversions */
492 Iop_32to16, // :: I32 -> I16, low half
493 Iop_32HIto16, // :: I32 -> I16, high half
494 Iop_16HLto32, // :: (I16,I16) -> I32
495 /* 32 <-> 64 bit conversions */
496 Iop_64to32, // :: I64 -> I32, low half
497 Iop_64HIto32, // :: I64 -> I32, high half
498 Iop_32HLto64, // :: (I32,I32) -> I64
499 /* 64 <-> 128 bit conversions */
500 Iop_128to64, // :: I128 -> I64, low half
501 Iop_128HIto64, // :: I128 -> I64, high half
502 Iop_64HLto128, // :: (I64,I64) -> I128
504 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */
505 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
506 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
507 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */
508 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
509 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
510 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */
511 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
512 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
513 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
515 /* ------ Floating point. We try to be IEEE754 compliant. ------ */
517 /* --- Simple stuff as mandated by 754. --- */
519 /* Binary operations, with rounding. */
520 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
521 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64,
523 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */
524 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32,
526 /* Variants of the above which produce a 64-bit result but which
527 round their result to a IEEE float range first. */
528 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
529 Iop_AddF64r32, Iop_SubF64r32, Iop_MulF64r32, Iop_DivF64r32,
531 /* Unary operations, without rounding. */
533 Iop_NegF64, Iop_AbsF64,
536 Iop_NegF32, Iop_AbsF32,
538 /* Unary operations, with rounding. */
539 /* :: IRRoundingMode(I32) x F64 -> F64 */
540 Iop_SqrtF64, Iop_SqrtF64r32,
542 /* :: IRRoundingMode(I32) x F32 -> F32 */
545 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
550 This just happens to be the Intel encoding. The values
551 are recorded in the type IRCmpF64Result.
553 /* :: F64 x F64 -> IRCmpF64Result(I32) */
556 /* --- Int to/from FP conversions. --- */
558 /* For the most part, these take a first argument :: Ity_I32 (as
559 IRRoundingMode) which is an indication of the rounding mode
560 to use, as per the following encoding ("the standard
562 00b to nearest (the default)
566 This just happens to be the Intel encoding. For reference only,
568 00b to nearest (the default)
572 Any PPC -> IR front end will have to translate these PPC
573 encodings, as encoded in the guest state, to the standard
574 encodings, to pass to the primops.
575 For reference only, the ARM VFP encoding is:
580 Again, this will have to be converted to the standard encoding
583 If one of these conversions gets an out-of-range condition,
584 or a NaN, as an argument, the result is host-defined. On x86
585 the "integer indefinite" value 0x80..00 is produced. On PPC
586 it is either 0x80..00 or 0x7F..FF depending on the sign of
589 On ARMvfp, when converting to a signed integer result, the
590 overflow result is 0x80..00 for negative args and 0x7F..FF
591 for positive args. For unsigned integer results it is
592 0x00..00 and 0xFF..FF respectively.
594 Rounding is required whenever the destination type cannot
595 represent exactly all values of the source type.
597 Iop_F64toI16S, /* IRRoundingMode(I32) x F64 -> signed I16 */
598 Iop_F64toI32S, /* IRRoundingMode(I32) x F64 -> signed I32 */
599 Iop_F64toI64S, /* IRRoundingMode(I32) x F64 -> signed I64 */
601 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */
603 Iop_I16StoF64, /* signed I16 -> F64 */
604 Iop_I32StoF64, /* signed I32 -> F64 */
605 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */
607 Iop_I32UtoF64, /* unsigned I32 -> F64 */
609 /* Conversion between floating point formats */
610 Iop_F32toF64, /* F32 -> F64 */
611 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */
613 /* Reinterpretation. Take an F64 and produce an I64 with
614 the same bit pattern, or vice versa. */
615 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
616 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
618 /* --- guest x86/amd64 specifics, not mandated by 754. --- */
620 /* Binary ops, with rounding. */
621 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */
622 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */
623 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */
624 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */
625 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */
626 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */
627 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */
628 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
629 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */
630 /* Note that on x86 guest, PRem1{C3210} has the same behaviour
631 as the IEEE mandated RemF64, except it is limited in the
632 range of its operand. Hence the partialness. */
634 /* Unary ops, with rounding. */
635 /* :: IRRoundingMode(I32) x F64 -> F64 */
636 Iop_SinF64, /* FSIN */
637 Iop_CosF64, /* FCOS */
638 Iop_TanF64, /* FTAN */
639 Iop_2xm1F64, /* (2^arg - 1.0) */
640 Iop_RoundF64toInt, /* F64 value to nearest integral value (still
643 /* --- guest ppc32/64 specifics, not mandated by 754. --- */
645 /* Ternary operations, with rounding. */
646 /* Fused multiply-add/sub, with 112-bit intermediate
648 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64
649 (computes arg2 * arg3 +/- arg4) */
650 Iop_MAddF64, Iop_MSubF64,
652 /* Variants of the above which produce a 64-bit result but which
653 round their result to a IEEE float range first. */
654 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */
655 Iop_MAddF64r32, Iop_MSubF64r32,
658 Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */
659 Iop_RoundF64toF64_NEAREST, /* frin */
660 Iop_RoundF64toF64_NegINF, /* frim */
661 Iop_RoundF64toF64_PosINF, /* frip */
662 Iop_RoundF64toF64_ZERO, /* friz */
665 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */
667 /* :: IRRoundingMode(I32) x F64 -> F64 */
668 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */
669 /* NB: pretty much the same as Iop_F64toF32, except no change
673 Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord)
676 /* ------------------ 64-bit SIMD Integer. ------------------ */
678 /* MISC (vector integer cmp != 0) */
679 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
681 /* ADDITION (normal / unsigned sat / signed sat) */
682 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,
683 Iop_QAdd8Ux8, Iop_QAdd16Ux4,
684 Iop_QAdd8Sx8, Iop_QAdd16Sx4,
686 /* SUBTRACTION (normal / unsigned sat / signed sat) */
687 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2,
688 Iop_QSub8Ux8, Iop_QSub16Ux4,
689 Iop_QSub8Sx8, Iop_QSub16Sx4,
691 /* MULTIPLICATION (normal / high half of signed/unsigned) */
692 Iop_Mul16x4, Iop_Mul32x2,
696 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
707 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2,
708 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
710 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
711 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2,
712 Iop_ShrN16x4, Iop_ShrN32x2,
713 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2,
715 /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */
720 /* INTERLEAVING -- interleave lanes from low or high halves of
721 operands. Most-significant result lane is from the left
723 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
724 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
726 /* CONCATENATION -- build a new value by concatenating either
727 the even or odd lanes of both operands. Note that
728 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2
729 and so are omitted. */
730 Iop_CatOddLanes16x4, Iop_CatEvenLanes16x4,
732 /* PERMUTING -- copy src bytes to dst,
733 as indexed by control vector bytes:
734 for i in 0 .. 7 . result[i] = argL[ argR[i] ]
735 argR[i] values may only be in the range 0 .. 7, else behaviour
739 /* ------------------ 128-bit SIMD FP. ------------------ */
741 /* --- 32x4 vector FP --- */
744 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
745 Iop_Max32Fx4, Iop_Min32Fx4,
746 /* Note: For the following compares, the ppc front-end assumes a
747 nan in a lane of either argument returns zero for that lane. */
748 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
749 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
752 Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
754 /* --- Int to/from FP conversion --- */
755 /* Unlike the standard fp conversions, these irops take no
756 rounding mode argument. Instead the irop trailers _R{M,P,N,Z}
757 indicate the mode: {-inf, +inf, nearest, zero} respectively. */
758 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */
759 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 */
760 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */
761 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */
763 /* --- 32x4 lowest-lane-only scalar FP --- */
765 /* In binary cases, upper 3/4 is copied from first operand. In
766 unary cases, upper 3/4 is copied from the operand. */
769 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
770 Iop_Max32F0x4, Iop_Min32F0x4,
771 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
774 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
776 /* --- 64x2 vector FP --- */
779 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
780 Iop_Max64Fx2, Iop_Min64Fx2,
781 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
784 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
786 /* --- 64x2 lowest-lane-only scalar FP --- */
788 /* In binary cases, upper half is copied from first operand. In
789 unary cases, upper half is copied from the operand. */
792 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
793 Iop_Max64F0x2, Iop_Min64F0x2,
794 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
797 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
799 /* --- pack / unpack --- */
801 /* 64 <-> 128 bit vector */
802 Iop_V128to64, // :: V128 -> I64, low half
803 Iop_V128HIto64, // :: V128 -> I64, high half
804 Iop_64HLtoV128, // :: (I64,I64) -> V128
809 /* 32 <-> 128 bit vector */
811 Iop_V128to32, // :: V128 -> I32, lowest lane
812 Iop_SetV128lo32, // :: (V128,I32) -> V128
814 /* ------------------ 128-bit SIMD Integer. ------------------ */
818 Iop_AndV128, Iop_OrV128, Iop_XorV128,
820 /* VECTOR SHIFT (shift amt :: Ity_I8) */
821 Iop_ShlV128, Iop_ShrV128,
823 /* MISC (vector integer cmp != 0) */
824 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
826 /* ADDITION (normal / unsigned sat / signed sat) */
827 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2,
828 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4,
829 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4,
831 /* SUBTRACTION (normal / unsigned sat / signed sat) */
832 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2,
833 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4,
834 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4,
836 /* MULTIPLICATION (normal / high half of signed/unsigned) */
838 Iop_MulHi16Ux8, Iop_MulHi32Ux4,
839 Iop_MulHi16Sx8, Iop_MulHi32Sx4,
840 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
841 Iop_MullEven8Ux16, Iop_MullEven16Ux8,
842 Iop_MullEven8Sx16, Iop_MullEven16Sx8,
844 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
845 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
846 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
849 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
850 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
851 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
852 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
855 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4,
856 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
857 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
859 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
860 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
861 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
862 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4,
864 /* VECTOR x VECTOR SHIFT / ROTATE */
865 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4,
866 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4,
867 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4,
868 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
870 /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */
871 /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */
872 Iop_QNarrow16Ux8, Iop_QNarrow32Ux4,
873 Iop_QNarrow16Sx8, Iop_QNarrow32Sx4,
874 Iop_Narrow16x8, Iop_Narrow32x4,
876 /* INTERLEAVING -- interleave lanes from low or high halves of
877 operands. Most-significant result lane is from the left
879 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
880 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
881 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
882 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
884 /* DUPLICATING -- copy value to all lanes */
885 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
887 /* PERMUTING -- copy src bytes to dst,
888 as indexed by control vector bytes:
889 for i in 0 .. 15 . result[i] = argL[ argR[i] ]
890 argR[i] values may only be in the range 0 .. 15, else behaviour
896 /* Pretty-print an op. */
897 extern void ppIROp ( IROp );
900 /* Encoding of IEEE754-specified rounding modes. This is the same as
901 the encoding used by Intel IA32 to indicate x87 rounding mode.
902 Note, various front and back ends rely on the actual numerical
903 values of these, so do not change them. */
913 /* Floating point comparison result values, as created by Iop_CmpF64.
914 This is also derived from what IA32 does. */
925 /* ------------------ Expressions ------------------ */
927 /* The different kinds of expressions. Their meaning is explained below
928 in the comments for IRExpr. */
946 /* An expression. Stored as a tagged union. 'tag' indicates what kind
947 of expression this is. 'Iex' is the union that holds the fields. If
948 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load
949 expression, and the fields can be accessed with
950 'e.Iex.Load.<fieldname>'.
952 For each kind of expression, we show what it looks like when
953 pretty-printed with ppIRExpr().
962 /* Used only in pattern matching within Vex. Should not be seen
968 /* Read a guest register, at a fixed offset in the guest state.
969 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0)
972 Int offset; /* Offset into the guest state */
973 IRType ty; /* Type of the value being read */
976 /* Read a guest register at a non-fixed offset in the guest
977 state. This allows circular indexing into parts of the guest
978 state, which is essential for modelling situations where the
979 identity of guest registers is not known until run time. One
980 example is the x87 FP register stack.
982 The part of the guest state to be treated as a circular array
983 is described in the IRRegArray 'descr' field. It holds the
984 offset of the first element in the array, the type of each
985 element, and the number of elements.
987 The array index is indicated rather indirectly, in a way
988 which makes optimisation easy: as the sum of variable part
989 (the 'ix' field) and a constant offset (the 'bias' field).
991 Since the indexing is circular, the actual array index to use
992 is computed as (ix + bias) % num-of-elems-in-the-array.
994 Here's an example. The description
998 describes an array of 8 F64-typed values, the
999 guest-state-offset of the first being 96. This array is
1000 being indexed at (t39 - 7) % 8.
1002 It is important to get the array size/type exactly correct
1003 since IR optimisation looks closely at such info in order to
1004 establish aliasing/non-aliasing between seperate GetI and
1005 PutI events, which is used to establish when they can be
1006 reordered, etc. Putting incorrect info in will lead to
1007 obscure IR optimisation bugs.
1009 ppIRExpr output: GETI<descr>[<ix>,<bias]
1010 eg. GETI(128:8xI8)[t1,0]
1013 IRRegArray* descr; /* Part of guest state treated as circular */
1014 IRExpr* ix; /* Variable part of index into array */
1015 Int bias; /* Constant offset part of index into array */
1018 /* The value held by a temporary.
1019 ppIRExpr output: t<tmp>, eg. t1
1022 IRTemp tmp; /* The temporary number */
1025 /* A quaternary operation.
1026 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>),
1027 eg. MAddF64r32(t1, t2, t3, t4)
1030 IROp op; /* op-code */
1031 IRExpr* arg1; /* operand 1 */
1032 IRExpr* arg2; /* operand 2 */
1033 IRExpr* arg3; /* operand 3 */
1034 IRExpr* arg4; /* operand 4 */
1037 /* A ternary operation.
1038 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>),
1039 eg. MulF64(1, 2.0, 3.0)
1042 IROp op; /* op-code */
1043 IRExpr* arg1; /* operand 1 */
1044 IRExpr* arg2; /* operand 2 */
1045 IRExpr* arg3; /* operand 3 */
1048 /* A binary operation.
1049 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2)
1052 IROp op; /* op-code */
1053 IRExpr* arg1; /* operand 1 */
1054 IRExpr* arg2; /* operand 2 */
1057 /* A unary operation.
1058 ppIRExpr output: <op>(<arg>), eg. Neg8(t1)
1061 IROp op; /* op-code */
1062 IRExpr* arg; /* operand */
1065 /* A load from memory -- a normal load, not a load-linked.
1066 Load-Linkeds (and Store-Conditionals) are instead represented
1067 by IRStmt.LLSC since Load-Linkeds have side effects and so
1068 are not semantically valid IRExpr's.
1069 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1)
1072 IREndness end; /* Endian-ness of the load */
1073 IRType ty; /* Type of the loaded value */
1074 IRExpr* addr; /* Address being loaded from */
1077 /* A constant-valued expression.
1078 ppIRExpr output: <con>, eg. 0x4:I32
1081 IRConst* con; /* The constant itself */
1084 /* A call to a pure (no side-effects) helper C function.
1086 With the 'cee' field, 'name' is the function's name. It is
1087 only used for pretty-printing purposes. The address to call
1088 (host address, of course) is stored in the 'addr' field
1091 The 'args' field is a NULL-terminated array of arguments.
1092 The stated return IRType, and the implied argument types,
1093 must match that of the function being called well enough so
1094 that the back end can actually generate correct code for the
1097 The called function **must** satisfy the following:
1099 * no side effects -- must be a pure function, the result of
1100 which depends only on the passed parameters.
1102 * it may not look at, nor modify, any of the guest state
1103 since that would hide guest state transitions from
1106 * it may not access guest memory, since that would hide
1107 guest memory transactions from the instrumenters
1109 This is restrictive, but makes the semantics clean, and does
1110 not interfere with IR optimisation.
1112 If you want to call a helper which can mess with guest state
1113 and/or memory, instead use Ist_Dirty. This is a lot more
1114 flexible, but you have to give a bunch of details about what
1115 the helper does (and you better be telling the truth,
1116 otherwise any derived instrumentation will be wrong). Also
1117 Ist_Dirty inhibits various IR optimisations and so can cause
1118 quite poor code to be generated. Try to avoid it.
1120 ppIRExpr output: <cee>(<args>):<retty>
1121 eg. foo{0x80489304}(t1, t2):I32
1124 IRCallee* cee; /* Function to call. */
1125 IRType retty; /* Type of return value. */
1126 IRExpr** args; /* Vector of argument expressions. */
1129 /* A ternary if-then-else operator. It returns expr0 if cond is
1130 zero, exprX otherwise. Note that it is STRICT, ie. both
1131 expr0 and exprX are evaluated in all cases.
1133 ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>),
1137 IRExpr* cond; /* Condition */
1138 IRExpr* expr0; /* True expression */
1139 IRExpr* exprX; /* False expression */
1144 /* Expression constructors. */
1145 extern IRExpr* IRExpr_Binder ( Int binder );
1146 extern IRExpr* IRExpr_Get ( Int off, IRType ty );
1147 extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias );
1148 extern IRExpr* IRExpr_RdTmp ( IRTemp tmp );
1149 extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2,
1150 IRExpr* arg3, IRExpr* arg4 );
1151 extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
1152 IRExpr* arg2, IRExpr* arg3 );
1153 extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 );
1154 extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg );
1155 extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr );
1156 extern IRExpr* IRExpr_Const ( IRConst* con );
1157 extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args );
1158 extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
1160 /* Deep-copy an IRExpr. */
1161 extern IRExpr* deepCopyIRExpr ( IRExpr* );
1163 /* Pretty-print an IRExpr. */
1164 extern void ppIRExpr ( IRExpr* );
1166 /* NULL-terminated IRExpr vector constructors, suitable for
1167 use as arg lists in clean/dirty helper calls. */
1168 extern IRExpr** mkIRExprVec_0 ( void );
1169 extern IRExpr** mkIRExprVec_1 ( IRExpr* );
1170 extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
1171 extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
1172 extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
1173 extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1175 extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1177 extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*,
1178 IRExpr*, IRExpr*, IRExpr* );
1181 - shallowCopy: shallow-copy (ie. create a new vector that shares the
1182 elements with the original).
1183 - deepCopy: deep-copy (ie. create a completely new vector). */
1184 extern IRExpr** shallowCopyIRExprVec ( IRExpr** );
1185 extern IRExpr** deepCopyIRExprVec ( IRExpr** );
1187 /* Make a constant expression from the given host word taking into
1188 account (of course) the host word size. */
1189 extern IRExpr* mkIRExpr_HWord ( HWord );
1191 /* Convenience function for constructing clean helper calls. */
1193 IRExpr* mkIRExprCCall ( IRType retty,
1194 Int regparms, HChar* name, void* addr,
1198 /* Convenience functions for atoms (IRExprs which are either Iex_Tmp or
1200 static inline Bool isIRAtom ( IRExpr* e ) {
1201 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const);
1204 /* Are these two IR atoms identical? Causes an assertion
1205 failure if they are passed non-atoms. */
1206 extern Bool eqIRAtom ( IRExpr*, IRExpr* );
1209 /* ------------------ Jump kinds ------------------ */
1211 /* This describes hints which can be passed to the dispatcher at guest
1212 control-flow transfer points.
1214 Re Ijk_TInval: the guest state _must_ have two pseudo-registers,
1215 guest_TISTART and guest_TILEN, which specify the start and length
1216 of the region to be invalidated. These are both the size of a
1217 guest word. It is the responsibility of the relevant toIR.c to
1218 ensure that these are filled in with suitable values before issuing
1219 a jump of kind Ijk_TInval.
1221 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a
1222 pseudo-register guest_EMWARN, which is 32-bits regardless of the
1223 host or guest word size. That register should be made to hold an
1224 EmWarn_* value to indicate the reason for the exit.
1226 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code
1227 cannot continue) and so the jump destination can be anything.
1229 Re Ijk_Sys_ (syscall jumps): the guest state must have a
1230 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest
1231 word. Front ends should set this to be the IP at the most recently
1232 executed kernel-entering (system call) instruction. This makes it
1233 very much easier (viz, actually possible at all) to back up the
1234 guest to restart a syscall that has been interrupted by a signal.
1238 Ijk_Boring=0x16000, /* not interesting; just goto next */
1239 Ijk_Call, /* guest is doing a call */
1240 Ijk_Ret, /* guest is doing a return */
1241 Ijk_ClientReq, /* do guest client req before continuing */
1242 Ijk_Yield, /* client is yielding to thread scheduler */
1243 Ijk_EmWarn, /* report emulation warning before continuing */
1244 Ijk_EmFail, /* emulation critical (FATAL) error; give up */
1245 Ijk_NoDecode, /* next instruction cannot be decoded */
1246 Ijk_MapFail, /* Vex-provided address translation failed */
1247 Ijk_TInval, /* Invalidate translations before continuing. */
1248 Ijk_NoRedir, /* Jump to un-redirected guest addr */
1249 Ijk_SigTRAP, /* current instruction synths SIGTRAP */
1250 Ijk_SigSEGV, /* current instruction synths SIGSEGV */
1251 Ijk_SigBUS, /* current instruction synths SIGBUS */
1252 /* Unfortunately, various guest-dependent syscall kinds. They
1253 all mean: do a syscall before continuing. */
1254 Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
1255 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */
1256 Ijk_Sys_int48, /* amd64/x86 'int $0x30' */
1257 Ijk_Sys_int50, /* amd64/x86 'int $0x32' */
1258 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */
1259 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */
1260 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */
1261 Ijk_Sys_sysenter, /* x86 'sysenter'. guest_EIP becomes
1262 invalid at the point this happens. */
1269 Ijk_l4_ud2, /* UD2 instruction */
1270 Ijk_l4_artificial, /* L4Re artificial trap */
1274 extern void ppIRJumpKind ( IRJumpKind );
1277 /* ------------------ Dirty helper calls ------------------ */
1279 /* A dirty call is a flexible mechanism for calling (possibly
1280 conditionally) a helper function or procedure. The helper function
1281 may read, write or modify client memory, and may read, write or
1282 modify client state. It can take arguments and optionally return a
1283 value. It may return different results and/or do different things
1284 when called repeatedly with the same arguments, by means of storing
1287 If a value is returned, it is assigned to the nominated return
1290 Dirty calls are statements rather than expressions for obvious
1291 reasons. If a dirty call is marked as writing guest state, any
1292 values derived from the written parts of the guest state are
1293 invalid. Similarly, if the dirty call is stated as writing
1294 memory, any loaded values are invalidated by it.
1296 In order that instrumentation is possible, the call must state, and
1299 * whether it reads, writes or modifies memory, and if so where
1300 (only one chunk can be stated)
1302 * whether it reads, writes or modifies guest state, and if so which
1303 pieces (several pieces may be stated, and currently their extents
1304 must be known at translation-time).
1306 Normally, code is generated to pass just the args to the helper.
1307 However, if .needsBBP is set, then an extra first argument is
1308 passed, which is the baseblock pointer, so that the callee can
1309 access the guest state. It is invalid for .nFxState to be zero
1310 but .needsBBP to be True, since .nFxState==0 is a claim that the
1311 call does not access guest state.
1313 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The
1314 arguments are evaluated REGARDLESS of the guard value. It is
1315 unspecified the relative order of arg evaluation and guard
1319 #define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */
1321 /* Effects on resources (eg. registers, memory locations) */
1324 Ifx_None = 0x17000, /* no effect */
1325 Ifx_Read, /* reads the resource */
1326 Ifx_Write, /* writes the resource */
1327 Ifx_Modify, /* modifies the resource */
1331 /* Pretty-print an IREffect */
1332 extern void ppIREffect ( IREffect );
1337 /* What to call, and details of args/results */
1338 IRCallee* cee; /* where to call */
1339 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
1340 IRExpr** args; /* arg list, ends in NULL */
1341 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */
1343 /* Mem effects; we allow only one R/W/M region to be stated */
1344 IREffect mFx; /* indicates memory effects, if any */
1345 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */
1346 Int mSize; /* of access, or zero if mFx==Ifx_None */
1348 /* Guest state effects; up to N allowed */
1349 Bool needsBBP; /* True => also pass guest state ptr to callee */
1350 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
1352 IREffect fx; /* read, write or modify? Ifx_None is invalid. */
1355 } fxState[VEX_N_FXSTATE];
1359 /* Pretty-print a dirty call */
1360 extern void ppIRDirty ( IRDirty* );
1362 /* Allocate an uninitialised dirty call */
1363 extern IRDirty* emptyIRDirty ( void );
1365 /* Deep-copy a dirty call */
1366 extern IRDirty* deepCopyIRDirty ( IRDirty* );
1368 /* A handy function which takes some of the tedium out of constructing
1369 dirty helper calls. The called function impliedly does not return
1370 any value and has a constant-True guard. The call is marked as
1371 accessing neither guest state nor memory (hence the "unsafe"
1372 designation) -- you can change this marking later if need be. A
1373 suitable IRCallee is constructed from the supplied bits. */
1375 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
1378 /* Similarly, make a zero-annotation dirty call which returns a value,
1379 and assign that to the given temp. */
1381 IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
1382 Int regparms, HChar* name, void* addr,
1386 /* --------------- Memory Bus Events --------------- */
1394 extern void ppIRMBusEvent ( IRMBusEvent );
1397 /* --------------- Compare and Swap --------------- */
1399 /* This denotes an atomic compare and swap operation, either
1400 a single-element one or a double-element one.
1402 In the single-element case:
1404 .addr is the memory address.
1405 .end is the endianness with which memory is accessed
1407 If .addr contains the same value as .expdLo, then .dataLo is
1408 written there, else there is no write. In both cases, the
1409 original value at .addr is copied into .oldLo.
1411 Types: .expdLo, .dataLo and .oldLo must all have the same type.
1412 It may be any integral type, viz: I8, I16, I32 or, for 64-bit
1415 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must
1418 In the double-element case:
1420 .addr is the memory address.
1421 .end is the endianness with which memory is accessed
1423 The operation is the same:
1425 If .addr contains the same value as .expdHi:.expdLo, then
1426 .dataHi:.dataLo is written there, else there is no write. In
1427 both cases the original value at .addr is copied into
1430 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must
1431 all have the same type, which may be any integral type, viz: I8,
1432 I16, I32 or, for 64-bit guests, I64.
1434 The double-element case is complicated by the issue of
1435 endianness. In all cases, the two elements are understood to be
1436 located adjacently in memory, starting at the address .addr.
1438 If .end is Iend_LE, then the .xxxLo component is at the lower
1439 address and the .xxxHi component is at the higher address, and
1440 each component is itself stored little-endianly.
1442 If .end is Iend_BE, then the .xxxHi component is at the lower
1443 address and the .xxxLo component is at the higher address, and
1444 each component is itself stored big-endianly.
1446 This allows representing more cases than most architectures can
1447 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements.
1449 How to know if the CAS succeeded?
1451 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo),
1452 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now
1453 stored at .addr, and the original value there was .oldLo (resp
1456 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo),
1457 then the CAS failed, and the original value at .addr was .oldLo
1458 (resp. .oldHi:.oldLo).
1460 Hence it is easy to know whether or not the CAS succeeded.
1464 IRTemp oldHi; /* old value of *addr is written here */
1466 IREndness end; /* endianness of the data in memory */
1467 IRExpr* addr; /* store address */
1468 IRExpr* expdHi; /* expected old value at *addr */
1470 IRExpr* dataHi; /* new value for *addr */
1475 extern void ppIRCAS ( IRCAS* cas );
1477 extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo,
1478 IREndness end, IRExpr* addr,
1479 IRExpr* expdHi, IRExpr* expdLo,
1480 IRExpr* dataHi, IRExpr* dataLo );
1482 extern IRCAS* deepCopyIRCAS ( IRCAS* );
1484 /* ------------------ Statements ------------------ */
1486 /* The different kinds of statements. Their meaning is explained
1487 below in the comments for IRStmt.
1489 Those marked META do not represent code, but rather extra
1490 information about the code. These statements can be removed
1491 without affecting the functional behaviour of the code, however
1492 they are required by some IR consumers such as tools that
1493 instrument the code.
1499 Ist_IMark, /* META */
1500 Ist_AbiHint, /* META */
1508 Ist_MBE, /* META (maybe) */
1513 /* A statement. Stored as a tagged union. 'tag' indicates what kind
1514 of expression this is. 'Ist' is the union that holds the fields.
1515 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store
1516 statement, and the fields can be accessed with
1517 'st.Ist.Store.<fieldname>'.
1519 For each kind of statement, we show what it looks like when
1520 pretty-printed with ppIRStmt().
1526 /* A no-op (usually resulting from IR optimisation). Can be
1527 omitted without any effect.
1529 ppIRStmt output: IR-NoOp
1534 /* META: instruction mark. Marks the start of the statements
1535 that represent a single machine instruction (the end of
1536 those statements is marked by the next IMark or the end of
1537 the IRSB). Contains the address and length of the
1540 ppIRStmt output: ------ IMark(<addr>, <len>) ------,
1541 eg. ------ IMark(0x4000792, 5) ------,
1544 Addr64 addr; /* instruction address */
1545 Int len; /* instruction length */
1548 /* META: An ABI hint, which says something about this
1551 At the moment, the only AbiHint is one which indicates
1552 that a given chunk of address space, [base .. base+len-1],
1553 has become undefined. This is used on amd64-linux and
1554 some ppc variants to pass stack-redzoning hints to whoever
1555 wants to see them. It also indicates the address of the
1556 next (dynamic) instruction that will be executed. This is
1557 to help Memcheck to origin tracking.
1559 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
1560 eg. ====== AbiHint(t1, 16, t2) ======
1563 IRExpr* base; /* Start of undefined chunk */
1564 Int len; /* Length of undefined chunk */
1565 IRExpr* nia; /* Address of next (guest) insn */
1568 /* Write a guest register, at a fixed offset in the guest state.
1569 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
1572 Int offset; /* Offset into the guest state */
1573 IRExpr* data; /* The value to write */
1576 /* Write a guest register, at a non-fixed offset in the guest
1577 state. See the comment for GetI expressions for more
1580 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
1581 eg. PUTI(64:8xF64)[t5,0] = t1
1584 IRRegArray* descr; /* Part of guest state treated as circular */
1585 IRExpr* ix; /* Variable part of index into array */
1586 Int bias; /* Constant offset part of index into array */
1587 IRExpr* data; /* The value to write */
1590 /* Assign a value to a temporary. Note that SSA rules require
1591 each tmp is only assigned to once. IR sanity checking will
1592 reject any block containing a temporary which is not assigned
1595 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
1598 IRTemp tmp; /* Temporary (LHS of assignment) */
1599 IRExpr* data; /* Expression (RHS of assignment) */
1602 /* Write a value to memory. This is a normal store, not a
1603 Store-Conditional. To represent a Store-Conditional,
1604 instead use IRStmt.LLSC.
1605 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
1608 IREndness end; /* Endianness of the store */
1609 IRExpr* addr; /* store address */
1610 IRExpr* data; /* value to write */
1613 /* Do an atomic compare-and-swap operation. Semantics are
1614 described above on a comment at the definition of IRCAS.
1617 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
1619 t1 = CASle(t2 :: t3->Add32(t3,1))
1620 which denotes a 32-bit atomic increment
1621 of a value at address t2
1623 A double-element CAS may also be denoted, in which case <tmp>,
1624 <expected> and <new> are all pairs of items, separated by
1631 /* Either Load-Linked or Store-Conditional, depending on
1634 If STOREDATA is NULL then this is a Load-Linked, meaning
1635 that data is loaded from memory as normal, but a
1636 'reservation' for the address is also lodged in the
1639 result = Load-Linked(addr, end)
1641 The data transfer type is the type of RESULT (I32, I64,
1642 etc). ppIRStmt output:
1644 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
1646 If STOREDATA is not NULL then this is a Store-Conditional,
1649 result = Store-Conditional(addr, storedata, end)
1651 The data transfer type is the type of STOREDATA and RESULT
1652 has type Ity_I1. The store may fail or succeed depending
1653 on the state of a previously lodged reservation on this
1654 address. RESULT is written 1 if the store succeeds and 0
1655 if it fails. eg ppIRStmt output:
1657 result = ( ST<end>-Cond(<addr>) = <storedata> )
1658 eg t3 = ( STbe-Cond(t1, t2) )
1660 In all cases, the address must be naturally aligned for
1661 the transfer type -- any misaligned addresses should be
1662 caught by a dominating IR check and side exit. This
1663 alignment restriction exists because on at least some
1664 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on
1665 misaligned addresses, and we have to actually generate
1666 stwcx. on the host, and we don't want it trapping on the
1669 Summary of rules for transfer type:
1670 STOREDATA == NULL (LL):
1671 transfer type = type of RESULT
1672 STOREDATA != NULL (SC):
1673 transfer type = type of STOREDATA, and RESULT :: Ity_I1
1679 IRExpr* storedata; /* NULL => LL, non-NULL => SC */
1682 /* Call (possibly conditionally) a C function that has side
1683 effects (ie. is "dirty"). See the comments above the
1684 IRDirty type declaration for more information.
1687 t<tmp> = DIRTY <guard> <effects>
1688 ::: <callee>(<args>)
1690 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
1691 ::: foo{0x380035f4}(t2)
1697 /* A memory bus event - a fence, or acquisition/release of the
1698 hardware bus lock. IR optimisation treats all these as fences
1699 across which no memory references may be moved.
1700 ppIRStmt output: MBusEvent-Fence,
1701 MBusEvent-BusLock, MBusEvent-BusUnlock.
1707 /* Conditional exit from the middle of an IRSB.
1708 ppIRStmt output: if (<guard>) goto {<jk>} <dst>
1709 eg. if (t69) goto {Boring} 0x4000AAA:I32
1712 IRExpr* guard; /* Conditional expression */
1713 IRJumpKind jk; /* Jump kind */
1714 IRConst* dst; /* Jump target (constant only) */
1720 /* Statement constructors. */
1721 extern IRStmt* IRStmt_NoOp ( void );
1722 extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len );
1723 extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia );
1724 extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
1725 extern IRStmt* IRStmt_PutI ( IRRegArray* descr, IRExpr* ix, Int bias,
1727 extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
1728 extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
1729 extern IRStmt* IRStmt_CAS ( IRCAS* details );
1730 extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result,
1731 IRExpr* addr, IRExpr* storedata );
1732 extern IRStmt* IRStmt_Dirty ( IRDirty* details );
1733 extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
1734 extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
1736 /* Deep-copy an IRStmt. */
1737 extern IRStmt* deepCopyIRStmt ( IRStmt* );
1739 /* Pretty-print an IRStmt. */
1740 extern void ppIRStmt ( IRStmt* );
1743 /* ------------------ Basic Blocks ------------------ */
1745 /* Type environments: a bunch of statements, expressions, etc, are
1746 incomplete without an environment indicating the type of each
1747 IRTemp. So this provides one. IR temporaries are really just
1748 unsigned ints and so this provides an array, 0 .. n_types_used-1 of
1759 /* Obtain a new IRTemp */
1760 extern IRTemp newIRTemp ( IRTypeEnv*, IRType );
1762 /* Deep-copy a type environment */
1763 extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* );
1765 /* Pretty-print a type environment */
1766 extern void ppIRTypeEnv ( IRTypeEnv* );
1769 /* Code blocks, which in proper compiler terminology are superblocks
1770 (single entry, multiple exit code sequences) contain:
1772 - A table giving a type for each temp (the "type environment")
1773 - An expandable array of statements
1774 - An expression of type 32 or 64 bits, depending on the
1775 guest's word size, indicating the next destination if the block
1776 executes all the way to the end, without a side exit
1777 - An indication of any special actions (JumpKind) needed
1778 for this final jump.
1780 "IRSB" stands for "IR Super Block".
1789 IRJumpKind jumpkind;
1793 /* Allocate a new, uninitialised IRSB */
1794 extern IRSB* emptyIRSB ( void );
1796 /* Deep-copy an IRSB */
1797 extern IRSB* deepCopyIRSB ( IRSB* );
1799 /* Deep-copy an IRSB, except for the statements list, which set to be
1800 a new, empty, list of statements. */
1801 extern IRSB* deepCopyIRSBExceptStmts ( IRSB* );
1803 /* Pretty-print an IRSB */
1804 extern void ppIRSB ( IRSB* );
1806 /* Append an IRStmt to an IRSB */
1807 extern void addStmtToIRSB ( IRSB*, IRStmt* );
1810 /*---------------------------------------------------------------*/
1811 /*--- Helper functions for the IR ---*/
1812 /*---------------------------------------------------------------*/
1814 /* For messing with IR type environments */
1815 extern IRTypeEnv* emptyIRTypeEnv ( void );
1817 /* What is the type of this expression? */
1818 extern IRType typeOfIRConst ( IRConst* );
1819 extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp );
1820 extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* );
1822 /* Sanity check a BB of IR */
1823 extern void sanityCheckIRSB ( IRSB* bb,
1825 Bool require_flatness,
1826 IRType guest_word_size );
1827 extern Bool isFlatIRStmt ( IRStmt* );
1829 /* Is this any value actually in the enumeration 'IRType' ? */
1830 extern Bool isPlausibleIRType ( IRType ty );
1832 #endif /* ndef __LIBVEX_IR_H */
1835 /*---------------------------------------------------------------*/
1836 /*--- libvex_ir.h ---*/
1837 /*---------------------------------------------------------------*/