libvex_ir.h revision af1cecaf9c96f99381dda16f41d286fc3e4d220a
1 2/*---------------------------------------------------------------*/ 3/*--- ---*/ 4/*--- This file (libvex_ir.h) is ---*/ 5/*--- Copyright (c) OpenWorks LLP. All rights reserved. ---*/ 6/*--- ---*/ 7/*---------------------------------------------------------------*/ 8 9/* 10 This file is part of LibVEX, a library for dynamic binary 11 instrumentation and translation. 12 13 Copyright (C) 2004-2005 OpenWorks LLP. 14 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation; Version 2 dated June 1991 of the 18 license. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability 23 for damages. See the GNU General Public License for more details. 24 25 Neither the names of the U.S. Department of Energy nor the 26 University of California nor the names of its contributors may be 27 used to endorse or promote products derived from this software 28 without prior written permission. 29 30 You should have received a copy of the GNU General Public License 31 along with this program; if not, write to the Free Software 32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 33 USA. 34*/ 35 36#ifndef __LIBVEX_IR_H 37#define __LIBVEX_IR_H 38 39#include "libvex_basictypes.h" 40 41 42 43/*---------------------------------------------------------------*/ 44/*--- Type definitions for the IR ---*/ 45/*---------------------------------------------------------------*/ 46 47/* General comments about naming schemes: 48 49 All publically visible functions contain the name of the primary 50 type on which they operate (IRFoo, IRBar, etc). Hence you should 51 be able to identify these functions by grepping for "IR[A-Z]". 52 53 For some type 'IRFoo': 54 55 - ppIRFoo is the printing method for IRFoo, printing it to the 56 output channel specified in the LibVEX_Initialise call. 57 58 - eqIRFoo is a structural equality predicate for IRFoos. 59 60 - dopyIRFoo is a deep copy constructor for IRFoos. 61 It recursively traverses the entire argument tree and 62 produces a complete new tree. 63 64 - sopyIRFoo is the shallow copy constructor for IRFoos. 65 It creates a new top-level copy of the supplied object, 66 but does not copy any sub-objects. 67*/ 68 69/* ------------------ Types ------------------ */ 70 71typedef 72 enum { 73 Ity_INVALID=0x10FFF, 74 Ity_I1=0x11000, 75 Ity_I8, 76 Ity_I16, 77 Ity_I32, 78 Ity_I64, 79 Ity_I128, /* 128-bit scalar */ 80 Ity_F32, /* IEEE 754 float */ 81 Ity_F64, /* IEEE 754 double */ 82 Ity_V128 /* 128-bit SIMD */ 83 } 84 IRType; 85 86extern void ppIRType ( IRType ); 87extern Int sizeofIRType ( IRType ); 88 89 90/* ------------------ Endianness ------------------ */ 91 92typedef 93 enum { 94 Iend_LE=22, /* little endian */ 95 Iend_BE=33 /* big endian */ 96 } 97 IREndness; 98 99 100/* ------------------ Constants ------------------ */ 101 102typedef 103 enum { 104 Ico_U1=0x12000, 105 Ico_U8, 106 Ico_U16, 107 Ico_U32, 108 Ico_U64, 109 Ico_F64, /* 64-bit IEEE754 floating */ 110 Ico_F64i, /* 64-bit unsigned int to be interpreted literally 111 as a IEEE754 double value. */ 112 Ico_V128 /* 128-bit restricted vector constant, with 1 bit for 113 each of 16 byte lanes */ 114 } 115 IRConstTag; 116 117typedef 118 struct _IRConst { 119 IRConstTag tag; 120 union { 121 Bool U1; 122 UChar U8; 123 UShort U16; 124 UInt U32; 125 ULong U64; 126 Double F64; 127 ULong F64i; 128 UShort V128; 129 } Ico; 130 } 131 IRConst; 132 133extern IRConst* IRConst_U1 ( Bool ); 134extern IRConst* IRConst_U8 ( UChar ); 135extern IRConst* IRConst_U16 ( UShort ); 136extern IRConst* IRConst_U32 ( UInt ); 137extern IRConst* IRConst_U64 ( ULong ); 138extern IRConst* IRConst_F64 ( Double ); 139extern IRConst* IRConst_F64i ( ULong ); 140extern IRConst* IRConst_V128 ( UShort ); 141 142extern IRConst* dopyIRConst ( IRConst* ); 143 144extern void ppIRConst ( IRConst* ); 145extern Bool eqIRConst ( IRConst*, IRConst* ); 146 147 148/* ------------------ Call targets ------------------ */ 149 150/* Describes a helper function to call. The name part is purely for 151 pretty printing and not actually used. regparms=n tells the back 152 end that the callee has been declared 153 "__attribute__((regparm(n)))". On some targets (x86) the back end 154 will need to construct a non-standard sequence to call a function 155 declared like this. 156 157 mcx_mask is a sop to Memcheck. It indicates which args should be 158 considered 'always defined' when lazily computing definedness of 159 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to 160 args[1], etc. If a bit is set, the corresponding arg is excluded 161 (hence "x" in "mcx") from definedness checking. 162*/ 163 164typedef 165 struct { 166 Int regparms; 167 HChar* name; 168 void* addr; 169 UInt mcx_mask; 170 } 171 IRCallee; 172 173extern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr ); 174 175extern IRCallee* dopyIRCallee ( IRCallee* ); 176 177extern void ppIRCallee ( IRCallee* ); 178 179 180/* ------------------ Guest state arrays ------------------ */ 181 182typedef 183 struct { 184 Int base; 185 IRType elemTy; 186 Int nElems; 187 } 188 IRArray; 189 190extern IRArray* mkIRArray ( Int, IRType, Int ); 191 192extern IRArray* dopyIRArray ( IRArray* ); 193 194extern void ppIRArray ( IRArray* ); 195extern Bool eqIRArray ( IRArray*, IRArray* ); 196 197 198/* ------------------ Temporaries ------------------ */ 199 200/* The IR optimiser relies on the fact that IRTemps are 32-bit 201 ints. Do not change them to be ints of any other size. */ 202typedef UInt IRTemp; 203 204extern void ppIRTemp ( IRTemp ); 205 206#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF) 207 208 209/* ------------------ Binary and unary ops ------------------ */ 210 211typedef 212 enum { 213 /* -- Do not change this ordering. The IR generators rely on 214 (eg) Iop_Add64 == IopAdd8 + 3. -- */ 215 216 Iop_INVALID=0x13000, 217 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64, 218 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, 219 /* Signless mul. MullS/MullU is elsewhere. */ 220 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64, 221 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64, 222 Iop_And8, Iop_And16, Iop_And32, Iop_And64, 223 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64, 224 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64, 225 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64, 226 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64, 227 /* Integer comparisons. */ 228 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64, 229 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, 230 /* Tags for unary ops */ 231 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, 232 Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64, 233 234 /* -- Ordering not important after here. -- */ 235 236 /* Widening multiplies */ 237 Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64, 238 Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64, 239 240 /* Wierdo integer stuff */ 241 Iop_Clz64, Iop_Clz32, /* count leading zeroes */ 242 Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */ 243 /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of 244 zero. You must ensure they are never given a zero argument. 245 */ 246 247 Iop_CmpLT32S, Iop_CmpLT64S, 248 Iop_CmpLE32S, Iop_CmpLE64S, 249 Iop_CmpLT32U, Iop_CmpLT64U, 250 Iop_CmpLE32U, Iop_CmpLE64U, 251 252 /* As a sop to Valgrind-Memcheck, the following are useful. */ 253 Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64, 254 255 /* Division */ 256 /* TODO: clarify semantics wrt rounding, negative values, whatever */ 257 Iop_DivU32, // :: I32,I32 -> I32 (simple div, no mod) 258 Iop_DivS32, // ditto, signed 259 260 Iop_DivModU64to32, // :: I64,I32 -> I64 261 // of which lo half is div and hi half is mod 262 Iop_DivModS64to32, // ditto, signed 263 264 Iop_DivModU128to64, // :: V128,I64 -> V128 265 // of which lo half is div and hi half is mod 266 Iop_DivModS128to64, // ditto, signed 267 268 /* Integer conversions. Some of these are redundant (eg 269 Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but 270 having a complete set reduces the typical dynamic size of IR 271 and makes the instruction selectors easier to write. */ 272 273 /* Widening conversions */ 274 Iop_8Uto16, Iop_8Uto32, Iop_8Uto64, 275 Iop_16Uto32, Iop_16Uto64, 276 Iop_32Uto64, 277 Iop_8Sto16, Iop_8Sto32, Iop_8Sto64, 278 Iop_16Sto32, Iop_16Sto64, 279 Iop_32Sto64, 280 281 /* Narrowing conversions */ 282 Iop_64to8, Iop_32to8, Iop_64to16, 283 /* 8 <-> 16 bit conversions */ 284 Iop_16to8, // :: I16 -> I8, low half 285 Iop_16HIto8, // :: I16 -> I8, high half 286 Iop_8HLto16, // :: (I8,I8) -> I16 287 /* 16 <-> 32 bit conversions */ 288 Iop_32to16, // :: I32 -> I16, low half 289 Iop_32HIto16, // :: I32 -> I16, high half 290 Iop_16HLto32, // :: (I16,I16) -> I32 291 /* 32 <-> 64 bit conversions */ 292 Iop_64to32, // :: I64 -> I32, low half 293 Iop_64HIto32, // :: I64 -> I32, high half 294 Iop_32HLto64, // :: (I32,I32) -> I64 295 /* 64 <-> 128 bit conversions */ 296 Iop_128to64, // :: I128 -> I64, low half 297 Iop_128HIto64, // :: I128 -> I64, high half 298 Iop_64HLto128, // :: (I64,I64) -> I128 299 /* 1-bit stuff */ 300 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */ 301 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ 302 Iop_64to1, /* :: Ity_I64 -> Ity_Bit, just select bit[0] */ 303 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ 304 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ 305 Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */ 306 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */ 307 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */ 308 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ 309 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */ 310 311 /* ------ Floating point. We try and be IEEE754 compliant. ------ */ 312 313 /* Binary operations mandated by IEEE754. */ 314 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */ 315 316 /* Binary ops supported by IA32 but not mandated by 754. */ 317 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */ 318 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */ 319 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */ 320 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */ 321 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */ 322 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */ 323 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */ 324 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */ 325 /* Note that on x86 guest, PRem1{C3210} has the same behaviour 326 as the IEEE mandated RemF64, except it is limited in the 327 range of its operand. Hence the partialness. */ 328 329 /* Unary operations mandated by IEEE754. */ 330 Iop_NegF64, Iop_SqrtF64, 331 332 /* Unary ops supported by IA32 but not mandated by 754. */ 333 Iop_AbsF64, /* FABS */ 334 Iop_SinF64, /* FSIN */ 335 Iop_CosF64, /* FCOS */ 336 Iop_TanF64, /* FTAN */ 337 Iop_2xm1F64, /* (2^arg - 1.0) */ 338 339 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following: 340 0x45 Unordered 341 0x01 LT 342 0x00 GT 343 0x40 EQ 344 This just happens to be the Intel encoding. The values 345 are recorded in the type IRCmpF64Result. 346 */ 347 Iop_CmpF64, 348 349 /* --- Int to/from FP conversions. --- */ 350 /* For the most part, these take a first argument :: Ity_I32 351 (as IRRoundingMode) which is an indication of the rounding 352 mode to use, as per the following encoding: 353 00b to nearest (the default) 354 01b to -infinity 355 10b to +infinity 356 11b to zero 357 This just happens to be the Intel encoding. For reference only, 358 the PPC encoding is: 359 00b to nearest (the default) 360 01b to zero 361 10b to +infinity 362 11b to -infinity 363 Any PPC -> IR front end will have to translate these PPC 364 encodings to the standard encodings. 365 366 If one of these conversions gets an out-of-range condition, 367 or a NaN, as an argument, the result is host-defined. On x86 368 the "integer indefinite" value 0x80..00 is produced. 369 On PPC it is either 0x80..00 or 0x7F..FF depending on the sign 370 of the argument. 371 372 Rounding is required whenever the destination type cannot 373 represent exactly all values of the source type. 374 */ 375 Iop_F64toI16, /* IRRoundingMode(I32) x F64 -> I16 */ 376 Iop_F64toI32, /* IRRoundingMode(I32) x F64 -> I32 */ 377 Iop_F64toI64, /* IRRoundingMode(I32) x F64 -> I64 */ 378 379 Iop_I16toF64, /* I16 -> F64 */ 380 Iop_I32toF64, /* I32 -> F64 */ 381 Iop_I64toF64, /* IRRoundingMode(I32) x I64 -> F64 */ 382 383 Iop_F32toF64, /* F32 -> F64 */ 384 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */ 385 386 /* F64 -> F64, also takes an I32 first argument encoding the 387 rounding mode. */ 388 Iop_RoundF64, 389 390 /* Reinterpretation. Take an F64 and produce an I64 with 391 the same bit pattern, or vice versa. */ 392 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64, 393 Iop_ReinterpF32asI32, Iop_ReinterpI32asF32, 394 395 /* ------------------ 64-bit SIMD Integer. ------------------ */ 396 397 /* MISC (vector integer cmp != 0) */ 398 Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2, 399 400 /* ADDITION (normal / unsigned sat / signed sat) */ 401 Iop_Add8x8, Iop_Add16x4, Iop_Add32x2, 402 Iop_QAdd8Ux8, Iop_QAdd16Ux4, 403 Iop_QAdd8Sx8, Iop_QAdd16Sx4, 404 405 /* SUBTRACTION (normal / unsigned sat / signed sat) */ 406 Iop_Sub8x8, Iop_Sub16x4, Iop_Sub32x2, 407 Iop_QSub8Ux8, Iop_QSub16Ux4, 408 Iop_QSub8Sx8, Iop_QSub16Sx4, 409 410 /* MULTIPLICATION (normal / high half of signed/unsigned) */ 411 Iop_Mul16x4, 412 Iop_MulHi16Ux4, 413 Iop_MulHi16Sx4, 414 415 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 416 Iop_Avg8Ux8, 417 Iop_Avg16Ux4, 418 419 /* MIN/MAX */ 420 Iop_Max16Sx4, 421 Iop_Max8Ux8, 422 Iop_Min16Sx4, 423 Iop_Min8Ux8, 424 425 /* COMPARISON */ 426 Iop_CmpEQ8x8, Iop_CmpEQ16x4, Iop_CmpEQ32x2, 427 Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2, 428 429 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 430 Iop_ShlN16x4, Iop_ShlN32x2, 431 Iop_ShrN16x4, Iop_ShrN32x2, 432 Iop_SarN16x4, Iop_SarN32x2, 433 434 /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */ 435 Iop_QNarrow16Ux4, 436 Iop_QNarrow16Sx4, 437 Iop_QNarrow32Sx2, 438 439 /* INTERLEAVING -- interleave lanes from low or high halves of 440 operands. Most-significant result lane is from the left 441 arg. */ 442 Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2, 443 Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2, 444 445 /* ------------------ 128-bit SIMD FP. ------------------ */ 446 447 /* --- 32x4 vector FP --- */ 448 449 /* binary */ 450 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 451 Iop_Max32Fx4, Iop_Min32Fx4, 452 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 453 454 /* unary */ 455 Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, 456 457 /* --- 32x4 lowest-lane-only scalar FP --- */ 458 459 /* In binary cases, upper 3/4 is copied from first operand. In 460 unary cases, upper 3/4 is copied from the operand. */ 461 462 /* binary */ 463 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 464 Iop_Max32F0x4, Iop_Min32F0x4, 465 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 466 467 /* unary */ 468 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, 469 470 /* --- 64x2 vector FP --- */ 471 472 /* binary */ 473 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 474 Iop_Max64Fx2, Iop_Min64Fx2, 475 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 476 477 /* unary */ 478 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2, 479 480 /* --- 64x2 lowest-lane-only scalar FP --- */ 481 482 /* In binary cases, upper half is copied from first operand. In 483 unary cases, upper half is copied from the operand. */ 484 485 /* binary */ 486 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 487 Iop_Max64F0x2, Iop_Min64F0x2, 488 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 489 490 /* unary */ 491 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2, 492 493 /* --- pack / unpack --- */ 494 495 /* 64 <-> 128 bit vector */ 496 Iop_V128to64, // :: V128 -> I64, low half 497 Iop_V128HIto64, // :: V128 -> I64, high half 498 Iop_64HLtoV128, // :: (I64,I64) -> V128 499 500 Iop_64UtoV128, 501 Iop_SetV128lo64, 502 503 /* 32 <-> 128 bit vector */ 504 Iop_32UtoV128, 505 Iop_V128to32, // :: V128 -> I32, lowest lane 506 Iop_SetV128lo32, // :: (V128,I32) -> V128 507 508 /* ------------------ 128-bit SIMD Integer. ------------------ */ 509 510 /* BITWISE OPS */ 511 Iop_NotV128, 512 Iop_AndV128, Iop_OrV128, Iop_XorV128, 513 514 /* MISC (vector integer cmp != 0) */ 515 Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2, 516 517 /* ADDITION (normal / unsigned sat / signed sat) */ 518 Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2, 519 Iop_QAdd8Ux16, Iop_QAdd16Ux8, 520 Iop_QAdd8Sx16, Iop_QAdd16Sx8, 521 522 /* SUBTRACTION (normal / unsigned sat / signed sat) */ 523 Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2, 524 Iop_QSub8Ux16, Iop_QSub16Ux8, 525 Iop_QSub8Sx16, Iop_QSub16Sx8, 526 527 /* MULTIPLICATION (normal / high half of signed/unsigned) */ 528 Iop_Mul16x8, 529 Iop_MulHi16Ux8, 530 Iop_MulHi16Sx8, 531 532 /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */ 533 Iop_Avg8Ux16, 534 Iop_Avg16Ux8, 535 536 /* MIN/MAX */ 537 Iop_Max16Sx8, 538 Iop_Max8Ux16, 539 Iop_Min16Sx8, 540 Iop_Min8Ux16, 541 542 /* COMPARISON */ 543 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, 544 Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, 545 546 /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */ 547 Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2, 548 Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2, 549 Iop_SarN16x8, Iop_SarN32x4, 550 551 /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */ 552 Iop_QNarrow16Ux8, 553 Iop_QNarrow16Sx8, 554 Iop_QNarrow32Sx4, 555 556 /* INTERLEAVING -- interleave lanes from low or high halves of 557 operands. Most-significant result lane is from the left 558 arg. */ 559 Iop_InterleaveHI8x16, Iop_InterleaveHI16x8, 560 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2, 561 Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, 562 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 563 } 564 IROp; 565 566extern void ppIROp ( IROp ); 567 568 569/* Encoding of IEEE754-specified rounding modes in Float -> Int 570 conversions. This is the same as the encoding used by Intel IA32 571 to indicate x87 rounding mode. */ 572typedef 573 enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 } 574 IRRoundingMode; 575 576/* Floating point comparison result values, as created by Iop_CmpF64. 577 This is also derived from what IA32 does. */ 578typedef 579 enum { 580 Ircr_UN = 0x45, 581 Ircr_LT = 0x01, 582 Ircr_GT = 0x00, 583 Ircr_EQ = 0x40 584 } 585 IRCmpF64Result; 586 587 588/* ------------------ Expressions ------------------ */ 589/* 590 Some details of expression semantics: 591 592 IRExpr_GetI (also IRStmt_PutI) 593 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 These allow circular indexing into parts of the guest state, which 595 is essential for modelling situations where the identity of guest 596 registers is not known until run time. One example is the x87 FP 597 register stack. 598 599 The part of the guest state to be treated as a circular array is 600 described in an IRArray structure attached to the GetI/PutI. 601 IRArray holds the offset of the first element in the array, the 602 type of each element, and the number of elements. 603 604 The array index is indicated rather indirectly, in a way which 605 makes optimisation easy: as the sum of variable part (the 'ix' 606 field) and a constant offset (the 'bias' field). 607 608 Since the indexing is circular, the actual array index to use 609 is computed as (ix + bias) % number-of-elements-in-the-array. 610 611 Here's an example. The description 612 613 (96:8xF64)[t39,-7] 614 615 describes an array of 8 F64-typed values, the guest-state-offset 616 of the first being 96. This array is being indexed at 617 (t39 - 7) % 8. 618 619 It is important to get the array size/type exactly correct since IR 620 optimisation looks closely at such info in order to establish 621 aliasing/non-aliasing between seperate GetI and PutI events, which 622 is used to establish when they can be reordered, etc. Putting 623 incorrect info in will lead to obscure IR optimisation bugs. 624 625 IRExpr_CCall 626 ~~~~~~~~~~~~ 627 The name is the C helper function; the backends will call back to 628 the front ends to get the address of a host-code helper function to 629 be called. 630 631 The args are a NULL-terminated array of arguments. The stated 632 return IRType, and the implied argument types, must match that of 633 the function being called well enough so that the back end can 634 actually generate correct code for the call. 635 636 The called function **must** satisfy the following: 637 638 * no side effects -- must be a pure function, the result of which 639 depends only on the passed parameters. 640 641 * it may not look at, nor modify, any of the guest state since that 642 would hide guest state transitions from instrumenters 643 644 * it may not access guest memory, since that would hide guest 645 memory transactions from the instrumenters 646 647 This is restrictive, but makes the semantics clean, and does 648 not interfere with IR optimisation. 649 650 If you want to call a helper which can mess with guest state and/or 651 memory, instead use IRStmt_Dirty. This is a lot more flexible, but 652 you pay for that flexibility in that you have to give a bunch of 653 details about what the helper does (and you better be telling the 654 truth, otherwise any derived instrumentation will be wrong). Also 655 IRStmt_Dirty inhibits various IR optimisations and so can cause 656 quite poor code to be generated. Try to avoid it. */ 657 658/* The possible kinds of expressions are as follows: */ 659typedef 660 enum { 661 Iex_Binder, /* Used only in pattern matching. 662 Not an expression. */ 663 Iex_Get, /* read guest state, fixed offset */ 664 Iex_GetI, /* read guest state, run-time offset */ 665 Iex_Tmp, /* value of temporary */ 666 Iex_Binop, /* binary operation */ 667 Iex_Unop, /* unary operation */ 668 Iex_Load, /* read from memory */ 669 Iex_Const, /* constant-valued expression */ 670 Iex_Mux0X, /* ternary if-then-else operator (STRICT) */ 671 Iex_CCall /* call to pure (side-effect-free) helper fn */ 672 } 673 IRExprTag; 674 675typedef 676 struct _IRExpr { 677 IRExprTag tag; 678 union { 679 struct { 680 Int binder; 681 } Binder; 682 struct { 683 Int offset; 684 IRType ty; 685 } Get; 686 struct { 687 IRArray* descr; 688 struct _IRExpr* ix; 689 Int bias; 690 } GetI; 691 struct { 692 IRTemp tmp; 693 } Tmp; 694 struct { 695 IROp op; 696 struct _IRExpr* arg1; 697 struct _IRExpr* arg2; 698 } Binop; 699 struct { 700 IROp op; 701 struct _IRExpr* arg; 702 } Unop; 703 struct { 704 IREndness end; 705 IRType ty; 706 struct _IRExpr* addr; 707 } Load; 708 struct { 709 IRConst* con; 710 } Const; 711 struct { 712 IRCallee* cee; 713 IRType retty; 714 struct _IRExpr** args; 715 } CCall; 716 struct { 717 struct _IRExpr* cond; 718 struct _IRExpr* expr0; 719 struct _IRExpr* exprX; 720 } Mux0X; 721 } Iex; 722 } 723 IRExpr; 724 725extern IRExpr* IRExpr_Binder ( Int binder ); 726extern IRExpr* IRExpr_Get ( Int off, IRType ty ); 727extern IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ); 728extern IRExpr* IRExpr_Tmp ( IRTemp tmp ); 729extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 730extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 731extern IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ); 732extern IRExpr* IRExpr_Const ( IRConst* con ); 733extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ); 734extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ); 735 736extern IRExpr* dopyIRExpr ( IRExpr* ); 737 738extern void ppIRExpr ( IRExpr* ); 739 740/* NULL-terminated IRExpr expression vectors, suitable for use as arg 741 lists in clean/dirty helper calls. */ 742 743extern IRExpr** mkIRExprVec_0 ( void ); 744extern IRExpr** mkIRExprVec_1 ( IRExpr* ); 745extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* ); 746extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* ); 747extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* ); 748extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, 749 IRExpr*, IRExpr*, IRExpr* ); 750 751extern IRExpr** sopyIRExprVec ( IRExpr** ); 752extern IRExpr** dopyIRExprVec ( IRExpr** ); 753 754/* Make a constant expression from the given host word taking into 755 account of course the host word size. */ 756extern IRExpr* mkIRExpr_HWord ( HWord ); 757 758/* Convenience function for constructing clean helper calls. */ 759extern 760IRExpr* mkIRExprCCall ( IRType retty, 761 Int regparms, HChar* name, void* addr, 762 IRExpr** args ); 763 764 765/* Convenience functions for atoms, that is, IRExprs which 766 are either Iex_Tmp or Iex_Const. */ 767static inline Bool isIRAtom ( IRExpr* e ) { 768 return toBool(e->tag == Iex_Tmp || e->tag == Iex_Const); 769} 770 771/* Are these two IR atoms identical? Causes an assertion 772 failure if they are passed non-atoms. */ 773extern Bool eqIRAtom ( IRExpr*, IRExpr* ); 774 775 776/* ------------------ Jump kinds ------------------ */ 777 778/* This describes hints which can be passed to the dispatcher at guest 779 control-flow transfer points. 780 781 Re Ijk_Invalidate: typically the guest state will have two 782 pseudo-registers, guest_TISTART and guest_TILEN, which 783 specify the start and length of the region to be invalidated. 784 It is the responsibility of the relevant toIR.c to ensure that 785 these are filled in with suitable values before issuing a jump 786 of kind Ijk_TInval. 787*/ 788typedef 789 enum { 790 Ijk_Boring=0x14000, /* not interesting; just goto next */ 791 Ijk_Call, /* guest is doing a call */ 792 Ijk_Ret, /* guest is doing a return */ 793 Ijk_ClientReq, /* do guest client req before continuing */ 794 Ijk_Syscall, /* do guest syscall before continuing */ 795 Ijk_Yield, /* client is yielding to thread scheduler */ 796 Ijk_EmWarn, /* report emulation warning before continuing */ 797 Ijk_NoDecode, /* next instruction cannot be decoded */ 798 Ijk_MapFail, /* Vex-provided address translation failed */ 799 Ijk_TInval /* Invalidate translations before continuing. */ 800 } 801 IRJumpKind; 802 803extern void ppIRJumpKind ( IRJumpKind ); 804 805 806/* ------------------ Dirty helper calls ------------------ */ 807 808/* A dirty call is a flexible mechanism for calling a helper function 809 or procedure. The helper function may read, write or modify client 810 memory, and may read, write or modify client state. It can take 811 arguments and optionally return a value. It may return different 812 results and/or do different things when called repeated with the 813 same arguments, by means of storing private state. 814 815 If a value is returned, it is assigned to the nominated return 816 temporary. 817 818 Dirty calls are statements rather than expressions for obvious 819 reasons. If a dirty call is stated as writing guest state, any 820 values derived from the written parts of the guest state are 821 invalid. Similarly, if the dirty call is stated as writing 822 memory, any loaded values are invalidated by it. 823 824 In order that instrumentation is possible, the call must state, and 825 state correctly 826 827 * whether it reads, writes or modifies memory, and if so where 828 (only one chunk can be stated) 829 830 * whether it reads, writes or modifies guest state, and if so which 831 pieces (several pieces may be stated, and currently their extents 832 must be known at translation-time). 833 834 Normally, code is generated to pass just the args to the helper. 835 However, if .needsBBP is set, then an extra first argument is 836 passed, which is the baseblock pointer, so that the callee can 837 access the guest state. It is invalid for .nFxState to be zero 838 but .needsBBP to be True, since .nFxState==0 is a claim that the 839 call does not access guest state. 840 841 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The 842 arguments are evaluated REGARDLESS of the guard value. It is 843 unspecified the relative order of arg evaluation and guard 844 evaluation. 845*/ 846 847#define VEX_N_FXSTATE 7 /* enough for FXSAVE/FXRSTOR on x86 */ 848 849typedef 850 enum { 851 Ifx_None = 0x15000, /* no effect */ 852 Ifx_Read, /* reads the resource */ 853 Ifx_Write, /* writes the resource */ 854 Ifx_Modify, /* modifies the resource */ 855 } 856 IREffect; 857 858extern void ppIREffect ( IREffect ); 859 860 861typedef 862 struct { 863 /* What to call, and details of args/results */ 864 IRCallee* cee; /* where to call */ 865 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */ 866 IRExpr** args; /* arg list, ends in NULL */ 867 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */ 868 869 /* Mem effects; we allow only one R/W/M region to be stated */ 870 IREffect mFx; /* indicates memory effects, if any */ 871 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */ 872 Int mSize; /* of access, or zero if mFx==Ifx_None */ 873 874 /* Guest state effects; up to N allowed */ 875 Bool needsBBP; /* True => also pass guest state ptr to callee */ 876 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */ 877 struct { 878 IREffect fx; /* read, write or modify? Ifx_None is invalid. */ 879 Int offset; 880 Int size; 881 } fxState[VEX_N_FXSTATE]; 882 } 883 IRDirty; 884 885extern void ppIRDirty ( IRDirty* ); 886extern IRDirty* emptyIRDirty ( void ); 887 888extern IRDirty* dopyIRDirty ( IRDirty* ); 889 890/* A handy function which takes some of the tedium out of constructing 891 dirty helper calls. The called function impliedly does not return 892 any value and has a constant-True guard. The call is marked as 893 accessing neither guest state nor memory (hence the "unsafe" 894 designation) -- you can mess with this later if need be. A 895 suitable IRCallee is constructed from the supplied bits. */ 896extern 897IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr, 898 IRExpr** args ); 899 900/* Similarly, make a zero-annotation dirty call which returns a value, 901 and assign that to the given temp. */ 902extern 903IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 904 Int regparms, HChar* name, void* addr, 905 IRExpr** args ); 906 907 908/* ------------------ Statements ------------------ */ 909 910/* The possible kinds of statements are as follows. Those marked 911 OPTIONAL are hints of one kind or another, and as such do not 912 denote any change in the guest state or of IR temporaries. They 913 can therefore be omitted without changing the meaning denoted by 914 the IR. 915 916 At the moment, the only AbiHint is one which indicates that a given 917 chunk of address space has become undefined. This is used on 918 amd64-linux to pass stack-redzoning hints to whoever wants to see 919 them. 920*/ 921typedef 922 enum { 923 Ist_NoOp, /* OPTIONAL: no-op (usually resulting from IR 924 optimisation) */ 925 Ist_IMark, /* OPTIONAL: instruction mark: describe addr/len of 926 guest insn whose IR follows. */ 927 Ist_AbiHint, /* OPTIONAL: tell me something about this 928 platform's ABI */ 929 Ist_Put, /* write guest state, fixed offset */ 930 Ist_PutI, /* write guest state, run-time offset */ 931 Ist_Tmp, /* assign value to temporary */ 932 Ist_Store, /* write to memory */ 933 Ist_Dirty, /* call complex ("dirty") helper function */ 934 Ist_MFence, /* memory fence */ 935 Ist_Exit /* conditional exit from BB */ 936 } 937 IRStmtTag; 938 939typedef 940 struct _IRStmt { 941 IRStmtTag tag; 942 union { 943 struct { 944 } NoOp; 945 struct { 946 Addr64 addr; 947 Int len; 948 } IMark; 949 struct { 950 /* [base .. base+len-1] has become uninitialised */ 951 IRExpr* base; 952 Int len; 953 } AbiHint; 954 struct { 955 Int offset; 956 IRExpr* data; 957 } Put; 958 struct { 959 IRArray* descr; 960 IRExpr* ix; 961 Int bias; 962 IRExpr* data; 963 } PutI; 964 struct { 965 IRTemp tmp; 966 IRExpr* data; 967 } Tmp; 968 struct { 969 IREndness end; 970 IRExpr* addr; 971 IRExpr* data; 972 } Store; 973 struct { 974 IRDirty* details; 975 } Dirty; 976 struct { 977 } MFence; 978 struct { 979 IRExpr* guard; 980 IRJumpKind jk; 981 IRConst* dst; 982 } Exit; 983 } Ist; 984 } 985 IRStmt; 986 987extern IRStmt* IRStmt_NoOp ( void ); 988extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len ); 989extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len ); 990extern IRStmt* IRStmt_Put ( Int off, IRExpr* data ); 991extern IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix, Int bias, 992 IRExpr* data ); 993extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ); 994extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ); 995extern IRStmt* IRStmt_Dirty ( IRDirty* details ); 996extern IRStmt* IRStmt_MFence ( void ); 997extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ); 998 999extern IRStmt* dopyIRStmt ( IRStmt* ); 1000 1001extern void ppIRStmt ( IRStmt* ); 1002 1003 1004/* ------------------ Basic Blocks ------------------ */ 1005 1006/* A bunch of statements, expressions, etc, are incomplete without an 1007 environment indicating the type of each IRTemp. So this provides 1008 one. IR temporaries are really just unsigned ints and so this 1009 provides an array, 0 .. n_types_used-1 of them. 1010*/ 1011typedef 1012 struct { 1013 IRType* types; 1014 Int types_size; 1015 Int types_used; 1016 } 1017 IRTypeEnv; 1018 1019extern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 1020extern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* ); 1021 1022extern void ppIRTypeEnv ( IRTypeEnv* ); 1023 1024 1025/* Basic blocks contain: 1026 - A table giving a type for each temp 1027 - An expandable array of statements 1028 - An expression of type 32 or 64 bits, depending on the 1029 guest's word size, indicating the next destination. 1030 - An indication of any special actions (JumpKind) needed 1031 for this final jump. 1032*/ 1033typedef 1034 struct _IRBB { 1035 IRTypeEnv* tyenv; 1036 IRStmt** stmts; 1037 Int stmts_size; 1038 Int stmts_used; 1039 IRExpr* next; 1040 IRJumpKind jumpkind; 1041 } 1042 IRBB; 1043 1044extern IRBB* emptyIRBB ( void ); 1045 1046extern IRBB* dopyIRBB ( IRBB* ); 1047 1048extern void ppIRBB ( IRBB* ); 1049 1050extern void addStmtToIRBB ( IRBB*, IRStmt* ); 1051 1052 1053/*---------------------------------------------------------------*/ 1054/*--- Helper functions for the IR ---*/ 1055/*---------------------------------------------------------------*/ 1056 1057/* For messing with IR type environments */ 1058extern IRTypeEnv* emptyIRTypeEnv ( void ); 1059 1060/* What is the type of this expression? */ 1061extern IRType typeOfIRConst ( IRConst* ); 1062extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp ); 1063extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 1064 1065/* Sanity check a BB of IR */ 1066extern void sanityCheckIRBB ( IRBB* bb, 1067 HChar* caller, 1068 Bool require_flatness, 1069 IRType guest_word_size ); 1070extern Bool isFlatIRStmt ( IRStmt* ); 1071 1072/* Is this any value actually in the enumeration 'IRType' ? */ 1073extern Bool isPlausibleIRType ( IRType ty ); 1074 1075#endif /* ndef __LIBVEX_IR_H */ 1076 1077 1078/*---------------------------------------------------------------*/ 1079/*--- libvex_ir.h ---*/ 1080/*---------------------------------------------------------------*/ 1081