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