libvex_ir.h revision e739ac0589b4fb43561f801c4faba8c1b89f8680
1 2/*---------------------------------------------------------------*/ 3/*--- begin libvex_ir.h ---*/ 4/*---------------------------------------------------------------*/ 5 6/* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2010 OpenWorks LLP 11 info@open-works.net 12 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. 17 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. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 02110-1301, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 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. 34*/ 35 36#ifndef __LIBVEX_IR_H 37#define __LIBVEX_IR_H 38 39#include "libvex_basictypes.h" 40 41 42/*---------------------------------------------------------------*/ 43/*--- High-level IR description ---*/ 44/*---------------------------------------------------------------*/ 45 46/* Vex IR is an architecture-neutral intermediate representation. 47 Unlike some IRs in systems similar to Vex, it is not like assembly 48 language (ie. a list of instructions). Rather, it is more like the 49 IR that might be used in a compiler. 50 51 Code blocks 52 ~~~~~~~~~~~ 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). 66 67 Statements and expressions 68 ~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 Statements (type 'IRStmt') represent operations with side-effects, 70 eg. guest register writes, stores, and assignments to temporaries. 71 Expressions (type 'IRExpr') represent operations without 72 side-effects, eg. arithmetic operations, loads, constants. 73 Expressions can contain sub-expressions, forming expression trees, 74 eg. (3 + (4 * load(addr1)). 75 76 Storage of guest state 77 ~~~~~~~~~~~~~~~~~~~~~~ 78 The "guest state" contains the guest registers of the guest machine 79 (ie. the machine that we are simulating). It is stored by default 80 in a block of memory supplied by the user of the VEX library, 81 generally referred to as the guest state (area). To operate on 82 these registers, one must first read ("Get") them from the guest 83 state into a temporary value. Afterwards, one can write ("Put") 84 them back into the guest state. 85 86 Get and Put are characterised by a byte offset into the guest 87 state, a small integer which effectively gives the identity of the 88 referenced guest register, and a type, which indicates the size of 89 the value to be transferred. 90 91 The basic "Get" and "Put" operations are sufficient to model normal 92 fixed registers on the guest. Selected areas of the guest state 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. 98 99 Examples, and flattened vs. unflattened code 100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 101 For example, consider this x86 instruction: 102 103 addl %eax, %ebx 104 105 One Vex IR translation for this code would be this: 106 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 112 113 (For simplicity, this ignores the effects on the condition codes, and 114 the update of the instruction pointer.) 115 116 The "IMark" is an IR statement that doesn't represent actual code. 117 Instead it indicates the address and length of the original 118 instruction. The numbers 0 and 12 are offsets into the guest state 119 for %eax and %ebx. The full list of offsets for an architecture 120 <ARCH> can be found in the type VexGuest<ARCH>State in the file 121 VEX/pub/libvex_guest_<ARCH>.h. 122 123 The five statements in this example are: 124 - the IMark 125 - three assignments to temporaries 126 - one register write (put) 127 128 The six expressions in this example are: 129 - two register reads (gets) 130 - one arithmetic (add) operation 131 - three temporaries (two nested within the Add32, one in the PUT) 132 133 The above IR is "flattened", ie. all sub-expressions are "atoms", 134 either constants or temporaries. An equivalent, unflattened version 135 would be: 136 137 PUT(0) = Add32(GET:I32(0), GET:I32(12)) 138 139 IR is guaranteed to be flattened at instrumentation-time. This makes 140 instrumentation easier. Equivalent flattened and unflattened IR 141 typically results in the same generated code. 142 143 Another example, this one showing loads and stores: 144 145 addl %edx,4(%eax) 146 147 This becomes (again ignoring condition code and instruction pointer 148 updates): 149 150 ------ IMark(0x4000ABA, 3) ------ 151 t3 = Add32(GET:I32(0),0x4:I32) 152 t2 = LDle:I32(t3) 153 t1 = GET:I32(8) 154 t0 = Add32(t2,t1) 155 STle(t3) = t0 156 157 The "le" in "LDle" and "STle" is short for "little-endian". 158 159 No need for deallocations 160 ~~~~~~~~~~~~~~~~~~~~~~~~~ 161 Although there are allocation functions for various data structures 162 in this file, there are no deallocation functions. This is because 163 Vex uses a memory allocation scheme that automatically reclaims the 164 memory used by allocated structures once translation is completed. 165 This makes things easier for tools that instruments/transforms code 166 blocks. 167 168 SSAness and typing 169 ~~~~~~~~~~~~~~~~~~ 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. 176 177 IR also has the SSA property. SSA stands for Static Single 178 Assignment, and what it means is that each IR temporary may be 179 assigned to only once. This idea became widely used in compiler 180 construction in the mid to late 90s. It makes many IR-level 181 transformations/code improvements easier, simpler and faster. 182 Whenever it typechecks an IR block, VEX also checks the SSA 183 property holds, and will abort if not so. So SSAness is 184 mechanically and rigidly enforced. 185*/ 186 187/*---------------------------------------------------------------*/ 188/*--- Type definitions for the IR ---*/ 189/*---------------------------------------------------------------*/ 190 191/* General comments about naming schemes: 192 193 All publically visible functions contain the name of the primary 194 type on which they operate (IRFoo, IRBar, etc). Hence you should 195 be able to identify these functions by grepping for "IR[A-Z]". 196 197 For some type 'IRFoo': 198 199 - ppIRFoo is the printing method for IRFoo, printing it to the 200 output channel specified in the LibVEX_Initialise call. 201 202 - eqIRFoo is a structural equality predicate for IRFoos. 203 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 207 constructor. 208 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. 213*/ 214 215/* ------------------ Types ------------------ */ 216 217/* A type indicates the size of a value, and whether it's an integer, a 218 float, or a vector (SIMD) value. */ 219typedef 220 enum { 221 Ity_INVALID=0x11000, 222 Ity_I1, 223 Ity_I8, 224 Ity_I16, 225 Ity_I32, 226 Ity_I64, 227 Ity_I128, /* 128-bit scalar */ 228 Ity_F32, /* IEEE 754 float */ 229 Ity_F64, /* IEEE 754 double */ 230 Ity_V128 /* 128-bit SIMD */ 231 } 232 IRType; 233 234/* Pretty-print an IRType */ 235extern void ppIRType ( IRType ); 236 237/* Get the size (in bytes) of an IRType */ 238extern Int sizeofIRType ( IRType ); 239 240 241/* ------------------ Endianness ------------------ */ 242 243/* IREndness is used in load IRExprs and store IRStmts. */ 244typedef 245 enum { 246 Iend_LE=0x12000, /* little endian */ 247 Iend_BE /* big endian */ 248 } 249 IREndness; 250 251 252/* ------------------ Constants ------------------ */ 253 254/* IRConsts are used within 'Const' and 'Exit' IRExprs. */ 255 256/* The various kinds of constant. */ 257typedef 258 enum { 259 Ico_U1=0x13000, 260 Ico_U8, 261 Ico_U16, 262 Ico_U32, 263 Ico_U64, 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 */ 269 } 270 IRConstTag; 271 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'. */ 276typedef 277 struct _IRConst { 278 IRConstTag tag; 279 union { 280 Bool U1; 281 UChar U8; 282 UShort U16; 283 UInt U32; 284 ULong U64; 285 Double F64; 286 ULong F64i; 287 UShort V128; /* 16-bit value; see Ico_V128 comment above */ 288 } Ico; 289 } 290 IRConst; 291 292/* IRConst constructors */ 293extern IRConst* IRConst_U1 ( Bool ); 294extern IRConst* IRConst_U8 ( UChar ); 295extern IRConst* IRConst_U16 ( UShort ); 296extern IRConst* IRConst_U32 ( UInt ); 297extern IRConst* IRConst_U64 ( ULong ); 298extern IRConst* IRConst_F64 ( Double ); 299extern IRConst* IRConst_F64i ( ULong ); 300extern IRConst* IRConst_V128 ( UShort ); 301 302/* Deep-copy an IRConst */ 303extern IRConst* deepCopyIRConst ( IRConst* ); 304 305/* Pretty-print an IRConst */ 306extern void ppIRConst ( IRConst* ); 307 308/* Compare two IRConsts for equality */ 309extern Bool eqIRConst ( IRConst*, IRConst* ); 310 311 312/* ------------------ Call targets ------------------ */ 313 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 319 declared like this. 320 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. 326*/ 327 328typedef 329 struct { 330 Int regparms; 331 HChar* name; 332 void* addr; 333 UInt mcx_mask; 334 } 335 IRCallee; 336 337/* Create an IRCallee. */ 338extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr ); 339 340/* Deep-copy an IRCallee. */ 341extern IRCallee* deepCopyIRCallee ( IRCallee* ); 342 343/* Pretty-print an IRCallee. */ 344extern void ppIRCallee ( IRCallee* ); 345 346 347/* ------------------ Guest state arrays ------------------ */ 348 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. */ 352typedef 353 struct { 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 */ 357 } 358 IRRegArray; 359 360extern IRRegArray* mkIRRegArray ( Int, IRType, Int ); 361 362extern IRRegArray* deepCopyIRRegArray ( IRRegArray* ); 363 364extern void ppIRRegArray ( IRRegArray* ); 365extern Bool eqIRRegArray ( IRRegArray*, IRRegArray* ); 366 367 368/* ------------------ Temporaries ------------------ */ 369 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 372 any other size. */ 373typedef UInt IRTemp; 374 375/* Pretty-print an IRTemp. */ 376extern void ppIRTemp ( IRTemp ); 377 378#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF) 379 380 381/* --------------- Primops (arity 1,2,3 and 4) --------------- */ 382 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. 392*/ 393typedef 394 enum { 395 /* -- Do not change this ordering. The IR generators rely on 396 (eg) Iop_Add64 == IopAdd8 + 3. -- */ 397 398 Iop_INVALID=0x14000, 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, 414 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, 422 423 /* -- Ordering not important after here. -- */ 424 425 /* Widening multiplies */ 426 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64, 427 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64, 428 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. 434 */ 435 436 /* Standard integer comparisons */ 437 Iop_CmpLT32S, Iop_CmpLT64S, 438 Iop_CmpLE32S, Iop_CmpLE64S, 439 Iop_CmpLT32U, Iop_CmpLT64U, 440 Iop_CmpLE32U, Iop_CmpLE64U, 441 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 */ 447 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 451 | x > y = 0x4 else 452 | x == y = 0x2 453 */ 454 Iop_CmpORD32U, Iop_CmpORD64U, 455 Iop_CmpORD32S, Iop_CmpORD64S, 456 457 /* Division */ 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 463 464 Iop_DivModU64to32, // :: I64,I32 -> I64 465 // of which lo half is div and hi half is mod 466 Iop_DivModS64to32, // ditto, signed 467 468 Iop_DivModU128to64, // :: V128,I64 -> V128 469 // of which lo half is div and hi half is mod 470 Iop_DivModS128to64, // ditto, signed 471 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. */ 476 477 /* Widening conversions */ 478 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64, 479 Iop_16Uto32, Iop_16Uto64, 480 Iop_32Uto64, 481 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64, 482 Iop_16Sto32, Iop_16Sto64, 483 Iop_32Sto64, 484 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 503 /* 1-bit stuff */ 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 */ 514 515 /* ------ Floating point. We try to be IEEE754 compliant. ------ */ 516 517 /* --- Simple stuff as mandated by 754. --- */ 518 519 /* Binary operations, with rounding. */ 520 /* :: IRRoundingMode(I32) x F64 x F64 -> F64 */ 521 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, 522 523 /* :: IRRoundingMode(I32) x F32 x F32 -> F32 */ 524 Iop_AddF32, Iop_SubF32, Iop_MulF32, Iop_DivF32, 525 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, 530 531 /* Unary operations, without rounding. */ 532 /* :: F64 -> F64 */ 533 Iop_NegF64, Iop_AbsF64, 534 535 /* :: F32 -> F32 */ 536 Iop_NegF32, Iop_AbsF32, 537 538 /* Unary operations, with rounding. */ 539 /* :: IRRoundingMode(I32) x F64 -> F64 */ 540 Iop_SqrtF64, Iop_SqrtF64r32, 541 542 /* :: IRRoundingMode(I32) x F32 -> F32 */ 543 Iop_SqrtF32, 544 545 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following: 546 0x45 Unordered 547 0x01 LT 548 0x00 GT 549 0x40 EQ 550 This just happens to be the Intel encoding. The values 551 are recorded in the type IRCmpF64Result. 552 */ 553 /* :: F64 x F64 -> IRCmpF64Result(I32) */ 554 Iop_CmpF64, 555 556 /* --- Int to/from FP conversions. --- */ 557 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 561 encoding"): 562 00b to nearest (the default) 563 01b to -infinity 564 10b to +infinity 565 11b to zero 566 This just happens to be the Intel encoding. For reference only, 567 the PPC encoding is: 568 00b to nearest (the default) 569 01b to zero 570 10b to +infinity 571 11b to -infinity 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: 576 00b to nearest 577 01b to +infinity 578 10b to -infinity 579 11b to zero 580 Again, this will have to be converted to the standard encoding 581 to pass to primops. 582 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 587 the argument. 588 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. 593 594 Rounding is required whenever the destination type cannot 595 represent exactly all values of the source type. 596 */ 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 */ 600 601 Iop_F64toI32U, /* IRRoundingMode(I32) x F64 -> unsigned I32 */ 602 603 Iop_I16StoF64, /* signed I16 -> F64 */ 604 Iop_I32StoF64, /* signed I32 -> F64 */ 605 Iop_I64StoF64, /* IRRoundingMode(I32) x signed I64 -> F64 */ 606 607 Iop_I32UtoF64, /* unsigned I32 -> F64 */ 608 609 /* Conversion between floating point formats */ 610 Iop_F32toF64, /* F32 -> F64 */ 611 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */ 612 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, 617 618 /* --- guest x86/amd64 specifics, not mandated by 754. --- */ 619 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. */ 633 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 641 as F64) */ 642 Iop_RoundF32toInt, /* F32 value to nearest integral value (still 643 as F32) */ 644 645 /* --- guest ppc32/64 specifics, not mandated by 754. --- */ 646 647 /* Ternary operations, with rounding. */ 648 /* Fused multiply-add/sub, with 112-bit intermediate 649 precision */ 650 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 651 (computes arg2 * arg3 +/- arg4) */ 652 Iop_MAddF64, Iop_MSubF64, 653 654 /* Variants of the above which produce a 64-bit result but which 655 round their result to a IEEE float range first. */ 656 /* :: IRRoundingMode(I32) x F64 x F64 x F64 -> F64 */ 657 Iop_MAddF64r32, Iop_MSubF64r32, 658 659 /* :: F64 -> F64 */ 660 Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */ 661 Iop_RoundF64toF64_NEAREST, /* frin */ 662 Iop_RoundF64toF64_NegINF, /* frim */ 663 Iop_RoundF64toF64_PosINF, /* frip */ 664 Iop_RoundF64toF64_ZERO, /* friz */ 665 666 /* :: F64 -> F32 */ 667 Iop_TruncF64asF32, /* do F64->F32 truncation as per 'fsts' */ 668 669 /* :: IRRoundingMode(I32) x F64 -> F64 */ 670 Iop_RoundF64toF32, /* round F64 to nearest F32 value (still as F64) */ 671 /* NB: pretty much the same as Iop_F64toF32, except no change 672 of type. */ 673 674 /* :: F64 -> I32 */ 675 Iop_CalcFPRF, /* Calc 5 fpscr[FPRF] bits (Class, <, =, >, Unord) 676 from FP result */ 677 678 /* ------------------ 32-bit SIMD Integer ------------------ */ 679 680 /* 16x2 add/sub, also signed/unsigned saturating variants */ 681 Iop_Add16x2, Iop_Sub16x2, 682 Iop_QAdd16Sx2, Iop_QAdd16Ux2, 683 Iop_QSub16Sx2, Iop_QSub16Ux2, 684 685 /* 16x2 signed/unsigned halving add/sub. For each lane, these 686 compute bits 16:1 of (eg) sx(argL) + sx(argR), 687 or zx(argL) - zx(argR) etc. */ 688 Iop_HAdd16Ux2, Iop_HAdd16Sx2, 689 Iop_HSub16Ux2, Iop_HSub16Sx2, 690 691 /* 8x4 add/sub, also signed/unsigned saturating variants */ 692 Iop_Add8x4, Iop_Sub8x4, 693 Iop_QAdd8Sx4, Iop_QAdd8Ux4, 694 Iop_QSub8Sx4, Iop_QSub8Ux4, 695 696 /* 8x4 signed/unsigned halving add/sub. For each lane, these 697 compute bits 8:1 of (eg) sx(argL) + sx(argR), 698 or zx(argL) - zx(argR) etc. */ 699 Iop_HAdd8Ux4, Iop_HAdd8Sx4, 700 Iop_HSub8Ux4, Iop_HSub8Sx4, 701 702 /* 8x4 sum of absolute unsigned differences. */ 703 Iop_Sad8Ux4, 704 705 /* MISC (vector integer cmp != 0) */ 706 Iop_CmpNEZ16x2, Iop_CmpNEZ8x4, 707 708 /* ------------------ 64-bit SIMD FP ------------------------ */ 709 710 /* Convertion to/from int */ 711 Iop_I32UtoFx2, Iop_I32StoFx2, /* I32x4 -> F32x4 */ 712 Iop_FtoI32Ux2_RZ, Iop_FtoI32Sx2_RZ, /* F32x4 -> I32x4 */ 713 /* Fixed32 format is floating-point number with fixed number of fraction 714 bits. The number of fraction bits is passed as a second argument of 715 type I8. */ 716 Iop_F32ToFixed32Ux2_RZ, Iop_F32ToFixed32Sx2_RZ, /* fp -> fixed-point */ 717 Iop_Fixed32UToF32x2_RN, Iop_Fixed32SToF32x2_RN, /* fixed-point -> fp */ 718 719 /* Binary operations */ 720 Iop_Max32Fx2, Iop_Min32Fx2, 721 /* Pairwise Min and Max. See integer pairwise operations for more 722 details. */ 723 Iop_PwMax32Fx2, Iop_PwMin32Fx2, 724 /* Note: For the following compares, the arm front-end assumes a 725 nan in a lane of either argument returns zero for that lane. */ 726 Iop_CmpEQ32Fx2, Iop_CmpGT32Fx2, Iop_CmpGE32Fx2, 727 728 /* Vector Reciprocal Estimate finds an approximate reciprocal of each 729 element in the operand vector, and places the results in the destination 730 vector. */ 731 Iop_Recip32Fx2, 732 733 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2). 734 Note, that if one of the arguments is zero and another one is infinity 735 of arbitrary sign the result of the operation is 2.0. */ 736 Iop_Recps32Fx2, 737 738 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal 739 square root of each element in the operand vector. */ 740 Iop_Rsqrte32Fx2, 741 742 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0. 743 Note, that of one of the arguments is zero and another one is infiinty 744 of arbitrary sign the result of the operation is 1.5. */ 745 Iop_Rsqrts32Fx2, 746 747 /* Unary */ 748 Iop_Neg32Fx2, Iop_Abs32Fx2, 749 750 /* ------------------ 64-bit SIMD Integer. ------------------ */ 751 752 /* MISC (vector integer cmp != 0) */ 753 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2, 754 755 /* ADDITION (normal / unsigned sat / signed sat) */ 756 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2, 757 Iop_QAdd8Ux8, Iop_QAdd16Ux4, Iop_QAdd32Ux2, Iop_QAdd64Ux1, 758 Iop_QAdd8Sx8, Iop_QAdd16Sx4, Iop_QAdd32Sx2, Iop_QAdd64Sx1, 759 760 /* PAIRWISE operations */ 761 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) = 762 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */ 763 Iop_PwAdd8x8, Iop_PwAdd16x4, Iop_PwAdd32x2, 764 Iop_PwMax8Sx8, Iop_PwMax16Sx4, Iop_PwMax32Sx2, 765 Iop_PwMax8Ux8, Iop_PwMax16Ux4, Iop_PwMax32Ux2, 766 Iop_PwMin8Sx8, Iop_PwMin16Sx4, Iop_PwMin32Sx2, 767 Iop_PwMin8Ux8, Iop_PwMin16Ux4, Iop_PwMin32Ux2, 768 /* Longening variant is unary. The resulting vector contains two times 769 less elements than operand, but they are two times wider. 770 Example: 771 Iop_PAddL16Ux4( [a,b,c,d] ) = [a+b,c+d] 772 where a+b and c+d are unsigned 32-bit values. */ 773 Iop_PwAddL8Ux8, Iop_PwAddL16Ux4, Iop_PwAddL32Ux2, 774 Iop_PwAddL8Sx8, Iop_PwAddL16Sx4, Iop_PwAddL32Sx2, 775 776 /* SUBTRACTION (normal / unsigned sat / signed sat) */ 777 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2, 778 Iop_QSub8Ux8, Iop_QSub16Ux4, Iop_QSub32Ux2, Iop_QSub64Ux1, 779 Iop_QSub8Sx8, Iop_QSub16Sx4, Iop_QSub32Sx2, Iop_QSub64Sx1, 780 781 /* ABSOLUTE VALUE */ 782 Iop_Abs8x8, Iop_Abs16x4, Iop_Abs32x2, 783 784 /* MULTIPLICATION (normal / high half of signed/unsigned / plynomial ) */ 785 Iop_Mul8x8, Iop_Mul16x4, Iop_Mul32x2, 786 Iop_Mul32Fx2, 787 Iop_MulHi16Ux4, 788 Iop_MulHi16Sx4, 789 /* Plynomial multiplication treats it's arguments as coefficients of 790 polynoms over {0, 1}. */ 791 Iop_PolynomialMul8x8, 792 793 /* Vector Saturating Doubling Multiply Returning High Half and 794 Vector Saturating Rounding Doubling Multiply Returning High Half */ 795 /* These IROp's multiply corresponding elements in two vectors, double 796 the results, and place the most significant half of the final results 797 in the destination vector. The results are truncated or rounded. If 798 any of the results overflow, they are saturated. */ 799 Iop_QDMulHi16Sx4, Iop_QDMulHi32Sx2, 800 Iop_QRDMulHi16Sx4, Iop_QRDMulHi32Sx2, 801 802 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 803 Iop_Avg8Ux8, 804 Iop_Avg16Ux4, 805 806 /* MIN/MAX */ 807 Iop_Max8Sx8, Iop_Max16Sx4, Iop_Max32Sx2, 808 Iop_Max8Ux8, Iop_Max16Ux4, Iop_Max32Ux2, 809 Iop_Min8Sx8, Iop_Min16Sx4, Iop_Min32Sx2, 810 Iop_Min8Ux8, Iop_Min16Ux4, Iop_Min32Ux2, 811 812 /* COMPARISON */ 813 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2, 814 Iop_CmpGT8Ux8, Iop_CmpGT16Ux4, Iop_CmpGT32Ux2, 815 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2, 816 817 /* COUNT ones / leading zeroes / leading sign bits (not including topmost 818 bit) */ 819 Iop_Cnt8x8, 820 Iop_Clz8Sx8, Iop_Clz16Sx4, Iop_Clz32Sx2, 821 Iop_Cls8Sx8, Iop_Cls16Sx4, Iop_Cls32Sx2, 822 823 /* VECTOR x VECTOR SHIFT / ROTATE */ 824 Iop_Shl8x8, Iop_Shl16x4, Iop_Shl32x2, 825 Iop_Shr8x8, Iop_Shr16x4, Iop_Shr32x2, 826 Iop_Sar8x8, Iop_Sar16x4, Iop_Sar32x2, 827 Iop_Sal8x8, Iop_Sal16x4, Iop_Sal32x2, Iop_Sal64x1, 828 829 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 830 Iop_ShlN8x8, Iop_ShlN16x4, Iop_ShlN32x2, 831 Iop_ShrN8x8, Iop_ShrN16x4, Iop_ShrN32x2, 832 Iop_SarN8x8, Iop_SarN16x4, Iop_SarN32x2, 833 834 /* VECTOR x VECTOR SATURATING SHIFT */ 835 Iop_QShl8x8, Iop_QShl16x4, Iop_QShl32x2, Iop_QShl64x1, 836 Iop_QSal8x8, Iop_QSal16x4, Iop_QSal32x2, Iop_QSal64x1, 837 /* VECTOR x INTEGER SATURATING SHIFT */ 838 Iop_QShlN8Sx8, Iop_QShlN16Sx4, Iop_QShlN32Sx2, Iop_QShlN64Sx1, 839 Iop_QShlN8x8, Iop_QShlN16x4, Iop_QShlN32x2, Iop_QShlN64x1, 840 Iop_QSalN8x8, Iop_QSalN16x4, Iop_QSalN32x2, Iop_QSalN64x1, 841 842 /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */ 843 Iop_QNarrow16Ux4, 844 Iop_QNarrow16Sx4, 845 Iop_QNarrow32Sx2, 846 847 /* INTERLEAVING */ 848 /* Interleave lanes from low or high halves of 849 operands. Most-significant result lane is from the left 850 arg. */ 851 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2, 852 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2, 853 /* Interleave odd/even lanes of operands. Most-significant result lane 854 is from the left arg. Note that Interleave{Odd,Even}Lanes32x2 are 855 identical to Interleave{HI,LO}32x2 and so are omitted.*/ 856 Iop_InterleaveOddLanes8x8, Iop_InterleaveEvenLanes8x8, 857 Iop_InterleaveOddLanes16x4, Iop_InterleaveEvenLanes16x4, 858 859 860 /* CONCATENATION -- build a new value by concatenating either 861 the even or odd lanes of both operands. Note that 862 Cat{Odd,Even}Lanes32x2 are identical to Interleave{HI,LO}32x2 863 and so are omitted. */ 864 Iop_CatOddLanes8x8, Iop_CatOddLanes16x4, 865 Iop_CatEvenLanes8x8, Iop_CatEvenLanes16x4, 866 867 /* GET / SET elements of VECTOR 868 GET is binop (I64, I8) -> I<elem_size> 869 SET is triop (I64, I8, I<elem_size>) -> I64 */ 870 /* Note: the arm back-end handles only constant second argument */ 871 Iop_GetElem8x8, Iop_GetElem16x4, Iop_GetElem32x2, 872 Iop_SetElem8x8, Iop_SetElem16x4, Iop_SetElem32x2, 873 874 /* DUPLICATING -- copy value to all lanes */ 875 Iop_Dup8x8, Iop_Dup16x4, Iop_Dup32x2, 876 877 /* EXTRACT -- copy 8-arg3 highest bytes from arg1 to 8-arg3 lowest bytes 878 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of 879 result. 880 It is a triop: (I64, I64, I8) -> I64 */ 881 /* Note: the arm back-end handles only constant third argumnet. */ 882 Iop_Extract64, 883 884 /* REVERSE the order of elements in each Half-words, Words, 885 Double-words */ 886 /* Examples: 887 Reverse16_8x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g] 888 Reverse32_8x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] 889 Reverse64_8x8([a,b,c,d,e,f,g,h]) = [h,g,f,e,d,c,b,a] */ 890 Iop_Reverse16_8x8, 891 Iop_Reverse32_8x8, Iop_Reverse32_16x4, 892 Iop_Reverse64_8x8, Iop_Reverse64_16x4, Iop_Reverse64_32x2, 893 894 /* PERMUTING -- copy src bytes to dst, 895 as indexed by control vector bytes: 896 for i in 0 .. 7 . result[i] = argL[ argR[i] ] 897 argR[i] values may only be in the range 0 .. 7, else behaviour 898 is undefined. */ 899 Iop_Perm8x8, 900 901 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate 902 See floating-point equiwalents for details. */ 903 Iop_Recip32x2, Iop_Rsqrte32x2, 904 905 /* ------------------ 128-bit SIMD FP. ------------------ */ 906 907 /* --- 32x4 vector FP --- */ 908 909 /* binary */ 910 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 911 Iop_Max32Fx4, Iop_Min32Fx4, 912 Iop_Add32Fx2, Iop_Sub32Fx2, 913 /* Note: For the following compares, the ppc and arm front-ends assume a 914 nan in a lane of either argument returns zero for that lane. */ 915 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 916 Iop_CmpGT32Fx4, Iop_CmpGE32Fx4, 917 918 /* Vector Absolute */ 919 Iop_Abs32Fx4, 920 921 /* Pairwise Max and Min. See integer pairwise operations for details. */ 922 Iop_PwMax32Fx4, Iop_PwMin32Fx4, 923 924 /* unary */ 925 Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, 926 Iop_Neg32Fx4, 927 928 /* Vector Reciprocal Estimate finds an approximate reciprocal of each 929 element in the operand vector, and places the results in the destination 930 vector. */ 931 Iop_Recip32Fx4, 932 933 /* Vector Reciprocal Step computes (2.0 - arg1 * arg2). 934 Note, that if one of the arguments is zero and another one is infinity 935 of arbitrary sign the result of the operation is 2.0. */ 936 Iop_Recps32Fx4, 937 938 /* Vector Reciprocal Square Root Estimate finds an approximate reciprocal 939 square root of each element in the operand vector. */ 940 Iop_Rsqrte32Fx4, 941 942 /* Vector Reciprocal Square Root Step computes (3.0 - arg1 * arg2) / 2.0. 943 Note, that of one of the arguments is zero and another one is infiinty 944 of arbitrary sign the result of the operation is 1.5. */ 945 Iop_Rsqrts32Fx4, 946 947 948 /* --- Int to/from FP conversion --- */ 949 /* Unlike the standard fp conversions, these irops take no 950 rounding mode argument. Instead the irop trailers _R{M,P,N,Z} 951 indicate the mode: {-inf, +inf, nearest, zero} respectively. */ 952 Iop_I32UtoFx4, Iop_I32StoFx4, /* I32x4 -> F32x4 */ 953 Iop_FtoI32Ux4_RZ, Iop_FtoI32Sx4_RZ, /* F32x4 -> I32x4 */ 954 Iop_QFtoI32Ux4_RZ, Iop_QFtoI32Sx4_RZ, /* F32x4 -> I32x4 (with saturation) */ 955 Iop_RoundF32x4_RM, Iop_RoundF32x4_RP, /* round to fp integer */ 956 Iop_RoundF32x4_RN, Iop_RoundF32x4_RZ, /* round to fp integer */ 957 /* Fixed32 format is floating-point number with fixed number of fraction 958 bits. The number of fraction bits is passed as a second argument of 959 type I8. */ 960 Iop_F32ToFixed32Ux4_RZ, Iop_F32ToFixed32Sx4_RZ, /* fp -> fixed-point */ 961 Iop_Fixed32UToF32x4_RN, Iop_Fixed32SToF32x4_RN, /* fixed-point -> fp */ 962 963 /* --- Single to/from half conversion --- */ 964 Iop_F32toF16x4, Iop_F16toF32x4, /* F32x4 <-> F16x4 */ 965 966 /* --- 32x4 lowest-lane-only scalar FP --- */ 967 968 /* In binary cases, upper 3/4 is copied from first operand. In 969 unary cases, upper 3/4 is copied from the operand. */ 970 971 /* binary */ 972 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 973 Iop_Max32F0x4, Iop_Min32F0x4, 974 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 975 976 /* unary */ 977 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, 978 979 /* --- 64x2 vector FP --- */ 980 981 /* binary */ 982 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 983 Iop_Max64Fx2, Iop_Min64Fx2, 984 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 985 986 /* unary */ 987 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2, 988 989 /* --- 64x2 lowest-lane-only scalar FP --- */ 990 991 /* In binary cases, upper half is copied from first operand. In 992 unary cases, upper half is copied from the operand. */ 993 994 /* binary */ 995 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 996 Iop_Max64F0x2, Iop_Min64F0x2, 997 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 998 999 /* unary */ 1000 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2, 1001 1002 /* --- pack / unpack --- */ 1003 1004 /* 64 <-> 128 bit vector */ 1005 Iop_V128to64, // :: V128 -> I64, low half 1006 Iop_V128HIto64, // :: V128 -> I64, high half 1007 Iop_64HLtoV128, // :: (I64,I64) -> V128 1008 1009 Iop_64UtoV128, 1010 Iop_SetV128lo64, 1011 1012 /* 32 <-> 128 bit vector */ 1013 Iop_32UtoV128, 1014 Iop_V128to32, // :: V128 -> I32, lowest lane 1015 Iop_SetV128lo32, // :: (V128,I32) -> V128 1016 1017 /* ------------------ 128-bit SIMD Integer. ------------------ */ 1018 1019 /* BITWISE OPS */ 1020 Iop_NotV128, 1021 Iop_AndV128, Iop_OrV128, Iop_XorV128, 1022 1023 /* VECTOR SHIFT (shift amt :: Ity_I8) */ 1024 Iop_ShlV128, Iop_ShrV128, 1025 1026 /* MISC (vector integer cmp != 0) */ 1027 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2, 1028 1029 /* ADDITION (normal / unsigned sat / signed sat) */ 1030 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2, 1031 Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4, Iop_QAdd64Ux2, 1032 Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4, Iop_QAdd64Sx2, 1033 1034 /* SUBTRACTION (normal / unsigned sat / signed sat) */ 1035 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2, 1036 Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4, Iop_QSub64Ux2, 1037 Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4, Iop_QSub64Sx2, 1038 1039 /* MULTIPLICATION (normal / high half of signed/unsigned) */ 1040 Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4, 1041 Iop_MulHi16Ux8, Iop_MulHi32Ux4, 1042 Iop_MulHi16Sx8, Iop_MulHi32Sx4, 1043 /* (widening signed/unsigned of even lanes, with lowest lane=zero) */ 1044 Iop_MullEven8Ux16, Iop_MullEven16Ux8, 1045 Iop_MullEven8Sx16, Iop_MullEven16Sx8, 1046 /* FIXME: document these */ 1047 Iop_Mull8Ux8, Iop_Mull8Sx8, 1048 Iop_Mull16Ux4, Iop_Mull16Sx4, 1049 Iop_Mull32Ux2, Iop_Mull32Sx2, 1050 /* Vector Saturating Doubling Multiply Returning High Half and 1051 Vector Saturating Rounding Doubling Multiply Returning High Half */ 1052 /* These IROp's multiply corresponding elements in two vectors, double 1053 the results, and place the most significant half of the final results 1054 in the destination vector. The results are truncated or rounded. If 1055 any of the results overflow, they are saturated. */ 1056 Iop_QDMulHi16Sx8, Iop_QDMulHi32Sx4, 1057 Iop_QRDMulHi16Sx8, Iop_QRDMulHi32Sx4, 1058 /* Doubling saturating multiplication (long) (I64, I64) -> V128 */ 1059 Iop_QDMulLong16Sx4, Iop_QDMulLong32Sx2, 1060 /* Plynomial multiplication treats it's arguments as coefficients of 1061 polynoms over {0, 1}. */ 1062 Iop_PolynomialMul8x16, /* (V128, V128) -> V128 */ 1063 Iop_PolynomialMull8x8, /* (I64, I64) -> V128 */ 1064 1065 /* PAIRWISE operations */ 1066 /* Iop_PwFoo16x4( [a,b,c,d], [e,f,g,h] ) = 1067 [Foo16(a,b), Foo16(c,d), Foo16(e,f), Foo16(g,h)] */ 1068 Iop_PwAdd8x16, Iop_PwAdd16x8, Iop_PwAdd32x4, 1069 Iop_PwAdd32Fx2, 1070 /* Longening variant is unary. The resulting vector contains two times 1071 less elements than operand, but they are two times wider. 1072 Example: 1073 Iop_PwAddL16Ux4( [a,b,c,d] ) = [a+b,c+d] 1074 where a+b and c+d are unsigned 32-bit values. */ 1075 Iop_PwAddL8Ux16, Iop_PwAddL16Ux8, Iop_PwAddL32Ux4, 1076 Iop_PwAddL8Sx16, Iop_PwAddL16Sx8, Iop_PwAddL32Sx4, 1077 1078 /* ABSOLUTE VALUE */ 1079 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, 1080 1081 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 1082 Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, 1083 Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, 1084 1085 /* MIN/MAX */ 1086 Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, 1087 Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, 1088 Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, 1089 Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, 1090 1091 /* COMPARISON */ 1092 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, 1093 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, Iop_CmpGT64Sx2, 1094 Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, 1095 1096 /* COUNT ones / leading zeroes / leading sign bits (not including topmost 1097 bit) */ 1098 Iop_Cnt8x16, 1099 Iop_Clz8Sx16, Iop_Clz16Sx8, Iop_Clz32Sx4, 1100 Iop_Cls8Sx16, Iop_Cls16Sx8, Iop_Cls32Sx4, 1101 1102 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 1103 Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2, 1104 Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2, 1105 Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2, 1106 1107 /* VECTOR x VECTOR SHIFT / ROTATE */ 1108 Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2, 1109 Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2, 1110 Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2, 1111 Iop_Sal8x16, Iop_Sal16x8, Iop_Sal32x4, Iop_Sal64x2, 1112 Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, 1113 1114 /* VECTOR x VECTOR SATURATING SHIFT */ 1115 Iop_QShl8x16, Iop_QShl16x8, Iop_QShl32x4, Iop_QShl64x2, 1116 Iop_QSal8x16, Iop_QSal16x8, Iop_QSal32x4, Iop_QSal64x2, 1117 /* VECTOR x INTEGER SATURATING SHIFT */ 1118 Iop_QShlN8Sx16, Iop_QShlN16Sx8, Iop_QShlN32Sx4, Iop_QShlN64Sx2, 1119 Iop_QShlN8x16, Iop_QShlN16x8, Iop_QShlN32x4, Iop_QShlN64x2, 1120 Iop_QSalN8x16, Iop_QSalN16x8, Iop_QSalN32x4, Iop_QSalN64x2, 1121 1122 /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */ 1123 /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */ 1124 Iop_QNarrow16Ux8, Iop_QNarrow32Ux4, 1125 Iop_QNarrow16Sx8, Iop_QNarrow32Sx4, 1126 Iop_Narrow16x8, Iop_Narrow32x4, 1127 /* Shortening V128->I64, lo half from each element */ 1128 Iop_Shorten16x8, Iop_Shorten32x4, Iop_Shorten64x2, 1129 /* Saturating shortening from signed source to signed/unsigned destination */ 1130 Iop_QShortenS16Sx8, Iop_QShortenS32Sx4, Iop_QShortenS64Sx2, 1131 Iop_QShortenU16Sx8, Iop_QShortenU32Sx4, Iop_QShortenU64Sx2, 1132 /* Saturating shortening from unsigned source to unsigned destination */ 1133 Iop_QShortenU16Ux8, Iop_QShortenU32Ux4, Iop_QShortenU64Ux2, 1134 1135 /* WIDENING */ 1136 /* Longening --- sign or zero extends each element of the argument 1137 vector to the twice original size. The resulting vector consists of 1138 the same number of elements but each element and the vector itself 1139 are two times wider. 1140 All operations are I64->V128. 1141 Example 1142 Iop_Longen32Sx2( [a, b] ) = [c, d] 1143 where c = Iop_32Sto64(a) and d = Iop_32Sto64(b) */ 1144 Iop_Longen8Ux8, Iop_Longen16Ux4, Iop_Longen32Ux2, 1145 Iop_Longen8Sx8, Iop_Longen16Sx4, Iop_Longen32Sx2, 1146 1147 /* INTERLEAVING */ 1148 /* Interleave lanes from low or high halves of 1149 operands. Most-significant result lane is from the left 1150 arg. */ 1151 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8, 1152 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2, 1153 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, 1154 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2, 1155 /* Interleave odd/even lanes of operands. Most-significant result lane 1156 is from the left arg. */ 1157 Iop_InterleaveOddLanes8x16, Iop_InterleaveEvenLanes8x16, 1158 Iop_InterleaveOddLanes16x8, Iop_InterleaveEvenLanes16x8, 1159 Iop_InterleaveOddLanes32x4, Iop_InterleaveEvenLanes32x4, 1160 1161 /* CONCATENATION -- build a new value by concatenating either 1162 the even or odd lanes of both operands. */ 1163 Iop_CatOddLanes8x16, Iop_CatOddLanes16x8, Iop_CatOddLanes32x4, 1164 Iop_CatEvenLanes8x16, Iop_CatEvenLanes16x8, Iop_CatEvenLanes32x4, 1165 1166 /* GET elements of VECTOR 1167 GET is binop (V128, I8) -> I<elem_size> */ 1168 /* Note: the arm back-end handles only constant second argument. */ 1169 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4, Iop_GetElem64x2, 1170 1171 /* DUPLICATING -- copy value to all lanes */ 1172 Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4, 1173 1174 /* EXTRACT -- copy 16-arg3 highest bytes from arg1 to 16-arg3 lowest bytes 1175 of result and arg3 lowest bytes of arg2 to arg3 highest bytes of 1176 result. 1177 It is a triop: (V128, V128, I8) -> V128 */ 1178 /* Note: the ARM back end handles only constant arg3 in this operation. */ 1179 Iop_ExtractV128, 1180 1181 /* REVERSE the order of elements in each Half-words, Words, 1182 Double-words */ 1183 /* Examples: 1184 Reverse32_16x8([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g] 1185 Reverse64_16x8([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e] */ 1186 Iop_Reverse16_8x16, 1187 Iop_Reverse32_8x16, Iop_Reverse32_16x8, 1188 Iop_Reverse64_8x16, Iop_Reverse64_16x8, Iop_Reverse64_32x4, 1189 1190 /* PERMUTING -- copy src bytes to dst, 1191 as indexed by control vector bytes: 1192 for i in 0 .. 15 . result[i] = argL[ argR[i] ] 1193 argR[i] values may only be in the range 0 .. 15, else behaviour 1194 is undefined. */ 1195 Iop_Perm8x16, 1196 1197 /* Vector Reciprocal Estimate and Vector Reciprocal Square Root Estimate 1198 See floating-point equiwalents for details. */ 1199 Iop_Recip32x4, Iop_Rsqrte32x4 1200 } 1201 IROp; 1202 1203/* Pretty-print an op. */ 1204extern void ppIROp ( IROp ); 1205 1206 1207/* Encoding of IEEE754-specified rounding modes. This is the same as 1208 the encoding used by Intel IA32 to indicate x87 rounding mode. 1209 Note, various front and back ends rely on the actual numerical 1210 values of these, so do not change them. */ 1211typedef 1212 enum { 1213 Irrm_NEAREST = 0, 1214 Irrm_NegINF = 1, 1215 Irrm_PosINF = 2, 1216 Irrm_ZERO = 3 1217 } 1218 IRRoundingMode; 1219 1220/* Floating point comparison result values, as created by Iop_CmpF64. 1221 This is also derived from what IA32 does. */ 1222typedef 1223 enum { 1224 Ircr_UN = 0x45, 1225 Ircr_LT = 0x01, 1226 Ircr_GT = 0x00, 1227 Ircr_EQ = 0x40 1228 } 1229 IRCmpF64Result; 1230 1231 1232/* ------------------ Expressions ------------------ */ 1233 1234/* The different kinds of expressions. Their meaning is explained below 1235 in the comments for IRExpr. */ 1236typedef 1237 enum { 1238 Iex_Binder=0x15000, 1239 Iex_Get, 1240 Iex_GetI, 1241 Iex_RdTmp, 1242 Iex_Qop, 1243 Iex_Triop, 1244 Iex_Binop, 1245 Iex_Unop, 1246 Iex_Load, 1247 Iex_Const, 1248 Iex_Mux0X, 1249 Iex_CCall 1250 } 1251 IRExprTag; 1252 1253/* An expression. Stored as a tagged union. 'tag' indicates what kind 1254 of expression this is. 'Iex' is the union that holds the fields. If 1255 an IRExpr 'e' has e.tag equal to Iex_Load, then it's a load 1256 expression, and the fields can be accessed with 1257 'e.Iex.Load.<fieldname>'. 1258 1259 For each kind of expression, we show what it looks like when 1260 pretty-printed with ppIRExpr(). 1261*/ 1262typedef 1263 struct _IRExpr 1264 IRExpr; 1265 1266struct _IRExpr { 1267 IRExprTag tag; 1268 union { 1269 /* Used only in pattern matching within Vex. Should not be seen 1270 outside of Vex. */ 1271 struct { 1272 Int binder; 1273 } Binder; 1274 1275 /* Read a guest register, at a fixed offset in the guest state. 1276 ppIRExpr output: GET:<ty>(<offset>), eg. GET:I32(0) 1277 */ 1278 struct { 1279 Int offset; /* Offset into the guest state */ 1280 IRType ty; /* Type of the value being read */ 1281 } Get; 1282 1283 /* Read a guest register at a non-fixed offset in the guest 1284 state. This allows circular indexing into parts of the guest 1285 state, which is essential for modelling situations where the 1286 identity of guest registers is not known until run time. One 1287 example is the x87 FP register stack. 1288 1289 The part of the guest state to be treated as a circular array 1290 is described in the IRRegArray 'descr' field. It holds the 1291 offset of the first element in the array, the type of each 1292 element, and the number of elements. 1293 1294 The array index is indicated rather indirectly, in a way 1295 which makes optimisation easy: as the sum of variable part 1296 (the 'ix' field) and a constant offset (the 'bias' field). 1297 1298 Since the indexing is circular, the actual array index to use 1299 is computed as (ix + bias) % num-of-elems-in-the-array. 1300 1301 Here's an example. The description 1302 1303 (96:8xF64)[t39,-7] 1304 1305 describes an array of 8 F64-typed values, the 1306 guest-state-offset of the first being 96. This array is 1307 being indexed at (t39 - 7) % 8. 1308 1309 It is important to get the array size/type exactly correct 1310 since IR optimisation looks closely at such info in order to 1311 establish aliasing/non-aliasing between seperate GetI and 1312 PutI events, which is used to establish when they can be 1313 reordered, etc. Putting incorrect info in will lead to 1314 obscure IR optimisation bugs. 1315 1316 ppIRExpr output: GETI<descr>[<ix>,<bias] 1317 eg. GETI(128:8xI8)[t1,0] 1318 */ 1319 struct { 1320 IRRegArray* descr; /* Part of guest state treated as circular */ 1321 IRExpr* ix; /* Variable part of index into array */ 1322 Int bias; /* Constant offset part of index into array */ 1323 } GetI; 1324 1325 /* The value held by a temporary. 1326 ppIRExpr output: t<tmp>, eg. t1 1327 */ 1328 struct { 1329 IRTemp tmp; /* The temporary number */ 1330 } RdTmp; 1331 1332 /* A quaternary operation. 1333 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>, <arg4>), 1334 eg. MAddF64r32(t1, t2, t3, t4) 1335 */ 1336 struct { 1337 IROp op; /* op-code */ 1338 IRExpr* arg1; /* operand 1 */ 1339 IRExpr* arg2; /* operand 2 */ 1340 IRExpr* arg3; /* operand 3 */ 1341 IRExpr* arg4; /* operand 4 */ 1342 } Qop; 1343 1344 /* A ternary operation. 1345 ppIRExpr output: <op>(<arg1>, <arg2>, <arg3>), 1346 eg. MulF64(1, 2.0, 3.0) 1347 */ 1348 struct { 1349 IROp op; /* op-code */ 1350 IRExpr* arg1; /* operand 1 */ 1351 IRExpr* arg2; /* operand 2 */ 1352 IRExpr* arg3; /* operand 3 */ 1353 } Triop; 1354 1355 /* A binary operation. 1356 ppIRExpr output: <op>(<arg1>, <arg2>), eg. Add32(t1,t2) 1357 */ 1358 struct { 1359 IROp op; /* op-code */ 1360 IRExpr* arg1; /* operand 1 */ 1361 IRExpr* arg2; /* operand 2 */ 1362 } Binop; 1363 1364 /* A unary operation. 1365 ppIRExpr output: <op>(<arg>), eg. Neg8(t1) 1366 */ 1367 struct { 1368 IROp op; /* op-code */ 1369 IRExpr* arg; /* operand */ 1370 } Unop; 1371 1372 /* A load from memory -- a normal load, not a load-linked. 1373 Load-Linkeds (and Store-Conditionals) are instead represented 1374 by IRStmt.LLSC since Load-Linkeds have side effects and so 1375 are not semantically valid IRExpr's. 1376 ppIRExpr output: LD<end>:<ty>(<addr>), eg. LDle:I32(t1) 1377 */ 1378 struct { 1379 IREndness end; /* Endian-ness of the load */ 1380 IRType ty; /* Type of the loaded value */ 1381 IRExpr* addr; /* Address being loaded from */ 1382 } Load; 1383 1384 /* A constant-valued expression. 1385 ppIRExpr output: <con>, eg. 0x4:I32 1386 */ 1387 struct { 1388 IRConst* con; /* The constant itself */ 1389 } Const; 1390 1391 /* A call to a pure (no side-effects) helper C function. 1392 1393 With the 'cee' field, 'name' is the function's name. It is 1394 only used for pretty-printing purposes. The address to call 1395 (host address, of course) is stored in the 'addr' field 1396 inside 'cee'. 1397 1398 The 'args' field is a NULL-terminated array of arguments. 1399 The stated return IRType, and the implied argument types, 1400 must match that of the function being called well enough so 1401 that the back end can actually generate correct code for the 1402 call. 1403 1404 The called function **must** satisfy the following: 1405 1406 * no side effects -- must be a pure function, the result of 1407 which depends only on the passed parameters. 1408 1409 * it may not look at, nor modify, any of the guest state 1410 since that would hide guest state transitions from 1411 instrumenters 1412 1413 * it may not access guest memory, since that would hide 1414 guest memory transactions from the instrumenters 1415 1416 This is restrictive, but makes the semantics clean, and does 1417 not interfere with IR optimisation. 1418 1419 If you want to call a helper which can mess with guest state 1420 and/or memory, instead use Ist_Dirty. This is a lot more 1421 flexible, but you have to give a bunch of details about what 1422 the helper does (and you better be telling the truth, 1423 otherwise any derived instrumentation will be wrong). Also 1424 Ist_Dirty inhibits various IR optimisations and so can cause 1425 quite poor code to be generated. Try to avoid it. 1426 1427 ppIRExpr output: <cee>(<args>):<retty> 1428 eg. foo{0x80489304}(t1, t2):I32 1429 */ 1430 struct { 1431 IRCallee* cee; /* Function to call. */ 1432 IRType retty; /* Type of return value. */ 1433 IRExpr** args; /* Vector of argument expressions. */ 1434 } CCall; 1435 1436 /* A ternary if-then-else operator. It returns expr0 if cond is 1437 zero, exprX otherwise. Note that it is STRICT, ie. both 1438 expr0 and exprX are evaluated in all cases. 1439 1440 ppIRExpr output: Mux0X(<cond>,<expr0>,<exprX>), 1441 eg. Mux0X(t6,t7,t8) 1442 */ 1443 struct { 1444 IRExpr* cond; /* Condition */ 1445 IRExpr* expr0; /* True expression */ 1446 IRExpr* exprX; /* False expression */ 1447 } Mux0X; 1448 } Iex; 1449}; 1450 1451/* Expression constructors. */ 1452extern IRExpr* IRExpr_Binder ( Int binder ); 1453extern IRExpr* IRExpr_Get ( Int off, IRType ty ); 1454extern IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ); 1455extern IRExpr* IRExpr_RdTmp ( IRTemp tmp ); 1456extern IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2, 1457 IRExpr* arg3, IRExpr* arg4 ); 1458extern IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1, 1459 IRExpr* arg2, IRExpr* arg3 ); 1460extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 1461extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 1462extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ); 1463extern IRExpr* IRExpr_Const ( IRConst* con ); 1464extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ); 1465extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ); 1466 1467/* Deep-copy an IRExpr. */ 1468extern IRExpr* deepCopyIRExpr ( IRExpr* ); 1469 1470/* Pretty-print an IRExpr. */ 1471extern void ppIRExpr ( IRExpr* ); 1472 1473/* NULL-terminated IRExpr vector constructors, suitable for 1474 use as arg lists in clean/dirty helper calls. */ 1475extern IRExpr** mkIRExprVec_0 ( void ); 1476extern IRExpr** mkIRExprVec_1 ( IRExpr* ); 1477extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* ); 1478extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* ); 1479extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* ); 1480extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 1481 IRExpr* ); 1482extern IRExpr** mkIRExprVec_6 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 1483 IRExpr*, IRExpr* ); 1484extern IRExpr** mkIRExprVec_7 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 1485 IRExpr*, IRExpr*, IRExpr* ); 1486extern IRExpr** mkIRExprVec_8 ( IRExpr*, IRExpr*, IRExpr*, IRExpr*, 1487 IRExpr*, IRExpr*, IRExpr*, IRExpr*); 1488 1489/* IRExpr copiers: 1490 - shallowCopy: shallow-copy (ie. create a new vector that shares the 1491 elements with the original). 1492 - deepCopy: deep-copy (ie. create a completely new vector). */ 1493extern IRExpr** shallowCopyIRExprVec ( IRExpr** ); 1494extern IRExpr** deepCopyIRExprVec ( IRExpr** ); 1495 1496/* Make a constant expression from the given host word taking into 1497 account (of course) the host word size. */ 1498extern IRExpr* mkIRExpr_HWord ( HWord ); 1499 1500/* Convenience function for constructing clean helper calls. */ 1501extern 1502IRExpr* mkIRExprCCall ( IRType retty, 1503 Int regparms, HChar* name, void* addr, 1504 IRExpr** args ); 1505 1506 1507/* Convenience functions for atoms (IRExprs which are either Iex_Tmp or 1508 * Iex_Const). */ 1509static inline Bool isIRAtom ( IRExpr* e ) { 1510 return toBool(e->tag == Iex_RdTmp || e->tag == Iex_Const); 1511} 1512 1513/* Are these two IR atoms identical? Causes an assertion 1514 failure if they are passed non-atoms. */ 1515extern Bool eqIRAtom ( IRExpr*, IRExpr* ); 1516 1517 1518/* ------------------ Jump kinds ------------------ */ 1519 1520/* This describes hints which can be passed to the dispatcher at guest 1521 control-flow transfer points. 1522 1523 Re Ijk_TInval: the guest state _must_ have two pseudo-registers, 1524 guest_TISTART and guest_TILEN, which specify the start and length 1525 of the region to be invalidated. These are both the size of a 1526 guest word. It is the responsibility of the relevant toIR.c to 1527 ensure that these are filled in with suitable values before issuing 1528 a jump of kind Ijk_TInval. 1529 1530 Re Ijk_EmWarn and Ijk_EmFail: the guest state must have a 1531 pseudo-register guest_EMWARN, which is 32-bits regardless of the 1532 host or guest word size. That register should be made to hold an 1533 EmWarn_* value to indicate the reason for the exit. 1534 1535 In the case of Ijk_EmFail, the exit is fatal (Vex-generated code 1536 cannot continue) and so the jump destination can be anything. 1537 1538 Re Ijk_Sys_ (syscall jumps): the guest state must have a 1539 pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest 1540 word. Front ends should set this to be the IP at the most recently 1541 executed kernel-entering (system call) instruction. This makes it 1542 very much easier (viz, actually possible at all) to back up the 1543 guest to restart a syscall that has been interrupted by a signal. 1544*/ 1545typedef 1546 enum { 1547 Ijk_Boring=0x16000, /* not interesting; just goto next */ 1548 Ijk_Call, /* guest is doing a call */ 1549 Ijk_Ret, /* guest is doing a return */ 1550 Ijk_ClientReq, /* do guest client req before continuing */ 1551 Ijk_Yield, /* client is yielding to thread scheduler */ 1552 Ijk_EmWarn, /* report emulation warning before continuing */ 1553 Ijk_EmFail, /* emulation critical (FATAL) error; give up */ 1554 Ijk_NoDecode, /* next instruction cannot be decoded */ 1555 Ijk_MapFail, /* Vex-provided address translation failed */ 1556 Ijk_TInval, /* Invalidate translations before continuing. */ 1557 Ijk_NoRedir, /* Jump to un-redirected guest addr */ 1558 Ijk_SigTRAP, /* current instruction synths SIGTRAP */ 1559 Ijk_SigSEGV, /* current instruction synths SIGSEGV */ 1560 Ijk_SigBUS, /* current instruction synths SIGBUS */ 1561 /* Unfortunately, various guest-dependent syscall kinds. They 1562 all mean: do a syscall before continuing. */ 1563 Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */ 1564 Ijk_Sys_int32, /* amd64/x86 'int $0x20' */ 1565 Ijk_Sys_int128, /* amd64/x86 'int $0x80' */ 1566 Ijk_Sys_int129, /* amd64/x86 'int $0x81' */ 1567 Ijk_Sys_int130, /* amd64/x86 'int $0x82' */ 1568 Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes 1569 invalid at the point this happens. */ 1570 } 1571 IRJumpKind; 1572 1573extern void ppIRJumpKind ( IRJumpKind ); 1574 1575 1576/* ------------------ Dirty helper calls ------------------ */ 1577 1578/* A dirty call is a flexible mechanism for calling (possibly 1579 conditionally) a helper function or procedure. The helper function 1580 may read, write or modify client memory, and may read, write or 1581 modify client state. It can take arguments and optionally return a 1582 value. It may return different results and/or do different things 1583 when called repeatedly with the same arguments, by means of storing 1584 private state. 1585 1586 If a value is returned, it is assigned to the nominated return 1587 temporary. 1588 1589 Dirty calls are statements rather than expressions for obvious 1590 reasons. If a dirty call is marked as writing guest state, any 1591 values derived from the written parts of the guest state are 1592 invalid. Similarly, if the dirty call is stated as writing 1593 memory, any loaded values are invalidated by it. 1594 1595 In order that instrumentation is possible, the call must state, and 1596 state correctly: 1597 1598 * whether it reads, writes or modifies memory, and if so where 1599 (only one chunk can be stated) 1600 1601 * whether it reads, writes or modifies guest state, and if so which 1602 pieces (several pieces may be stated, and currently their extents 1603 must be known at translation-time). 1604 1605 Normally, code is generated to pass just the args to the helper. 1606 However, if .needsBBP is set, then an extra first argument is 1607 passed, which is the baseblock pointer, so that the callee can 1608 access the guest state. It is invalid for .nFxState to be zero 1609 but .needsBBP to be True, since .nFxState==0 is a claim that the 1610 call does not access guest state. 1611 1612 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The 1613 arguments are evaluated REGARDLESS of the guard value. It is 1614 unspecified the relative order of arg evaluation and guard 1615 evaluation. 1616*/ 1617 1618#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */ 1619 1620/* Effects on resources (eg. registers, memory locations) */ 1621typedef 1622 enum { 1623 Ifx_None = 0x17000, /* no effect */ 1624 Ifx_Read, /* reads the resource */ 1625 Ifx_Write, /* writes the resource */ 1626 Ifx_Modify, /* modifies the resource */ 1627 } 1628 IREffect; 1629 1630/* Pretty-print an IREffect */ 1631extern void ppIREffect ( IREffect ); 1632 1633 1634typedef 1635 struct { 1636 /* What to call, and details of args/results */ 1637 IRCallee* cee; /* where to call */ 1638 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */ 1639 IRExpr** args; /* arg list, ends in NULL */ 1640 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */ 1641 1642 /* Mem effects; we allow only one R/W/M region to be stated */ 1643 IREffect mFx; /* indicates memory effects, if any */ 1644 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */ 1645 Int mSize; /* of access, or zero if mFx==Ifx_None */ 1646 1647 /* Guest state effects; up to N allowed */ 1648 Bool needsBBP; /* True => also pass guest state ptr to callee */ 1649 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */ 1650 struct { 1651 IREffect fx; /* read, write or modify? Ifx_None is invalid. */ 1652 Int offset; 1653 Int size; 1654 } fxState[VEX_N_FXSTATE]; 1655 } 1656 IRDirty; 1657 1658/* Pretty-print a dirty call */ 1659extern void ppIRDirty ( IRDirty* ); 1660 1661/* Allocate an uninitialised dirty call */ 1662extern IRDirty* emptyIRDirty ( void ); 1663 1664/* Deep-copy a dirty call */ 1665extern IRDirty* deepCopyIRDirty ( IRDirty* ); 1666 1667/* A handy function which takes some of the tedium out of constructing 1668 dirty helper calls. The called function impliedly does not return 1669 any value and has a constant-True guard. The call is marked as 1670 accessing neither guest state nor memory (hence the "unsafe" 1671 designation) -- you can change this marking later if need be. A 1672 suitable IRCallee is constructed from the supplied bits. */ 1673extern 1674IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr, 1675 IRExpr** args ); 1676 1677/* Similarly, make a zero-annotation dirty call which returns a value, 1678 and assign that to the given temp. */ 1679extern 1680IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 1681 Int regparms, HChar* name, void* addr, 1682 IRExpr** args ); 1683 1684 1685/* --------------- Memory Bus Events --------------- */ 1686 1687typedef 1688 enum { 1689 Imbe_Fence=0x18000, 1690 } 1691 IRMBusEvent; 1692 1693extern void ppIRMBusEvent ( IRMBusEvent ); 1694 1695 1696/* --------------- Compare and Swap --------------- */ 1697 1698/* This denotes an atomic compare and swap operation, either 1699 a single-element one or a double-element one. 1700 1701 In the single-element case: 1702 1703 .addr is the memory address. 1704 .end is the endianness with which memory is accessed 1705 1706 If .addr contains the same value as .expdLo, then .dataLo is 1707 written there, else there is no write. In both cases, the 1708 original value at .addr is copied into .oldLo. 1709 1710 Types: .expdLo, .dataLo and .oldLo must all have the same type. 1711 It may be any integral type, viz: I8, I16, I32 or, for 64-bit 1712 guests, I64. 1713 1714 .oldHi must be IRTemp_INVALID, and .expdHi and .dataHi must 1715 be NULL. 1716 1717 In the double-element case: 1718 1719 .addr is the memory address. 1720 .end is the endianness with which memory is accessed 1721 1722 The operation is the same: 1723 1724 If .addr contains the same value as .expdHi:.expdLo, then 1725 .dataHi:.dataLo is written there, else there is no write. In 1726 both cases the original value at .addr is copied into 1727 .oldHi:.oldLo. 1728 1729 Types: .expdHi, .expdLo, .dataHi, .dataLo, .oldHi, .oldLo must 1730 all have the same type, which may be any integral type, viz: I8, 1731 I16, I32 or, for 64-bit guests, I64. 1732 1733 The double-element case is complicated by the issue of 1734 endianness. In all cases, the two elements are understood to be 1735 located adjacently in memory, starting at the address .addr. 1736 1737 If .end is Iend_LE, then the .xxxLo component is at the lower 1738 address and the .xxxHi component is at the higher address, and 1739 each component is itself stored little-endianly. 1740 1741 If .end is Iend_BE, then the .xxxHi component is at the lower 1742 address and the .xxxLo component is at the higher address, and 1743 each component is itself stored big-endianly. 1744 1745 This allows representing more cases than most architectures can 1746 handle. For example, x86 cannot do DCAS on 8- or 16-bit elements. 1747 1748 How to know if the CAS succeeded? 1749 1750 * if .oldLo == .expdLo (resp. .oldHi:.oldLo == .expdHi:.expdLo), 1751 then the CAS succeeded, .dataLo (resp. .dataHi:.dataLo) is now 1752 stored at .addr, and the original value there was .oldLo (resp 1753 .oldHi:.oldLo). 1754 1755 * if .oldLo != .expdLo (resp. .oldHi:.oldLo != .expdHi:.expdLo), 1756 then the CAS failed, and the original value at .addr was .oldLo 1757 (resp. .oldHi:.oldLo). 1758 1759 Hence it is easy to know whether or not the CAS succeeded. 1760*/ 1761typedef 1762 struct { 1763 IRTemp oldHi; /* old value of *addr is written here */ 1764 IRTemp oldLo; 1765 IREndness end; /* endianness of the data in memory */ 1766 IRExpr* addr; /* store address */ 1767 IRExpr* expdHi; /* expected old value at *addr */ 1768 IRExpr* expdLo; 1769 IRExpr* dataHi; /* new value for *addr */ 1770 IRExpr* dataLo; 1771 } 1772 IRCAS; 1773 1774extern void ppIRCAS ( IRCAS* cas ); 1775 1776extern IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo, 1777 IREndness end, IRExpr* addr, 1778 IRExpr* expdHi, IRExpr* expdLo, 1779 IRExpr* dataHi, IRExpr* dataLo ); 1780 1781extern IRCAS* deepCopyIRCAS ( IRCAS* ); 1782 1783/* ------------------ Statements ------------------ */ 1784 1785/* The different kinds of statements. Their meaning is explained 1786 below in the comments for IRStmt. 1787 1788 Those marked META do not represent code, but rather extra 1789 information about the code. These statements can be removed 1790 without affecting the functional behaviour of the code, however 1791 they are required by some IR consumers such as tools that 1792 instrument the code. 1793*/ 1794 1795typedef 1796 enum { 1797 Ist_NoOp=0x19000, 1798 Ist_IMark, /* META */ 1799 Ist_AbiHint, /* META */ 1800 Ist_Put, 1801 Ist_PutI, 1802 Ist_WrTmp, 1803 Ist_Store, 1804 Ist_CAS, 1805 Ist_LLSC, 1806 Ist_Dirty, 1807 Ist_MBE, /* META (maybe) */ 1808 Ist_Exit 1809 } 1810 IRStmtTag; 1811 1812/* A statement. Stored as a tagged union. 'tag' indicates what kind 1813 of expression this is. 'Ist' is the union that holds the fields. 1814 If an IRStmt 'st' has st.tag equal to Iex_Store, then it's a store 1815 statement, and the fields can be accessed with 1816 'st.Ist.Store.<fieldname>'. 1817 1818 For each kind of statement, we show what it looks like when 1819 pretty-printed with ppIRStmt(). 1820*/ 1821typedef 1822 struct _IRStmt { 1823 IRStmtTag tag; 1824 union { 1825 /* A no-op (usually resulting from IR optimisation). Can be 1826 omitted without any effect. 1827 1828 ppIRStmt output: IR-NoOp 1829 */ 1830 struct { 1831 } NoOp; 1832 1833 /* META: instruction mark. Marks the start of the statements 1834 that represent a single machine instruction (the end of 1835 those statements is marked by the next IMark or the end of 1836 the IRSB). Contains the address and length of the 1837 instruction. 1838 1839 ppIRStmt output: ------ IMark(<addr>, <len>) ------, 1840 eg. ------ IMark(0x4000792, 5) ------, 1841 */ 1842 struct { 1843 Addr64 addr; /* instruction address */ 1844 Int len; /* instruction length */ 1845 } IMark; 1846 1847 /* META: An ABI hint, which says something about this 1848 platform's ABI. 1849 1850 At the moment, the only AbiHint is one which indicates 1851 that a given chunk of address space, [base .. base+len-1], 1852 has become undefined. This is used on amd64-linux and 1853 some ppc variants to pass stack-redzoning hints to whoever 1854 wants to see them. It also indicates the address of the 1855 next (dynamic) instruction that will be executed. This is 1856 to help Memcheck to origin tracking. 1857 1858 ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ====== 1859 eg. ====== AbiHint(t1, 16, t2) ====== 1860 */ 1861 struct { 1862 IRExpr* base; /* Start of undefined chunk */ 1863 Int len; /* Length of undefined chunk */ 1864 IRExpr* nia; /* Address of next (guest) insn */ 1865 } AbiHint; 1866 1867 /* Write a guest register, at a fixed offset in the guest state. 1868 ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1 1869 */ 1870 struct { 1871 Int offset; /* Offset into the guest state */ 1872 IRExpr* data; /* The value to write */ 1873 } Put; 1874 1875 /* Write a guest register, at a non-fixed offset in the guest 1876 state. See the comment for GetI expressions for more 1877 information. 1878 1879 ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>, 1880 eg. PUTI(64:8xF64)[t5,0] = t1 1881 */ 1882 struct { 1883 IRRegArray* descr; /* Part of guest state treated as circular */ 1884 IRExpr* ix; /* Variable part of index into array */ 1885 Int bias; /* Constant offset part of index into array */ 1886 IRExpr* data; /* The value to write */ 1887 } PutI; 1888 1889 /* Assign a value to a temporary. Note that SSA rules require 1890 each tmp is only assigned to once. IR sanity checking will 1891 reject any block containing a temporary which is not assigned 1892 to exactly once. 1893 1894 ppIRStmt output: t<tmp> = <data>, eg. t1 = 3 1895 */ 1896 struct { 1897 IRTemp tmp; /* Temporary (LHS of assignment) */ 1898 IRExpr* data; /* Expression (RHS of assignment) */ 1899 } WrTmp; 1900 1901 /* Write a value to memory. This is a normal store, not a 1902 Store-Conditional. To represent a Store-Conditional, 1903 instead use IRStmt.LLSC. 1904 ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2 1905 */ 1906 struct { 1907 IREndness end; /* Endianness of the store */ 1908 IRExpr* addr; /* store address */ 1909 IRExpr* data; /* value to write */ 1910 } Store; 1911 1912 /* Do an atomic compare-and-swap operation. Semantics are 1913 described above on a comment at the definition of IRCAS. 1914 1915 ppIRStmt output: 1916 t<tmp> = CAS<end>(<addr> :: <expected> -> <new>) 1917 eg 1918 t1 = CASle(t2 :: t3->Add32(t3,1)) 1919 which denotes a 32-bit atomic increment 1920 of a value at address t2 1921 1922 A double-element CAS may also be denoted, in which case <tmp>, 1923 <expected> and <new> are all pairs of items, separated by 1924 commas. 1925 */ 1926 struct { 1927 IRCAS* details; 1928 } CAS; 1929 1930 /* Either Load-Linked or Store-Conditional, depending on 1931 STOREDATA. 1932 1933 If STOREDATA is NULL then this is a Load-Linked, meaning 1934 that data is loaded from memory as normal, but a 1935 'reservation' for the address is also lodged in the 1936 hardware. 1937 1938 result = Load-Linked(addr, end) 1939 1940 The data transfer type is the type of RESULT (I32, I64, 1941 etc). ppIRStmt output: 1942 1943 result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1) 1944 1945 If STOREDATA is not NULL then this is a Store-Conditional, 1946 hence: 1947 1948 result = Store-Conditional(addr, storedata, end) 1949 1950 The data transfer type is the type of STOREDATA and RESULT 1951 has type Ity_I1. The store may fail or succeed depending 1952 on the state of a previously lodged reservation on this 1953 address. RESULT is written 1 if the store succeeds and 0 1954 if it fails. eg ppIRStmt output: 1955 1956 result = ( ST<end>-Cond(<addr>) = <storedata> ) 1957 eg t3 = ( STbe-Cond(t1, t2) ) 1958 1959 In all cases, the address must be naturally aligned for 1960 the transfer type -- any misaligned addresses should be 1961 caught by a dominating IR check and side exit. This 1962 alignment restriction exists because on at least some 1963 LL/SC platforms (ppc), stwcx. etc will trap w/ SIGBUS on 1964 misaligned addresses, and we have to actually generate 1965 stwcx. on the host, and we don't want it trapping on the 1966 host. 1967 1968 Summary of rules for transfer type: 1969 STOREDATA == NULL (LL): 1970 transfer type = type of RESULT 1971 STOREDATA != NULL (SC): 1972 transfer type = type of STOREDATA, and RESULT :: Ity_I1 1973 */ 1974 struct { 1975 IREndness end; 1976 IRTemp result; 1977 IRExpr* addr; 1978 IRExpr* storedata; /* NULL => LL, non-NULL => SC */ 1979 } LLSC; 1980 1981 /* Call (possibly conditionally) a C function that has side 1982 effects (ie. is "dirty"). See the comments above the 1983 IRDirty type declaration for more information. 1984 1985 ppIRStmt output: 1986 t<tmp> = DIRTY <guard> <effects> 1987 ::: <callee>(<args>) 1988 eg. 1989 t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4) 1990 ::: foo{0x380035f4}(t2) 1991 */ 1992 struct { 1993 IRDirty* details; 1994 } Dirty; 1995 1996 /* A memory bus event - a fence, or acquisition/release of the 1997 hardware bus lock. IR optimisation treats all these as fences 1998 across which no memory references may be moved. 1999 ppIRStmt output: MBusEvent-Fence, 2000 MBusEvent-BusLock, MBusEvent-BusUnlock. 2001 */ 2002 struct { 2003 IRMBusEvent event; 2004 } MBE; 2005 2006 /* Conditional exit from the middle of an IRSB. 2007 ppIRStmt output: if (<guard>) goto {<jk>} <dst> 2008 eg. if (t69) goto {Boring} 0x4000AAA:I32 2009 */ 2010 struct { 2011 IRExpr* guard; /* Conditional expression */ 2012 IRJumpKind jk; /* Jump kind */ 2013 IRConst* dst; /* Jump target (constant only) */ 2014 } Exit; 2015 } Ist; 2016 } 2017 IRStmt; 2018 2019/* Statement constructors. */ 2020extern IRStmt* IRStmt_NoOp ( void ); 2021extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len ); 2022extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ); 2023extern IRStmt* IRStmt_Put ( Int off, IRExpr* data ); 2024extern IRStmt* IRStmt_PutI ( IRRegArray* descr, IRExpr* ix, Int bias, 2025 IRExpr* data ); 2026extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ); 2027extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ); 2028extern IRStmt* IRStmt_CAS ( IRCAS* details ); 2029extern IRStmt* IRStmt_LLSC ( IREndness end, IRTemp result, 2030 IRExpr* addr, IRExpr* storedata ); 2031extern IRStmt* IRStmt_Dirty ( IRDirty* details ); 2032extern IRStmt* IRStmt_MBE ( IRMBusEvent event ); 2033extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ); 2034 2035/* Deep-copy an IRStmt. */ 2036extern IRStmt* deepCopyIRStmt ( IRStmt* ); 2037 2038/* Pretty-print an IRStmt. */ 2039extern void ppIRStmt ( IRStmt* ); 2040 2041 2042/* ------------------ Basic Blocks ------------------ */ 2043 2044/* Type environments: a bunch of statements, expressions, etc, are 2045 incomplete without an environment indicating the type of each 2046 IRTemp. So this provides one. IR temporaries are really just 2047 unsigned ints and so this provides an array, 0 .. n_types_used-1 of 2048 them. 2049*/ 2050typedef 2051 struct { 2052 IRType* types; 2053 Int types_size; 2054 Int types_used; 2055 } 2056 IRTypeEnv; 2057 2058/* Obtain a new IRTemp */ 2059extern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 2060 2061/* Deep-copy a type environment */ 2062extern IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* ); 2063 2064/* Pretty-print a type environment */ 2065extern void ppIRTypeEnv ( IRTypeEnv* ); 2066 2067 2068/* Code blocks, which in proper compiler terminology are superblocks 2069 (single entry, multiple exit code sequences) contain: 2070 2071 - A table giving a type for each temp (the "type environment") 2072 - An expandable array of statements 2073 - An expression of type 32 or 64 bits, depending on the 2074 guest's word size, indicating the next destination if the block 2075 executes all the way to the end, without a side exit 2076 - An indication of any special actions (JumpKind) needed 2077 for this final jump. 2078 2079 "IRSB" stands for "IR Super Block". 2080*/ 2081typedef 2082 struct { 2083 IRTypeEnv* tyenv; 2084 IRStmt** stmts; 2085 Int stmts_size; 2086 Int stmts_used; 2087 IRExpr* next; 2088 IRJumpKind jumpkind; 2089 } 2090 IRSB; 2091 2092/* Allocate a new, uninitialised IRSB */ 2093extern IRSB* emptyIRSB ( void ); 2094 2095/* Deep-copy an IRSB */ 2096extern IRSB* deepCopyIRSB ( IRSB* ); 2097 2098/* Deep-copy an IRSB, except for the statements list, which set to be 2099 a new, empty, list of statements. */ 2100extern IRSB* deepCopyIRSBExceptStmts ( IRSB* ); 2101 2102/* Pretty-print an IRSB */ 2103extern void ppIRSB ( IRSB* ); 2104 2105/* Append an IRStmt to an IRSB */ 2106extern void addStmtToIRSB ( IRSB*, IRStmt* ); 2107 2108 2109/*---------------------------------------------------------------*/ 2110/*--- Helper functions for the IR ---*/ 2111/*---------------------------------------------------------------*/ 2112 2113/* For messing with IR type environments */ 2114extern IRTypeEnv* emptyIRTypeEnv ( void ); 2115 2116/* What is the type of this expression? */ 2117extern IRType typeOfIRConst ( IRConst* ); 2118extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp ); 2119extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 2120 2121/* Sanity check a BB of IR */ 2122extern void sanityCheckIRSB ( IRSB* bb, 2123 HChar* caller, 2124 Bool require_flatness, 2125 IRType guest_word_size ); 2126extern Bool isFlatIRStmt ( IRStmt* ); 2127 2128/* Is this any value actually in the enumeration 'IRType' ? */ 2129extern Bool isPlausibleIRType ( IRType ty ); 2130 2131#endif /* ndef __LIBVEX_IR_H */ 2132 2133 2134/*---------------------------------------------------------------*/ 2135/*--- libvex_ir.h ---*/ 2136/*---------------------------------------------------------------*/ 2137