1 2 /*--------------------------------------------------------------------*/ 3 /*--- begin guest_ppc_toIR.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2017 OpenWorks LLP 11 info (at) 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 /* TODO 18/Nov/05: 37 38 Spot rld... cases which are simply left/right shifts and emit 39 Shl64/Shr64 accordingly. 40 41 Altivec 42 - datastream insns 43 - lvxl,stvxl: load/store with 'least recently used' hint 44 - vexptefp, vlogefp 45 46 LIMITATIONS: 47 48 Various, including: 49 50 - Some invalid forms of lswi and lswx are accepted when they should 51 not be. 52 53 - Floating Point: 54 - All exceptions disabled in FPSCR 55 - condition codes not set in FPSCR 56 57 - Altivec floating point: 58 - vmaddfp, vnmsubfp 59 Because we're using Java/IEEE mode (FPSCR[NJ]), rather than the 60 system default of Non-Java mode, we get some small errors 61 (lowest bit only). 62 This is because Non-Java mode brutally hacks denormalised results 63 to zero, whereas we keep maximum accuracy. However, using 64 Non-Java mode would give us more inaccuracy, as our intermediate 65 results would then be zeroed, too. 66 67 - AbiHints for the stack red zone are only emitted for 68 unconditional calls and returns (bl, blr). They should also be 69 emitted for conditional calls and returns, but we don't have a 70 way to express that right now. Ah well. 71 72 - Uses of Iop_{Add,Sub,Mul}32Fx4: the backend (host_ppc_isel.c) 73 ignores the rounding mode, and generates code that assumes 74 round-to-nearest. This means V will compute incorrect results 75 for uses of these IROps when the rounding mode (first) arg is 76 not mkU32(Irrm_NEAREST). 77 */ 78 79 /* "Special" instructions. 80 81 This instruction decoder can decode four special instructions 82 which mean nothing natively (are no-ops as far as regs/mem are 83 concerned) but have meaning for supporting Valgrind. A special 84 instruction is flagged by a 16-byte preamble: 85 86 32-bit mode: 5400183E 5400683E 5400E83E 5400983E 87 (rlwinm 0,0,3,0,31; rlwinm 0,0,13,0,31; 88 rlwinm 0,0,29,0,31; rlwinm 0,0,19,0,31) 89 90 64-bit mode: 78001800 78006800 7800E802 78009802 91 (rotldi 0,0,3; rotldi 0,0,13; 92 rotldi 0,0,61; rotldi 0,0,51) 93 94 Following that, one of the following 3 are allowed 95 (standard interpretation in parentheses): 96 97 7C210B78 (or 1,1,1) %R3 = client_request ( %R4 ) 98 7C421378 (or 2,2,2) %R3 = guest_NRADDR 99 7C631B78 (or 3,3,3) branch-and-link-to-noredir %R11 Big endian 100 7C631B78 (or 3,3,3) branch-and-link-to-noredir %R12 Little endian 101 7C842378 (or 4,4,4) %R3 = guest_NRADDR_GPR2 102 7CA52B78 (or 5,5,5) IR injection 103 104 Any other bytes following the 16-byte preamble are illegal and 105 constitute a failure in instruction decoding. This all assumes 106 that the preamble will never occur except in specific code 107 fragments designed for Valgrind to catch. 108 */ 109 110 /* Little Endian notes */ 111 /* 112 * Vector operations in little Endian mode behave in non-obvious ways at times. 113 * Below is an attempt at explaining this. 114 * 115 * LE/BE vector example 116 * With a vector of unsigned ints declared as follows: 117 * vector unsigned int vec_inA = 118 { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }; 119 * The '0x11111111' word is word zero in both LE and BE format. But the 120 * loaded vector register will have word zero on the far left in BE mode and 121 * on the far right in LE mode. The lvx and stvx instructions work naturally 122 * for whatever endianness is in effect. For example, in LE mode, the stvx 123 * stores word zero (far right word) of the vector at the lowest memory 124 * address of the EA; in BE mode, stvx still stores word zero at the lowest 125 * memory address, but with word zero interpreted as the one at the far left 126 * of the register. 127 * 128 * The lxvd2x and stxvd2x instructions are not so well suited for LE mode. 129 * When the compiler generates an lxvd2x instruction to load the 130 * above-declared vector of unsigned integers, it loads the vector as two 131 * double words, but they are in BE word-wise format. To put the vector in 132 * the right order for LE, the compiler also generates an xxswapd after the 133 * load, which puts it in proper LE format. Similarly, the stxvd2x 134 * instruction has a BE bias, storing the vector in BE word-wise format. But 135 * the compiler also generates an xxswapd prior to the store, thus ensuring 136 * the vector is stored in memory in the correct LE order. 137 * 138 * Vector-flavored Iops, such Iop_V128Hito64, reference the hi and lo parts 139 * of a double words and words within a vector. Because of the reverse order 140 * of numbering for LE as described above, the high part refers to word 1 in 141 * LE format. When input data is saved to a guest state vector register 142 * (e.g., via Iop_64HLtoV128), it is first saved to memory and then the 143 * register is loaded via PPCInstr_AvLdSt, which does an lvx instruction. 144 * The saving of the data to memory must be done in proper LE order. For the 145 * inverse operation of extracting data from a vector register (e.g., 146 * Iop_V128Hito64), the register is first saved (by PPCInstr_AvLdSt resulting 147 * in stvx), and then integer registers are loaded from the memory location 148 * from where the vector register was saved. Again, this must be done in 149 * proper LE order. So for these various vector Iops, we have LE-specific 150 * code in host_ppc_isel.c 151 * 152 * Another unique behavior of vectors in LE mode is with the vector scalar 153 * (VSX) operations that operate on "double word 0" of the source register, 154 * storing the result in "double word 0" of the output vector register. For 155 * these operations, "double word 0" is interpreted as "high half of the 156 * register" (i.e, the part on the left side). 157 * 158 */ 159 /* Translates PPC32/64 code to IR. */ 160 161 /* References 162 163 #define PPC32 164 "PowerPC Microprocessor Family: 165 The Programming Environments Manual for 32-Bit Microprocessors" 166 02/21/2000 167 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2 168 169 #define PPC64 170 "PowerPC Microprocessor Family: 171 Programming Environments Manual for 64-Bit Microprocessors" 172 06/10/2003 173 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/F7E732FF811F783187256FDD004D3797 174 175 #define AV 176 "PowerPC Microprocessor Family: 177 AltiVec(TM) Technology Programming Environments Manual" 178 07/10/2003 179 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/FBFA164F824370F987256D6A006F424D 180 */ 181 182 #include "libvex_basictypes.h" 183 #include "libvex_ir.h" 184 #include "libvex.h" 185 #include "libvex_emnote.h" 186 #include "libvex_guest_ppc32.h" 187 #include "libvex_guest_ppc64.h" 188 189 #include "main_util.h" 190 #include "main_globals.h" 191 #include "guest_generic_bb_to_IR.h" 192 #include "guest_ppc_defs.h" 193 194 /*------------------------------------------------------------*/ 195 /*--- Globals ---*/ 196 /*------------------------------------------------------------*/ 197 198 /* These are set at the start of the translation of an insn, right 199 down in disInstr_PPC, so that we don't have to pass them around 200 endlessly. They are all constant during the translation of any 201 given insn. */ 202 203 /* We need to know this to do sub-register accesses correctly. */ 204 static VexEndness host_endness; 205 206 /* Pointer to the guest code area. */ 207 static const UChar* guest_code; 208 209 /* The guest address corresponding to guest_code[0]. */ 210 static Addr64 guest_CIA_bbstart; 211 212 /* The guest address for the instruction currently being 213 translated. */ 214 static Addr64 guest_CIA_curr_instr; 215 216 /* The IRSB* into which we're generating code. */ 217 static IRSB* irsb; 218 219 /* Is our guest binary 32 or 64bit? Set at each call to 220 disInstr_PPC below. */ 221 static Bool mode64 = False; 222 223 // Given a pointer to a function as obtained by "& functionname" in C, 224 // produce a pointer to the actual entry point for the function. For 225 // most platforms it's the identity function. Unfortunately, on 226 // ppc64-linux it isn't (sigh) 227 static void* fnptr_to_fnentry( const VexAbiInfo* vbi, void* f ) 228 { 229 if (vbi->host_ppc_calls_use_fndescrs) { 230 /* f is a pointer to a 3-word function descriptor, of which the 231 first word is the entry address. */ 232 /* note, this is correct even with cross-jitting, since this is 233 purely a host issue, not a guest one. */ 234 HWord* fdescr = (HWord*)f; 235 return (void*)(fdescr[0]); 236 } else { 237 /* Simple; "& f" points directly at the code for f. */ 238 return f; 239 } 240 } 241 242 /* The OV32 and CA32 bits were added with ISA3.0 */ 243 static Bool OV32_CA32_supported = False; 244 245 #define SIGN_BIT 0x8000000000000000ULL 246 #define SIGN_MASK 0x7fffffffffffffffULL 247 #define SIGN_BIT32 0x80000000 248 #define SIGN_MASK32 0x7fffffff 249 250 251 /*------------------------------------------------------------*/ 252 /*--- Debugging output ---*/ 253 /*------------------------------------------------------------*/ 254 255 #define DIP(format, args...) \ 256 if (vex_traceflags & VEX_TRACE_FE) \ 257 vex_printf(format, ## args) 258 259 #define DIS(buf, format, args...) \ 260 if (vex_traceflags & VEX_TRACE_FE) \ 261 vex_sprintf(buf, format, ## args) 262 263 264 /*------------------------------------------------------------*/ 265 /*--- Offsets of various parts of the ppc32/64 guest state ---*/ 266 /*------------------------------------------------------------*/ 267 268 #define offsetofPPCGuestState(_x) \ 269 (mode64 ? offsetof(VexGuestPPC64State, _x) : \ 270 offsetof(VexGuestPPC32State, _x)) 271 272 #define OFFB_CIA offsetofPPCGuestState(guest_CIA) 273 #define OFFB_IP_AT_SYSCALL offsetofPPCGuestState(guest_IP_AT_SYSCALL) 274 #define OFFB_SPRG3_RO offsetofPPCGuestState(guest_SPRG3_RO) 275 #define OFFB_LR offsetofPPCGuestState(guest_LR) 276 #define OFFB_CTR offsetofPPCGuestState(guest_CTR) 277 #define OFFB_XER_SO offsetofPPCGuestState(guest_XER_SO) 278 #define OFFB_XER_OV offsetofPPCGuestState(guest_XER_OV) 279 #define OFFB_XER_OV32 offsetofPPCGuestState(guest_XER_OV32) 280 #define OFFB_XER_CA offsetofPPCGuestState(guest_XER_CA) 281 #define OFFB_XER_CA32 offsetofPPCGuestState(guest_XER_CA32) 282 #define OFFB_XER_BC offsetofPPCGuestState(guest_XER_BC) 283 #define OFFB_FPROUND offsetofPPCGuestState(guest_FPROUND) 284 #define OFFB_DFPROUND offsetofPPCGuestState(guest_DFPROUND) 285 #define OFFB_C_FPCC offsetofPPCGuestState(guest_C_FPCC) 286 #define OFFB_VRSAVE offsetofPPCGuestState(guest_VRSAVE) 287 #define OFFB_VSCR offsetofPPCGuestState(guest_VSCR) 288 #define OFFB_EMNOTE offsetofPPCGuestState(guest_EMNOTE) 289 #define OFFB_CMSTART offsetofPPCGuestState(guest_CMSTART) 290 #define OFFB_CMLEN offsetofPPCGuestState(guest_CMLEN) 291 #define OFFB_NRADDR offsetofPPCGuestState(guest_NRADDR) 292 #define OFFB_NRADDR_GPR2 offsetofPPCGuestState(guest_NRADDR_GPR2) 293 #define OFFB_TFHAR offsetofPPCGuestState(guest_TFHAR) 294 #define OFFB_TEXASR offsetofPPCGuestState(guest_TEXASR) 295 #define OFFB_TEXASRU offsetofPPCGuestState(guest_TEXASRU) 296 #define OFFB_TFIAR offsetofPPCGuestState(guest_TFIAR) 297 #define OFFB_PPR offsetofPPCGuestState(guest_PPR) 298 #define OFFB_PSPB offsetofPPCGuestState(guest_PSPB) 299 300 301 /*------------------------------------------------------------*/ 302 /*--- Extract instruction fields --- */ 303 /*------------------------------------------------------------*/ 304 305 /* Extract field from insn, given idx (zero = lsb) and field length */ 306 #define IFIELD( insn, idx, len ) ((insn >> idx) & ((1<<len)-1)) 307 308 /* Extract primary opcode, instr[31:26] */ 309 static UChar ifieldOPC( UInt instr ) { 310 return toUChar( IFIELD( instr, 26, 6 ) ); 311 } 312 313 /* Extract 10-bit secondary opcode, instr[10:1] */ 314 static UInt ifieldOPClo10 ( UInt instr) { 315 return IFIELD( instr, 1, 10 ); 316 } 317 318 /* Extract 9-bit secondary opcode, instr[9:1] */ 319 static UInt ifieldOPClo9 ( UInt instr) { 320 return IFIELD( instr, 1, 9 ); 321 } 322 323 /* Extract 8-bit secondary opcode, instr[8:1] */ 324 static UInt ifieldOPClo8 ( UInt instr) { 325 return IFIELD( instr, 1, 8 ); 326 } 327 328 /* Extract 5-bit secondary opcode, instr[5:1] */ 329 static UInt ifieldOPClo5 ( UInt instr) { 330 return IFIELD( instr, 1, 5 ); 331 } 332 333 /* Extract 2-bit secondary opcode, instr[1:0] */ 334 static UInt ifieldOPC0o2 ( UInt instr) { 335 return IFIELD( instr, 0, 2 ); 336 } 337 338 /* Extract RD (destination register) field, instr[25:21] */ 339 static UChar ifieldRegDS( UInt instr ) { 340 return toUChar( IFIELD( instr, 21, 5 ) ); 341 } 342 343 /* Extract XT (destination register) field, instr[0,25:21] */ 344 static UChar ifieldRegXT ( UInt instr ) 345 { 346 UChar upper_bit = toUChar (IFIELD (instr, 0, 1)); 347 UChar lower_bits = toUChar (IFIELD (instr, 21, 5)); 348 return (upper_bit << 5) | lower_bits; 349 } 350 351 /* Extract XS (store source register) field, instr[0,25:21] */ 352 static inline UChar ifieldRegXS ( UInt instr ) 353 { 354 return ifieldRegXT ( instr ); 355 } 356 357 /* Extract RA (1st source register) field, instr[20:16] */ 358 static UChar ifieldRegA ( UInt instr ) { 359 return toUChar( IFIELD( instr, 16, 5 ) ); 360 } 361 362 /* Extract XA (1st source register) field, instr[2,20:16] */ 363 static UChar ifieldRegXA ( UInt instr ) 364 { 365 UChar upper_bit = toUChar (IFIELD (instr, 2, 1)); 366 UChar lower_bits = toUChar (IFIELD (instr, 16, 5)); 367 return (upper_bit << 5) | lower_bits; 368 } 369 370 /* Extract RB (2nd source register) field, instr[15:11] */ 371 static UChar ifieldRegB ( UInt instr ) { 372 return toUChar( IFIELD( instr, 11, 5 ) ); 373 } 374 375 /* Extract XB (2nd source register) field, instr[1,15:11] */ 376 static UChar ifieldRegXB ( UInt instr ) 377 { 378 UChar upper_bit = toUChar (IFIELD (instr, 1, 1)); 379 UChar lower_bits = toUChar (IFIELD (instr, 11, 5)); 380 return (upper_bit << 5) | lower_bits; 381 } 382 383 /* Extract RC (3rd source register) field, instr[10:6] */ 384 static UChar ifieldRegC ( UInt instr ) { 385 return toUChar( IFIELD( instr, 6, 5 ) ); 386 } 387 388 /* Extract XC (3rd source register) field, instr[3,10:6] */ 389 static UChar ifieldRegXC ( UInt instr ) 390 { 391 UChar upper_bit = toUChar (IFIELD (instr, 3, 1)); 392 UChar lower_bits = toUChar (IFIELD (instr, 6, 5)); 393 return (upper_bit << 5) | lower_bits; 394 } 395 396 /* Extract bit 10, instr[10] */ 397 static UChar ifieldBIT10 ( UInt instr ) { 398 return toUChar( IFIELD( instr, 10, 1 ) ); 399 } 400 401 /* Extract 2nd lowest bit, instr[1] */ 402 static UChar ifieldBIT1 ( UInt instr ) { 403 return toUChar( IFIELD( instr, 1, 1 ) ); 404 } 405 406 /* Extract lowest bit, instr[0] */ 407 static UChar ifieldBIT0 ( UInt instr ) { 408 return toUChar( instr & 0x1 ); 409 } 410 411 /* Extract unsigned bottom half, instr[15:0] */ 412 static UInt ifieldUIMM16 ( UInt instr ) { 413 return instr & 0xFFFF; 414 } 415 416 /* Extract unsigned bottom 26 bits, instr[25:0] */ 417 static UInt ifieldUIMM26 ( UInt instr ) { 418 return instr & 0x3FFFFFF; 419 } 420 421 /* Extract DM field, instr[9:8] */ 422 static UChar ifieldDM ( UInt instr ) { 423 return toUChar( IFIELD( instr, 8, 2 ) ); 424 } 425 426 /* Extract SHW field, instr[9:8] */ 427 static inline UChar ifieldSHW ( UInt instr ) 428 { 429 return ifieldDM ( instr ); 430 } 431 432 /*------------------------------------------------------------*/ 433 /*--- Guest-state identifiers ---*/ 434 /*------------------------------------------------------------*/ 435 436 typedef enum { 437 PPC_GST_CIA, // Current Instruction Address 438 PPC_GST_LR, // Link Register 439 PPC_GST_CTR, // Count Register 440 PPC_GST_XER, // Overflow, carry flags, byte count 441 PPC_GST_CR, // Condition Register 442 PPC_GST_FPSCR, // Floating Point Status/Control Register 443 PPC_GST_VRSAVE, // Vector Save/Restore Register 444 PPC_GST_VSCR, // Vector Status and Control Register 445 PPC_GST_EMWARN, // Emulation warnings 446 PPC_GST_CMSTART,// For icbi: start of area to invalidate 447 PPC_GST_CMLEN, // For icbi: length of area to invalidate 448 PPC_GST_IP_AT_SYSCALL, // the CIA of the most recently executed SC insn 449 PPC_GST_SPRG3_RO, // SPRG3 450 PPC_GST_TFHAR, // Transactional Failure Handler Address Register 451 PPC_GST_TFIAR, // Transactional Failure Instruction Address Register 452 PPC_GST_TEXASR, // Transactional EXception And Summary Register 453 PPC_GST_TEXASRU, // Transactional EXception And Summary Register Upper 454 PPC_GST_PPR, // Program Priority register 455 PPC_GST_PPR32, // Upper 32-bits of Program Priority register 456 PPC_GST_PSPB, /* Problem State Priority Boost register, Note, the 457 * register is initialized to a non-zero value. Currently 458 * Valgrind is not supporting the register value to 459 * automatically decrement. Could be added later if 460 * needed. 461 */ 462 PPC_GST_MAX 463 } PPC_GST; 464 465 #define MASK_FPSCR_RN 0x3ULL // Binary floating point rounding mode 466 #define MASK_FPSCR_DRN 0x700000000ULL // Decimal floating point rounding mode 467 #define MASK_FPSCR_C_FPCC 0x1F000ULL // Floating-Point Condition code FPCC 468 469 #define MASK_VSCR_VALID 0x00010001 470 471 472 /*------------------------------------------------------------*/ 473 /*--- FP Helpers ---*/ 474 /*------------------------------------------------------------*/ 475 476 /* Produce the 32-bit pattern corresponding to the supplied 477 float. */ 478 static UInt float_to_bits ( Float f ) 479 { 480 union { UInt i; Float f; } u; 481 vassert(4 == sizeof(UInt)); 482 vassert(4 == sizeof(Float)); 483 vassert(4 == sizeof(u)); 484 u.f = f; 485 return u.i; 486 } 487 488 489 /*------------------------------------------------------------*/ 490 /*--- Misc Helpers ---*/ 491 /*------------------------------------------------------------*/ 492 493 /* Generate mask with 1's from 'begin' through 'end', 494 wrapping if begin > end. 495 begin->end works from right to left, 0=lsb 496 */ 497 static UInt MASK32( UInt begin, UInt end ) 498 { 499 UInt m1, m2, mask; 500 vassert(begin < 32); 501 vassert(end < 32); 502 m1 = ((UInt)(-1)) << begin; 503 m2 = ((UInt)(-1)) << end << 1; 504 mask = m1 ^ m2; 505 if (begin > end) mask = ~mask; // wrap mask 506 return mask; 507 } 508 509 static ULong MASK64( UInt begin, UInt end ) 510 { 511 ULong m1, m2, mask; 512 vassert(begin < 64); 513 vassert(end < 64); 514 m1 = ((ULong)(-1)) << begin; 515 m2 = ((ULong)(-1)) << end << 1; 516 mask = m1 ^ m2; 517 if (begin > end) mask = ~mask; // wrap mask 518 return mask; 519 } 520 521 static Addr64 nextInsnAddr( void ) 522 { 523 return guest_CIA_curr_instr + 4; 524 } 525 526 527 /*------------------------------------------------------------*/ 528 /*--- Helper bits and pieces for deconstructing the ---*/ 529 /*--- ppc32/64 insn stream. ---*/ 530 /*------------------------------------------------------------*/ 531 532 /* Add a statement to the list held by "irsb". */ 533 static void stmt ( IRStmt* st ) 534 { 535 addStmtToIRSB( irsb, st ); 536 } 537 538 /* Generate a new temporary of the given type. */ 539 static IRTemp newTemp ( IRType ty ) 540 { 541 vassert(isPlausibleIRType(ty)); 542 return newIRTemp( irsb->tyenv, ty ); 543 } 544 545 /* Various simple conversions */ 546 547 static UChar extend_s_5to8 ( UChar x ) 548 { 549 return toUChar((((Int)x) << 27) >> 27); 550 } 551 552 static UInt extend_s_8to32( UChar x ) 553 { 554 return (UInt)((((Int)x) << 24) >> 24); 555 } 556 557 static UInt extend_s_16to32 ( UInt x ) 558 { 559 return (UInt)((((Int)x) << 16) >> 16); 560 } 561 562 static ULong extend_s_16to64 ( UInt x ) 563 { 564 return (ULong)((((Long)x) << 48) >> 48); 565 } 566 567 static ULong extend_s_26to64 ( UInt x ) 568 { 569 return (ULong)((((Long)x) << 38) >> 38); 570 } 571 572 static ULong extend_s_32to64 ( UInt x ) 573 { 574 return (ULong)((((Long)x) << 32) >> 32); 575 } 576 577 /* Do a proper-endian load of a 32-bit word, regardless of the endianness 578 of the underlying host. */ 579 static UInt getUIntPPCendianly ( const UChar* p ) 580 { 581 UInt w = 0; 582 if (host_endness == VexEndnessBE) { 583 w = (w << 8) | p[0]; 584 w = (w << 8) | p[1]; 585 w = (w << 8) | p[2]; 586 w = (w << 8) | p[3]; 587 } else { 588 w = (w << 8) | p[3]; 589 w = (w << 8) | p[2]; 590 w = (w << 8) | p[1]; 591 w = (w << 8) | p[0]; 592 } 593 return w; 594 } 595 596 597 /*------------------------------------------------------------*/ 598 /*--- Helpers for constructing IR. ---*/ 599 /*------------------------------------------------------------*/ 600 601 static void assign ( IRTemp dst, IRExpr* e ) 602 { 603 stmt( IRStmt_WrTmp(dst, e) ); 604 } 605 606 /* This generates a normal (non store-conditional) store. */ 607 static void store ( IRExpr* addr, IRExpr* data ) 608 { 609 IRType tyA = typeOfIRExpr(irsb->tyenv, addr); 610 vassert(tyA == Ity_I32 || tyA == Ity_I64); 611 612 if (host_endness == VexEndnessBE) 613 stmt( IRStmt_Store(Iend_BE, addr, data) ); 614 else 615 stmt( IRStmt_Store(Iend_LE, addr, data) ); 616 } 617 618 static IRExpr* unop ( IROp op, IRExpr* a ) 619 { 620 return IRExpr_Unop(op, a); 621 } 622 623 static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ) 624 { 625 return IRExpr_Binop(op, a1, a2); 626 } 627 628 static IRExpr* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 ) 629 { 630 return IRExpr_Triop(op, a1, a2, a3); 631 } 632 633 static IRExpr* qop ( IROp op, IRExpr* a1, IRExpr* a2, 634 IRExpr* a3, IRExpr* a4 ) 635 { 636 return IRExpr_Qop(op, a1, a2, a3, a4); 637 } 638 639 static IRExpr* mkexpr ( IRTemp tmp ) 640 { 641 return IRExpr_RdTmp(tmp); 642 } 643 644 #define mkU1(_n) IRExpr_Const(IRConst_U1(_n)) 645 646 static IRExpr* mkU8 ( UChar i ) 647 { 648 return IRExpr_Const(IRConst_U8(i)); 649 } 650 651 static IRExpr* mkU16 ( UInt i ) 652 { 653 return IRExpr_Const(IRConst_U16(i)); 654 } 655 656 static IRExpr* mkU32 ( UInt i ) 657 { 658 return IRExpr_Const(IRConst_U32(i)); 659 } 660 661 static IRExpr* mkU64 ( ULong i ) 662 { 663 return IRExpr_Const(IRConst_U64(i)); 664 } 665 666 static IRExpr* mkV128 ( UShort i ) 667 { 668 vassert(i == 0 || i == 0xffff); 669 return IRExpr_Const(IRConst_V128(i)); 670 } 671 672 /* This generates a normal (non load-linked) load. */ 673 static IRExpr* load ( IRType ty, IRExpr* addr ) 674 { 675 if (host_endness == VexEndnessBE) 676 return IRExpr_Load(Iend_BE, ty, addr); 677 else 678 return IRExpr_Load(Iend_LE, ty, addr); 679 } 680 681 static IRStmt* stmt_load ( IRTemp result, 682 IRExpr* addr, IRExpr* storedata ) 683 { 684 if (host_endness == VexEndnessBE) 685 return IRStmt_LLSC(Iend_BE, result, addr, storedata); 686 else 687 return IRStmt_LLSC(Iend_LE, result, addr, storedata); 688 } 689 690 static IRExpr* mkOR1 ( IRExpr* arg1, IRExpr* arg2 ) 691 { 692 vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1); 693 vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1); 694 return unop(Iop_32to1, binop(Iop_Or32, unop(Iop_1Uto32, arg1), 695 unop(Iop_1Uto32, arg2))); 696 } 697 698 static IRExpr* mkAND1 ( IRExpr* arg1, IRExpr* arg2 ) 699 { 700 vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1); 701 vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1); 702 return unop(Iop_32to1, binop(Iop_And32, unop(Iop_1Uto32, arg1), 703 unop(Iop_1Uto32, arg2))); 704 } 705 706 static inline IRExpr* mkXOr4_32( IRTemp t0, IRTemp t1, IRTemp t2, 707 IRTemp t3 ) 708 { 709 return binop( Iop_Xor32, 710 binop( Iop_Xor32, mkexpr( t0 ), mkexpr( t1 ) ), 711 binop( Iop_Xor32, mkexpr( t2 ), mkexpr( t3 ) ) ); 712 } 713 714 static inline IRExpr* mkOr3_V128( IRTemp t0, IRTemp t1, IRTemp t2 ) 715 { 716 return binop( Iop_OrV128, 717 mkexpr( t0 ), 718 binop( Iop_OrV128, mkexpr( t1 ), mkexpr( t2 ) ) ); 719 } 720 721 static inline IRExpr* mkOr4_V128( IRTemp t0, IRTemp t1, IRTemp t2, 722 IRTemp t3 ) 723 { 724 return binop( Iop_OrV128, 725 binop( Iop_OrV128, mkexpr( t0 ), mkexpr( t1 ) ), 726 binop( Iop_OrV128, mkexpr( t2 ), mkexpr( t3 ) ) ); 727 } 728 729 static inline IRExpr* mkOr4_V128_expr( IRExpr* t0, IRExpr* t1, IRExpr* t2, 730 IRExpr* t3 ) 731 { 732 /* arguments are already expressions */ 733 return binop( Iop_OrV128, 734 binop( Iop_OrV128, ( t0 ), ( t1 ) ), 735 binop( Iop_OrV128, ( t2 ), ( t3 ) ) ); 736 } 737 738 static IRExpr* mkNOT1 ( IRExpr* arg1 ) 739 { 740 vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1); 741 return unop(Iop_32to1, unop(Iop_Not32, unop(Iop_1Uto32, arg1) ) ); 742 } 743 744 /* expand V128_8Ux16 to 2x V128_16Ux8's */ 745 static void expand8Ux16( IRExpr* vIn, 746 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 747 { 748 IRTemp ones8x16 = newTemp(Ity_V128); 749 750 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 751 vassert(vEvn && *vEvn == IRTemp_INVALID); 752 vassert(vOdd && *vOdd == IRTemp_INVALID); 753 *vEvn = newTemp(Ity_V128); 754 *vOdd = newTemp(Ity_V128); 755 756 assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); 757 assign( *vOdd, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), vIn) ); 758 assign( *vEvn, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), 759 binop(Iop_ShrV128, vIn, mkU8(8))) ); 760 } 761 762 /* expand V128_8Sx16 to 2x V128_16Sx8's */ 763 static void expand8Sx16( IRExpr* vIn, 764 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 765 { 766 IRTemp ones8x16 = newTemp(Ity_V128); 767 768 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 769 vassert(vEvn && *vEvn == IRTemp_INVALID); 770 vassert(vOdd && *vOdd == IRTemp_INVALID); 771 *vEvn = newTemp(Ity_V128); 772 *vOdd = newTemp(Ity_V128); 773 774 assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); 775 assign( *vOdd, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), vIn) ); 776 assign( *vEvn, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), 777 binop(Iop_ShrV128, vIn, mkU8(8))) ); 778 } 779 780 /* expand V128_16Uto8 to 2x V128_32Ux4's */ 781 static void expand16Ux8( IRExpr* vIn, 782 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 783 { 784 IRTemp ones16x8 = newTemp(Ity_V128); 785 786 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 787 vassert(vEvn && *vEvn == IRTemp_INVALID); 788 vassert(vOdd && *vOdd == IRTemp_INVALID); 789 *vEvn = newTemp(Ity_V128); 790 *vOdd = newTemp(Ity_V128); 791 792 assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); 793 assign( *vOdd, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), vIn) ); 794 assign( *vEvn, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), 795 binop(Iop_ShrV128, vIn, mkU8(16))) ); 796 } 797 798 /* expand V128_16Sto8 to 2x V128_32Sx4's */ 799 static void expand16Sx8( IRExpr* vIn, 800 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 801 { 802 IRTemp ones16x8 = newTemp(Ity_V128); 803 804 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 805 vassert(vEvn && *vEvn == IRTemp_INVALID); 806 vassert(vOdd && *vOdd == IRTemp_INVALID); 807 *vEvn = newTemp(Ity_V128); 808 *vOdd = newTemp(Ity_V128); 809 810 assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); 811 assign( *vOdd, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), vIn) ); 812 assign( *vEvn, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), 813 binop(Iop_ShrV128, vIn, mkU8(16))) ); 814 } 815 816 /* break V128 to 4xF64's*/ 817 static void breakV128to4xF64( IRExpr* t128, 818 /*OUTs*/ 819 IRTemp* t3, IRTemp* t2, 820 IRTemp* t1, IRTemp* t0 ) 821 { 822 IRTemp hi64 = newTemp(Ity_I64); 823 IRTemp lo64 = newTemp(Ity_I64); 824 825 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 826 vassert(t0 && *t0 == IRTemp_INVALID); 827 vassert(t1 && *t1 == IRTemp_INVALID); 828 vassert(t2 && *t2 == IRTemp_INVALID); 829 vassert(t3 && *t3 == IRTemp_INVALID); 830 *t0 = newTemp(Ity_F64); 831 *t1 = newTemp(Ity_F64); 832 *t2 = newTemp(Ity_F64); 833 *t3 = newTemp(Ity_F64); 834 835 assign( hi64, unop(Iop_V128HIto64, t128) ); 836 assign( lo64, unop(Iop_V128to64, t128) ); 837 assign( *t3, 838 unop( Iop_F32toF64, 839 unop( Iop_ReinterpI32asF32, 840 unop( Iop_64HIto32, mkexpr( hi64 ) ) ) ) ); 841 assign( *t2, 842 unop( Iop_F32toF64, 843 unop( Iop_ReinterpI32asF32, unop( Iop_64to32, mkexpr( hi64 ) ) ) ) ); 844 assign( *t1, 845 unop( Iop_F32toF64, 846 unop( Iop_ReinterpI32asF32, 847 unop( Iop_64HIto32, mkexpr( lo64 ) ) ) ) ); 848 assign( *t0, 849 unop( Iop_F32toF64, 850 unop( Iop_ReinterpI32asF32, unop( Iop_64to32, mkexpr( lo64 ) ) ) ) ); 851 } 852 853 854 /* break V128 to 4xI32's, then sign-extend to I64's */ 855 static void breakV128to4x64S( IRExpr* t128, 856 /*OUTs*/ 857 IRTemp* t3, IRTemp* t2, 858 IRTemp* t1, IRTemp* t0 ) 859 { 860 IRTemp hi64 = newTemp(Ity_I64); 861 IRTemp lo64 = newTemp(Ity_I64); 862 863 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 864 vassert(t0 && *t0 == IRTemp_INVALID); 865 vassert(t1 && *t1 == IRTemp_INVALID); 866 vassert(t2 && *t2 == IRTemp_INVALID); 867 vassert(t3 && *t3 == IRTemp_INVALID); 868 *t0 = newTemp(Ity_I64); 869 *t1 = newTemp(Ity_I64); 870 *t2 = newTemp(Ity_I64); 871 *t3 = newTemp(Ity_I64); 872 873 assign( hi64, unop(Iop_V128HIto64, t128) ); 874 assign( lo64, unop(Iop_V128to64, t128) ); 875 assign( *t3, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(hi64))) ); 876 assign( *t2, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(hi64))) ); 877 assign( *t1, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(lo64))) ); 878 assign( *t0, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(lo64))) ); 879 } 880 881 /* break V128 to 4xI32's, then zero-extend to I64's */ 882 static void breakV128to4x64U ( IRExpr* t128, 883 /*OUTs*/ 884 IRTemp* t3, IRTemp* t2, 885 IRTemp* t1, IRTemp* t0 ) 886 { 887 IRTemp hi64 = newTemp(Ity_I64); 888 IRTemp lo64 = newTemp(Ity_I64); 889 890 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 891 vassert(t0 && *t0 == IRTemp_INVALID); 892 vassert(t1 && *t1 == IRTemp_INVALID); 893 vassert(t2 && *t2 == IRTemp_INVALID); 894 vassert(t3 && *t3 == IRTemp_INVALID); 895 *t0 = newTemp(Ity_I64); 896 *t1 = newTemp(Ity_I64); 897 *t2 = newTemp(Ity_I64); 898 *t3 = newTemp(Ity_I64); 899 900 assign( hi64, unop(Iop_V128HIto64, t128) ); 901 assign( lo64, unop(Iop_V128to64, t128) ); 902 assign( *t3, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(hi64))) ); 903 assign( *t2, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(hi64))) ); 904 assign( *t1, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(lo64))) ); 905 assign( *t0, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(lo64))) ); 906 } 907 908 static void breakV128to4x32( IRExpr* t128, 909 /*OUTs*/ 910 IRTemp* t3, IRTemp* t2, 911 IRTemp* t1, IRTemp* t0 ) 912 { 913 IRTemp hi64 = newTemp(Ity_I64); 914 IRTemp lo64 = newTemp(Ity_I64); 915 916 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 917 vassert(t0 && *t0 == IRTemp_INVALID); 918 vassert(t1 && *t1 == IRTemp_INVALID); 919 vassert(t2 && *t2 == IRTemp_INVALID); 920 vassert(t3 && *t3 == IRTemp_INVALID); 921 *t0 = newTemp(Ity_I32); 922 *t1 = newTemp(Ity_I32); 923 *t2 = newTemp(Ity_I32); 924 *t3 = newTemp(Ity_I32); 925 926 assign( hi64, unop(Iop_V128HIto64, t128) ); 927 assign( lo64, unop(Iop_V128to64, t128) ); 928 assign( *t3, unop(Iop_64HIto32, mkexpr(hi64)) ); 929 assign( *t2, unop(Iop_64to32, mkexpr(hi64)) ); 930 assign( *t1, unop(Iop_64HIto32, mkexpr(lo64)) ); 931 assign( *t0, unop(Iop_64to32, mkexpr(lo64)) ); 932 } 933 934 static IRExpr* mkV128from32( IRTemp t3, IRTemp t2, 935 IRTemp t1, IRTemp t0 ) 936 { 937 return 938 binop( Iop_64HLtoV128, 939 binop(Iop_32HLto64, mkexpr(t3), mkexpr(t2)), 940 binop(Iop_32HLto64, mkexpr(t1), mkexpr(t0)) 941 ); 942 } 943 944 static IRExpr* extract_field_from_vector( IRTemp vB, IRExpr* index, UInt mask) 945 { 946 /* vB is a vector, extract bits starting at index to size of mask */ 947 return unop( Iop_V128to64, 948 binop( Iop_AndV128, 949 binop( Iop_ShrV128, 950 mkexpr( vB ), 951 unop( Iop_64to8, 952 binop( Iop_Mul64, index, 953 mkU64( 8 ) ) ) ), 954 binop( Iop_64HLtoV128, 955 mkU64( 0x0 ), 956 mkU64( mask ) ) ) ); 957 } 958 959 /* Signed saturating narrow 64S to 32 */ 960 static IRExpr* mkQNarrow64Sto32 ( IRExpr* t64 ) 961 { 962 IRTemp hi32 = newTemp(Ity_I32); 963 IRTemp lo32 = newTemp(Ity_I32); 964 965 vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64); 966 967 assign( hi32, unop(Iop_64HIto32, t64)); 968 assign( lo32, unop(Iop_64to32, t64)); 969 970 return IRExpr_ITE( 971 /* if (hi32 == (lo32 >>s 31)) */ 972 binop(Iop_CmpEQ32, mkexpr(hi32), 973 binop( Iop_Sar32, mkexpr(lo32), mkU8(31))), 974 /* then: within signed-32 range: lo half good enough */ 975 mkexpr(lo32), 976 /* else: sign dep saturate: 1->0x80000000, 0->0x7FFFFFFF */ 977 binop(Iop_Add32, mkU32(0x7FFFFFFF), 978 binop(Iop_Shr32, mkexpr(hi32), mkU8(31)))); 979 } 980 981 /* Unsigned saturating narrow 64S to 32 */ 982 static IRExpr* mkQNarrow64Uto32 ( IRExpr* t64 ) 983 { 984 IRTemp hi32 = newTemp(Ity_I32); 985 IRTemp lo32 = newTemp(Ity_I32); 986 987 vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64); 988 989 assign( hi32, unop(Iop_64HIto32, t64)); 990 assign( lo32, unop(Iop_64to32, t64)); 991 992 return IRExpr_ITE( 993 /* if (top 32 bits of t64 are 0) */ 994 binop(Iop_CmpEQ32, mkexpr(hi32), mkU32(0)), 995 /* then: within unsigned-32 range: lo half good enough */ 996 mkexpr(lo32), 997 /* else: positive saturate -> 0xFFFFFFFF */ 998 mkU32(0xFFFFFFFF)); 999 } 1000 1001 /* Signed saturate narrow 64->32, combining to V128 */ 1002 static IRExpr* mkV128from4x64S ( IRExpr* t3, IRExpr* t2, 1003 IRExpr* t1, IRExpr* t0 ) 1004 { 1005 vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64); 1006 vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64); 1007 vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64); 1008 vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64); 1009 return binop(Iop_64HLtoV128, 1010 binop(Iop_32HLto64, 1011 mkQNarrow64Sto32( t3 ), 1012 mkQNarrow64Sto32( t2 )), 1013 binop(Iop_32HLto64, 1014 mkQNarrow64Sto32( t1 ), 1015 mkQNarrow64Sto32( t0 ))); 1016 } 1017 1018 /* Unsigned saturate narrow 64->32, combining to V128 */ 1019 static IRExpr* mkV128from4x64U ( IRExpr* t3, IRExpr* t2, 1020 IRExpr* t1, IRExpr* t0 ) 1021 { 1022 vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64); 1023 vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64); 1024 vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64); 1025 vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64); 1026 return binop(Iop_64HLtoV128, 1027 binop(Iop_32HLto64, 1028 mkQNarrow64Uto32( t3 ), 1029 mkQNarrow64Uto32( t2 )), 1030 binop(Iop_32HLto64, 1031 mkQNarrow64Uto32( t1 ), 1032 mkQNarrow64Uto32( t0 ))); 1033 } 1034 1035 /* Simulate irops Iop_MullOdd*, since we don't have them */ 1036 #define MK_Iop_MullOdd8Ux16( expr_vA, expr_vB ) \ 1037 binop(Iop_MullEven8Ux16, \ 1038 binop(Iop_ShrV128, expr_vA, mkU8(8)), \ 1039 binop(Iop_ShrV128, expr_vB, mkU8(8))) 1040 1041 #define MK_Iop_MullOdd8Sx16( expr_vA, expr_vB ) \ 1042 binop(Iop_MullEven8Sx16, \ 1043 binop(Iop_ShrV128, expr_vA, mkU8(8)), \ 1044 binop(Iop_ShrV128, expr_vB, mkU8(8))) 1045 1046 #define MK_Iop_MullOdd16Ux8( expr_vA, expr_vB ) \ 1047 binop(Iop_MullEven16Ux8, \ 1048 binop(Iop_ShrV128, expr_vA, mkU8(16)), \ 1049 binop(Iop_ShrV128, expr_vB, mkU8(16))) 1050 1051 #define MK_Iop_MullOdd32Ux4( expr_vA, expr_vB ) \ 1052 binop(Iop_MullEven32Ux4, \ 1053 binop(Iop_ShrV128, expr_vA, mkU8(32)), \ 1054 binop(Iop_ShrV128, expr_vB, mkU8(32))) 1055 1056 #define MK_Iop_MullOdd16Sx8( expr_vA, expr_vB ) \ 1057 binop(Iop_MullEven16Sx8, \ 1058 binop(Iop_ShrV128, expr_vA, mkU8(16)), \ 1059 binop(Iop_ShrV128, expr_vB, mkU8(16))) 1060 1061 #define MK_Iop_MullOdd32Sx4( expr_vA, expr_vB ) \ 1062 binop(Iop_MullEven32Sx4, \ 1063 binop(Iop_ShrV128, expr_vA, mkU8(32)), \ 1064 binop(Iop_ShrV128, expr_vB, mkU8(32))) 1065 1066 1067 static IRExpr* /* :: Ity_I64 */ mk64lo32Sto64 ( IRExpr* src ) 1068 { 1069 vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64); 1070 return unop(Iop_32Sto64, unop(Iop_64to32, src)); 1071 } 1072 1073 static IRExpr* /* :: Ity_I64 */ mk64lo32Uto64 ( IRExpr* src ) 1074 { 1075 vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64); 1076 return unop(Iop_32Uto64, unop(Iop_64to32, src)); 1077 } 1078 1079 static IROp mkSzOp ( IRType ty, IROp op8 ) 1080 { 1081 Int adj; 1082 vassert(ty == Ity_I8 || ty == Ity_I16 || 1083 ty == Ity_I32 || ty == Ity_I64); 1084 vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 || 1085 op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 || 1086 op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 || 1087 op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || 1088 op8 == Iop_Not8 ); 1089 adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : (ty==Ity_I32 ? 2 : 3)); 1090 return adj + op8; 1091 } 1092 1093 /* Make sure we get valid 32 and 64bit addresses */ 1094 static Addr64 mkSzAddr ( IRType ty, Addr64 addr ) 1095 { 1096 vassert(ty == Ity_I32 || ty == Ity_I64); 1097 return ( ty == Ity_I64 ? 1098 (Addr64)addr : 1099 (Addr64)extend_s_32to64( toUInt(addr) ) ); 1100 } 1101 1102 /* sz, ULong -> IRExpr */ 1103 static IRExpr* mkSzImm ( IRType ty, ULong imm64 ) 1104 { 1105 vassert(ty == Ity_I32 || ty == Ity_I64); 1106 return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt)imm64); 1107 } 1108 1109 /* sz, ULong -> IRConst */ 1110 static IRConst* mkSzConst ( IRType ty, ULong imm64 ) 1111 { 1112 vassert(ty == Ity_I32 || ty == Ity_I64); 1113 return ( ty == Ity_I64 ? 1114 IRConst_U64(imm64) : 1115 IRConst_U32((UInt)imm64) ); 1116 } 1117 1118 /* Sign extend imm16 -> IRExpr* */ 1119 static IRExpr* mkSzExtendS16 ( IRType ty, UInt imm16 ) 1120 { 1121 vassert(ty == Ity_I32 || ty == Ity_I64); 1122 return ( ty == Ity_I64 ? 1123 mkU64(extend_s_16to64(imm16)) : 1124 mkU32(extend_s_16to32(imm16)) ); 1125 } 1126 1127 /* Sign extend imm32 -> IRExpr* */ 1128 static IRExpr* mkSzExtendS32 ( IRType ty, UInt imm32 ) 1129 { 1130 vassert(ty == Ity_I32 || ty == Ity_I64); 1131 return ( ty == Ity_I64 ? 1132 mkU64(extend_s_32to64(imm32)) : 1133 mkU32(imm32) ); 1134 } 1135 1136 /* IR narrows I32/I64 -> I8/I16/I32 */ 1137 static IRExpr* mkNarrowTo8 ( IRType ty, IRExpr* src ) 1138 { 1139 vassert(ty == Ity_I32 || ty == Ity_I64); 1140 return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src); 1141 } 1142 1143 static IRExpr* mkNarrowTo16 ( IRType ty, IRExpr* src ) 1144 { 1145 vassert(ty == Ity_I32 || ty == Ity_I64); 1146 return ty == Ity_I64 ? unop(Iop_64to16, src) : unop(Iop_32to16, src); 1147 } 1148 1149 static IRExpr* mkNarrowTo32 ( IRType ty, IRExpr* src ) 1150 { 1151 vassert(ty == Ity_I32 || ty == Ity_I64); 1152 return ty == Ity_I64 ? unop(Iop_64to32, src) : src; 1153 } 1154 1155 /* Signed/Unsigned IR widens I8/I16/I32 -> I32/I64 */ 1156 static IRExpr* mkWidenFrom8 ( IRType ty, IRExpr* src, Bool sined ) 1157 { 1158 IROp op; 1159 vassert(ty == Ity_I32 || ty == Ity_I64); 1160 if (sined) op = (ty==Ity_I32) ? Iop_8Sto32 : Iop_8Sto64; 1161 else op = (ty==Ity_I32) ? Iop_8Uto32 : Iop_8Uto64; 1162 return unop(op, src); 1163 } 1164 1165 static IRExpr* mkWidenFrom16 ( IRType ty, IRExpr* src, Bool sined ) 1166 { 1167 IROp op; 1168 vassert(ty == Ity_I32 || ty == Ity_I64); 1169 if (sined) op = (ty==Ity_I32) ? Iop_16Sto32 : Iop_16Sto64; 1170 else op = (ty==Ity_I32) ? Iop_16Uto32 : Iop_16Uto64; 1171 return unop(op, src); 1172 } 1173 1174 static IRExpr* mkWidenFrom32 ( IRType ty, IRExpr* src, Bool sined ) 1175 { 1176 vassert(ty == Ity_I32 || ty == Ity_I64); 1177 if (ty == Ity_I32) 1178 return src; 1179 return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src); 1180 } 1181 1182 1183 static Int integerGuestRegOffset ( UInt archreg ) 1184 { 1185 vassert(archreg < 32); 1186 1187 // jrs: probably not necessary; only matters if we reference sub-parts 1188 // of the ppc registers, but that isn't the case 1189 // later: this might affect Altivec though? 1190 1191 switch (archreg) { 1192 case 0: return offsetofPPCGuestState(guest_GPR0); 1193 case 1: return offsetofPPCGuestState(guest_GPR1); 1194 case 2: return offsetofPPCGuestState(guest_GPR2); 1195 case 3: return offsetofPPCGuestState(guest_GPR3); 1196 case 4: return offsetofPPCGuestState(guest_GPR4); 1197 case 5: return offsetofPPCGuestState(guest_GPR5); 1198 case 6: return offsetofPPCGuestState(guest_GPR6); 1199 case 7: return offsetofPPCGuestState(guest_GPR7); 1200 case 8: return offsetofPPCGuestState(guest_GPR8); 1201 case 9: return offsetofPPCGuestState(guest_GPR9); 1202 case 10: return offsetofPPCGuestState(guest_GPR10); 1203 case 11: return offsetofPPCGuestState(guest_GPR11); 1204 case 12: return offsetofPPCGuestState(guest_GPR12); 1205 case 13: return offsetofPPCGuestState(guest_GPR13); 1206 case 14: return offsetofPPCGuestState(guest_GPR14); 1207 case 15: return offsetofPPCGuestState(guest_GPR15); 1208 case 16: return offsetofPPCGuestState(guest_GPR16); 1209 case 17: return offsetofPPCGuestState(guest_GPR17); 1210 case 18: return offsetofPPCGuestState(guest_GPR18); 1211 case 19: return offsetofPPCGuestState(guest_GPR19); 1212 case 20: return offsetofPPCGuestState(guest_GPR20); 1213 case 21: return offsetofPPCGuestState(guest_GPR21); 1214 case 22: return offsetofPPCGuestState(guest_GPR22); 1215 case 23: return offsetofPPCGuestState(guest_GPR23); 1216 case 24: return offsetofPPCGuestState(guest_GPR24); 1217 case 25: return offsetofPPCGuestState(guest_GPR25); 1218 case 26: return offsetofPPCGuestState(guest_GPR26); 1219 case 27: return offsetofPPCGuestState(guest_GPR27); 1220 case 28: return offsetofPPCGuestState(guest_GPR28); 1221 case 29: return offsetofPPCGuestState(guest_GPR29); 1222 case 30: return offsetofPPCGuestState(guest_GPR30); 1223 case 31: return offsetofPPCGuestState(guest_GPR31); 1224 default: break; 1225 } 1226 vpanic("integerGuestRegOffset(ppc,be)"); /*notreached*/ 1227 } 1228 1229 static IRExpr* getIReg ( UInt archreg ) 1230 { 1231 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1232 vassert(archreg < 32); 1233 return IRExpr_Get( integerGuestRegOffset(archreg), ty ); 1234 } 1235 1236 /* Ditto, but write to a reg instead. */ 1237 static void putIReg ( UInt archreg, IRExpr* e ) 1238 { 1239 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1240 vassert(archreg < 32); 1241 vassert(typeOfIRExpr(irsb->tyenv, e) == ty ); 1242 stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) ); 1243 } 1244 1245 1246 /* Floating point egisters are mapped to VSX registers[0..31]. */ 1247 static Int floatGuestRegOffset ( UInt archreg ) 1248 { 1249 vassert(archreg < 32); 1250 1251 if (host_endness == VexEndnessLE) { 1252 switch (archreg) { 1253 case 0: return offsetofPPCGuestState(guest_VSR0) + 8; 1254 case 1: return offsetofPPCGuestState(guest_VSR1) + 8; 1255 case 2: return offsetofPPCGuestState(guest_VSR2) + 8; 1256 case 3: return offsetofPPCGuestState(guest_VSR3) + 8; 1257 case 4: return offsetofPPCGuestState(guest_VSR4) + 8; 1258 case 5: return offsetofPPCGuestState(guest_VSR5) + 8; 1259 case 6: return offsetofPPCGuestState(guest_VSR6) + 8; 1260 case 7: return offsetofPPCGuestState(guest_VSR7) + 8; 1261 case 8: return offsetofPPCGuestState(guest_VSR8) + 8; 1262 case 9: return offsetofPPCGuestState(guest_VSR9) + 8; 1263 case 10: return offsetofPPCGuestState(guest_VSR10) + 8; 1264 case 11: return offsetofPPCGuestState(guest_VSR11) + 8; 1265 case 12: return offsetofPPCGuestState(guest_VSR12) + 8; 1266 case 13: return offsetofPPCGuestState(guest_VSR13) + 8; 1267 case 14: return offsetofPPCGuestState(guest_VSR14) + 8; 1268 case 15: return offsetofPPCGuestState(guest_VSR15) + 8; 1269 case 16: return offsetofPPCGuestState(guest_VSR16) + 8; 1270 case 17: return offsetofPPCGuestState(guest_VSR17) + 8; 1271 case 18: return offsetofPPCGuestState(guest_VSR18) + 8; 1272 case 19: return offsetofPPCGuestState(guest_VSR19) + 8; 1273 case 20: return offsetofPPCGuestState(guest_VSR20) + 8; 1274 case 21: return offsetofPPCGuestState(guest_VSR21) + 8; 1275 case 22: return offsetofPPCGuestState(guest_VSR22) + 8; 1276 case 23: return offsetofPPCGuestState(guest_VSR23) + 8; 1277 case 24: return offsetofPPCGuestState(guest_VSR24) + 8; 1278 case 25: return offsetofPPCGuestState(guest_VSR25) + 8; 1279 case 26: return offsetofPPCGuestState(guest_VSR26) + 8; 1280 case 27: return offsetofPPCGuestState(guest_VSR27) + 8; 1281 case 28: return offsetofPPCGuestState(guest_VSR28) + 8; 1282 case 29: return offsetofPPCGuestState(guest_VSR29) + 8; 1283 case 30: return offsetofPPCGuestState(guest_VSR30) + 8; 1284 case 31: return offsetofPPCGuestState(guest_VSR31) + 8; 1285 default: break; 1286 } 1287 } else { 1288 switch (archreg) { 1289 case 0: return offsetofPPCGuestState(guest_VSR0); 1290 case 1: return offsetofPPCGuestState(guest_VSR1); 1291 case 2: return offsetofPPCGuestState(guest_VSR2); 1292 case 3: return offsetofPPCGuestState(guest_VSR3); 1293 case 4: return offsetofPPCGuestState(guest_VSR4); 1294 case 5: return offsetofPPCGuestState(guest_VSR5); 1295 case 6: return offsetofPPCGuestState(guest_VSR6); 1296 case 7: return offsetofPPCGuestState(guest_VSR7); 1297 case 8: return offsetofPPCGuestState(guest_VSR8); 1298 case 9: return offsetofPPCGuestState(guest_VSR9); 1299 case 10: return offsetofPPCGuestState(guest_VSR10); 1300 case 11: return offsetofPPCGuestState(guest_VSR11); 1301 case 12: return offsetofPPCGuestState(guest_VSR12); 1302 case 13: return offsetofPPCGuestState(guest_VSR13); 1303 case 14: return offsetofPPCGuestState(guest_VSR14); 1304 case 15: return offsetofPPCGuestState(guest_VSR15); 1305 case 16: return offsetofPPCGuestState(guest_VSR16); 1306 case 17: return offsetofPPCGuestState(guest_VSR17); 1307 case 18: return offsetofPPCGuestState(guest_VSR18); 1308 case 19: return offsetofPPCGuestState(guest_VSR19); 1309 case 20: return offsetofPPCGuestState(guest_VSR20); 1310 case 21: return offsetofPPCGuestState(guest_VSR21); 1311 case 22: return offsetofPPCGuestState(guest_VSR22); 1312 case 23: return offsetofPPCGuestState(guest_VSR23); 1313 case 24: return offsetofPPCGuestState(guest_VSR24); 1314 case 25: return offsetofPPCGuestState(guest_VSR25); 1315 case 26: return offsetofPPCGuestState(guest_VSR26); 1316 case 27: return offsetofPPCGuestState(guest_VSR27); 1317 case 28: return offsetofPPCGuestState(guest_VSR28); 1318 case 29: return offsetofPPCGuestState(guest_VSR29); 1319 case 30: return offsetofPPCGuestState(guest_VSR30); 1320 case 31: return offsetofPPCGuestState(guest_VSR31); 1321 default: break; 1322 } 1323 } 1324 vpanic("floatGuestRegOffset(ppc)"); /*notreached*/ 1325 } 1326 1327 static IRExpr* getFReg ( UInt archreg ) 1328 { 1329 vassert(archreg < 32); 1330 return IRExpr_Get( floatGuestRegOffset(archreg), Ity_F64 ); 1331 } 1332 1333 /* Ditto, but write to a reg instead. */ 1334 static void putFReg ( UInt archreg, IRExpr* e ) 1335 { 1336 vassert(archreg < 32); 1337 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64); 1338 stmt( IRStmt_Put(floatGuestRegOffset(archreg), e) ); 1339 } 1340 1341 /* get Decimal float value. Note, they share floating point register file. */ 1342 static IRExpr* getDReg(UInt archreg) { 1343 IRExpr *e; 1344 vassert( archreg < 32 ); 1345 e = IRExpr_Get( floatGuestRegOffset( archreg ), Ity_D64 ); 1346 return e; 1347 } 1348 static IRExpr* getDReg32(UInt archreg) { 1349 IRExpr *e; 1350 vassert( archreg < 32 ); 1351 e = IRExpr_Get( floatGuestRegOffset( archreg ), Ity_D32 ); 1352 return e; 1353 } 1354 1355 /* Read a floating point register pair and combine their contents into a 1356 128-bit value */ 1357 static IRExpr *getDReg_pair(UInt archreg) { 1358 IRExpr *high = getDReg( archreg ); 1359 IRExpr *low = getDReg( archreg + 1 ); 1360 1361 return binop( Iop_D64HLtoD128, high, low ); 1362 } 1363 1364 /* Ditto, but write to a reg instead. */ 1365 static void putDReg32(UInt archreg, IRExpr* e) { 1366 vassert( archreg < 32 ); 1367 vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_D32 ); 1368 stmt( IRStmt_Put( floatGuestRegOffset( archreg ), e ) ); 1369 } 1370 1371 static void putDReg(UInt archreg, IRExpr* e) { 1372 vassert( archreg < 32 ); 1373 vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_D64 ); 1374 stmt( IRStmt_Put( floatGuestRegOffset( archreg ), e ) ); 1375 } 1376 1377 /* Write a 128-bit floating point value into a register pair. */ 1378 static void putDReg_pair(UInt archreg, IRExpr *e) { 1379 IRTemp low = newTemp( Ity_D64 ); 1380 IRTemp high = newTemp( Ity_D64 ); 1381 1382 vassert( archreg < 32 ); 1383 vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_D128 ); 1384 1385 assign( low, unop( Iop_D128LOtoD64, e ) ); 1386 assign( high, unop( Iop_D128HItoD64, e ) ); 1387 1388 stmt( IRStmt_Put( floatGuestRegOffset( archreg ), mkexpr( high ) ) ); 1389 stmt( IRStmt_Put( floatGuestRegOffset( archreg + 1 ), mkexpr( low ) ) ); 1390 } 1391 1392 static Int vsxGuestRegOffset ( UInt archreg ) 1393 { 1394 vassert(archreg < 64); 1395 switch (archreg) { 1396 case 0: return offsetofPPCGuestState(guest_VSR0); 1397 case 1: return offsetofPPCGuestState(guest_VSR1); 1398 case 2: return offsetofPPCGuestState(guest_VSR2); 1399 case 3: return offsetofPPCGuestState(guest_VSR3); 1400 case 4: return offsetofPPCGuestState(guest_VSR4); 1401 case 5: return offsetofPPCGuestState(guest_VSR5); 1402 case 6: return offsetofPPCGuestState(guest_VSR6); 1403 case 7: return offsetofPPCGuestState(guest_VSR7); 1404 case 8: return offsetofPPCGuestState(guest_VSR8); 1405 case 9: return offsetofPPCGuestState(guest_VSR9); 1406 case 10: return offsetofPPCGuestState(guest_VSR10); 1407 case 11: return offsetofPPCGuestState(guest_VSR11); 1408 case 12: return offsetofPPCGuestState(guest_VSR12); 1409 case 13: return offsetofPPCGuestState(guest_VSR13); 1410 case 14: return offsetofPPCGuestState(guest_VSR14); 1411 case 15: return offsetofPPCGuestState(guest_VSR15); 1412 case 16: return offsetofPPCGuestState(guest_VSR16); 1413 case 17: return offsetofPPCGuestState(guest_VSR17); 1414 case 18: return offsetofPPCGuestState(guest_VSR18); 1415 case 19: return offsetofPPCGuestState(guest_VSR19); 1416 case 20: return offsetofPPCGuestState(guest_VSR20); 1417 case 21: return offsetofPPCGuestState(guest_VSR21); 1418 case 22: return offsetofPPCGuestState(guest_VSR22); 1419 case 23: return offsetofPPCGuestState(guest_VSR23); 1420 case 24: return offsetofPPCGuestState(guest_VSR24); 1421 case 25: return offsetofPPCGuestState(guest_VSR25); 1422 case 26: return offsetofPPCGuestState(guest_VSR26); 1423 case 27: return offsetofPPCGuestState(guest_VSR27); 1424 case 28: return offsetofPPCGuestState(guest_VSR28); 1425 case 29: return offsetofPPCGuestState(guest_VSR29); 1426 case 30: return offsetofPPCGuestState(guest_VSR30); 1427 case 31: return offsetofPPCGuestState(guest_VSR31); 1428 case 32: return offsetofPPCGuestState(guest_VSR32); 1429 case 33: return offsetofPPCGuestState(guest_VSR33); 1430 case 34: return offsetofPPCGuestState(guest_VSR34); 1431 case 35: return offsetofPPCGuestState(guest_VSR35); 1432 case 36: return offsetofPPCGuestState(guest_VSR36); 1433 case 37: return offsetofPPCGuestState(guest_VSR37); 1434 case 38: return offsetofPPCGuestState(guest_VSR38); 1435 case 39: return offsetofPPCGuestState(guest_VSR39); 1436 case 40: return offsetofPPCGuestState(guest_VSR40); 1437 case 41: return offsetofPPCGuestState(guest_VSR41); 1438 case 42: return offsetofPPCGuestState(guest_VSR42); 1439 case 43: return offsetofPPCGuestState(guest_VSR43); 1440 case 44: return offsetofPPCGuestState(guest_VSR44); 1441 case 45: return offsetofPPCGuestState(guest_VSR45); 1442 case 46: return offsetofPPCGuestState(guest_VSR46); 1443 case 47: return offsetofPPCGuestState(guest_VSR47); 1444 case 48: return offsetofPPCGuestState(guest_VSR48); 1445 case 49: return offsetofPPCGuestState(guest_VSR49); 1446 case 50: return offsetofPPCGuestState(guest_VSR50); 1447 case 51: return offsetofPPCGuestState(guest_VSR51); 1448 case 52: return offsetofPPCGuestState(guest_VSR52); 1449 case 53: return offsetofPPCGuestState(guest_VSR53); 1450 case 54: return offsetofPPCGuestState(guest_VSR54); 1451 case 55: return offsetofPPCGuestState(guest_VSR55); 1452 case 56: return offsetofPPCGuestState(guest_VSR56); 1453 case 57: return offsetofPPCGuestState(guest_VSR57); 1454 case 58: return offsetofPPCGuestState(guest_VSR58); 1455 case 59: return offsetofPPCGuestState(guest_VSR59); 1456 case 60: return offsetofPPCGuestState(guest_VSR60); 1457 case 61: return offsetofPPCGuestState(guest_VSR61); 1458 case 62: return offsetofPPCGuestState(guest_VSR62); 1459 case 63: return offsetofPPCGuestState(guest_VSR63); 1460 default: break; 1461 } 1462 vpanic("vsxGuestRegOffset(ppc)"); /*notreached*/ 1463 } 1464 1465 /* Vector registers are mapped to VSX registers[32..63]. */ 1466 static Int vectorGuestRegOffset ( UInt archreg ) 1467 { 1468 vassert(archreg < 32); 1469 1470 switch (archreg) { 1471 case 0: return offsetofPPCGuestState(guest_VSR32); 1472 case 1: return offsetofPPCGuestState(guest_VSR33); 1473 case 2: return offsetofPPCGuestState(guest_VSR34); 1474 case 3: return offsetofPPCGuestState(guest_VSR35); 1475 case 4: return offsetofPPCGuestState(guest_VSR36); 1476 case 5: return offsetofPPCGuestState(guest_VSR37); 1477 case 6: return offsetofPPCGuestState(guest_VSR38); 1478 case 7: return offsetofPPCGuestState(guest_VSR39); 1479 case 8: return offsetofPPCGuestState(guest_VSR40); 1480 case 9: return offsetofPPCGuestState(guest_VSR41); 1481 case 10: return offsetofPPCGuestState(guest_VSR42); 1482 case 11: return offsetofPPCGuestState(guest_VSR43); 1483 case 12: return offsetofPPCGuestState(guest_VSR44); 1484 case 13: return offsetofPPCGuestState(guest_VSR45); 1485 case 14: return offsetofPPCGuestState(guest_VSR46); 1486 case 15: return offsetofPPCGuestState(guest_VSR47); 1487 case 16: return offsetofPPCGuestState(guest_VSR48); 1488 case 17: return offsetofPPCGuestState(guest_VSR49); 1489 case 18: return offsetofPPCGuestState(guest_VSR50); 1490 case 19: return offsetofPPCGuestState(guest_VSR51); 1491 case 20: return offsetofPPCGuestState(guest_VSR52); 1492 case 21: return offsetofPPCGuestState(guest_VSR53); 1493 case 22: return offsetofPPCGuestState(guest_VSR54); 1494 case 23: return offsetofPPCGuestState(guest_VSR55); 1495 case 24: return offsetofPPCGuestState(guest_VSR56); 1496 case 25: return offsetofPPCGuestState(guest_VSR57); 1497 case 26: return offsetofPPCGuestState(guest_VSR58); 1498 case 27: return offsetofPPCGuestState(guest_VSR59); 1499 case 28: return offsetofPPCGuestState(guest_VSR60); 1500 case 29: return offsetofPPCGuestState(guest_VSR61); 1501 case 30: return offsetofPPCGuestState(guest_VSR62); 1502 case 31: return offsetofPPCGuestState(guest_VSR63); 1503 default: break; 1504 } 1505 vpanic("vextorGuestRegOffset(ppc)"); /*notreached*/ 1506 } 1507 1508 static IRExpr* getVReg ( UInt archreg ) 1509 { 1510 vassert(archreg < 32); 1511 return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_V128 ); 1512 } 1513 1514 /* Get contents of 128-bit reg guest register */ 1515 static IRExpr* getF128Reg ( UInt archreg ) 1516 { 1517 vassert(archreg < 64); 1518 return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_F128 ); 1519 } 1520 1521 /* Ditto, but write to a reg instead. */ 1522 static void putF128Reg ( UInt archreg, IRExpr* e ) 1523 { 1524 vassert(archreg < 64); 1525 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F128); 1526 stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) ); 1527 } 1528 1529 /* Ditto, but write to a reg instead. */ 1530 static void putVReg ( UInt archreg, IRExpr* e ) 1531 { 1532 vassert(archreg < 32); 1533 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128); 1534 stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) ); 1535 } 1536 1537 /* Get contents of VSX guest register */ 1538 static IRExpr* getVSReg ( UInt archreg ) 1539 { 1540 vassert(archreg < 64); 1541 return IRExpr_Get( vsxGuestRegOffset(archreg), Ity_V128 ); 1542 } 1543 1544 /* Ditto, but write to a VSX reg instead. */ 1545 static void putVSReg ( UInt archreg, IRExpr* e ) 1546 { 1547 vassert(archreg < 64); 1548 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128); 1549 stmt( IRStmt_Put(vsxGuestRegOffset(archreg), e) ); 1550 } 1551 1552 1553 static Int guestCR321offset ( UInt cr ) 1554 { 1555 switch (cr) { 1556 case 0: return offsetofPPCGuestState(guest_CR0_321 ); 1557 case 1: return offsetofPPCGuestState(guest_CR1_321 ); 1558 case 2: return offsetofPPCGuestState(guest_CR2_321 ); 1559 case 3: return offsetofPPCGuestState(guest_CR3_321 ); 1560 case 4: return offsetofPPCGuestState(guest_CR4_321 ); 1561 case 5: return offsetofPPCGuestState(guest_CR5_321 ); 1562 case 6: return offsetofPPCGuestState(guest_CR6_321 ); 1563 case 7: return offsetofPPCGuestState(guest_CR7_321 ); 1564 default: vpanic("guestCR321offset(ppc)"); 1565 } 1566 } 1567 1568 static Int guestCR0offset ( UInt cr ) 1569 { 1570 switch (cr) { 1571 case 0: return offsetofPPCGuestState(guest_CR0_0 ); 1572 case 1: return offsetofPPCGuestState(guest_CR1_0 ); 1573 case 2: return offsetofPPCGuestState(guest_CR2_0 ); 1574 case 3: return offsetofPPCGuestState(guest_CR3_0 ); 1575 case 4: return offsetofPPCGuestState(guest_CR4_0 ); 1576 case 5: return offsetofPPCGuestState(guest_CR5_0 ); 1577 case 6: return offsetofPPCGuestState(guest_CR6_0 ); 1578 case 7: return offsetofPPCGuestState(guest_CR7_0 ); 1579 default: vpanic("guestCR3offset(ppc)"); 1580 } 1581 } 1582 1583 typedef enum { 1584 _placeholder0, 1585 _placeholder1, 1586 _placeholder2, 1587 BYTE, 1588 HWORD, 1589 WORD, 1590 DWORD 1591 } _popcount_data_type; 1592 1593 /* Generate an IR sequence to do a popcount operation on the supplied 1594 IRTemp, and return a new IRTemp holding the result. 'ty' may be 1595 Ity_I32 or Ity_I64 only. */ 1596 static IRTemp gen_POPCOUNT ( IRType ty, IRTemp src, _popcount_data_type data_type ) 1597 { 1598 /* Do count across 2^data_type bits, 1599 byte: data_type = 3 1600 half word: data_type = 4 1601 word: data_type = 5 1602 double word: data_type = 6 (not supported for 32-bit type) 1603 */ 1604 Int shift[6]; 1605 _popcount_data_type idx, i; 1606 IRTemp mask[6]; 1607 IRTemp old = IRTemp_INVALID; 1608 IRTemp nyu = IRTemp_INVALID; 1609 1610 vassert(ty == Ity_I64 || ty == Ity_I32); 1611 1612 if (ty == Ity_I32) { 1613 1614 for (idx = 0; idx < WORD; idx++) { 1615 mask[idx] = newTemp(ty); 1616 shift[idx] = 1 << idx; 1617 } 1618 assign(mask[0], mkU32(0x55555555)); 1619 assign(mask[1], mkU32(0x33333333)); 1620 assign(mask[2], mkU32(0x0F0F0F0F)); 1621 assign(mask[3], mkU32(0x00FF00FF)); 1622 assign(mask[4], mkU32(0x0000FFFF)); 1623 old = src; 1624 for (i = 0; i < data_type; i++) { 1625 nyu = newTemp(ty); 1626 assign(nyu, 1627 binop(Iop_Add32, 1628 binop(Iop_And32, 1629 mkexpr(old), 1630 mkexpr(mask[i])), 1631 binop(Iop_And32, 1632 binop(Iop_Shr32, mkexpr(old), mkU8(shift[i])), 1633 mkexpr(mask[i])))); 1634 old = nyu; 1635 } 1636 return nyu; 1637 } 1638 1639 // else, ty == Ity_I64 1640 vassert(mode64); 1641 1642 for (i = 0; i < DWORD; i++) { 1643 mask[i] = newTemp( Ity_I64 ); 1644 shift[i] = 1 << i; 1645 } 1646 assign( mask[0], mkU64( 0x5555555555555555ULL ) ); 1647 assign( mask[1], mkU64( 0x3333333333333333ULL ) ); 1648 assign( mask[2], mkU64( 0x0F0F0F0F0F0F0F0FULL ) ); 1649 assign( mask[3], mkU64( 0x00FF00FF00FF00FFULL ) ); 1650 assign( mask[4], mkU64( 0x0000FFFF0000FFFFULL ) ); 1651 assign( mask[5], mkU64( 0x00000000FFFFFFFFULL ) ); 1652 old = src; 1653 for (i = 0; i < data_type; i++) { 1654 nyu = newTemp( Ity_I64 ); 1655 assign( nyu, 1656 binop( Iop_Add64, 1657 binop( Iop_And64, mkexpr( old ), mkexpr( mask[i] ) ), 1658 binop( Iop_And64, 1659 binop( Iop_Shr64, mkexpr( old ), mkU8( shift[i] ) ), 1660 mkexpr( mask[i] ) ) ) ); 1661 old = nyu; 1662 } 1663 return nyu; 1664 } 1665 1666 /* Special purpose population count function for 1667 * vpopcntd in 32-bit mode. 1668 */ 1669 static IRTemp gen_vpopcntd_mode32 ( IRTemp src1, IRTemp src2 ) 1670 { 1671 Int i, shift[6]; 1672 IRTemp mask[6]; 1673 IRTemp old = IRTemp_INVALID; 1674 IRTemp nyu1 = IRTemp_INVALID; 1675 IRTemp nyu2 = IRTemp_INVALID; 1676 IRTemp retval = newTemp(Ity_I64); 1677 1678 vassert(!mode64); 1679 1680 for (i = 0; i < WORD; i++) { 1681 mask[i] = newTemp(Ity_I32); 1682 shift[i] = 1 << i; 1683 } 1684 assign(mask[0], mkU32(0x55555555)); 1685 assign(mask[1], mkU32(0x33333333)); 1686 assign(mask[2], mkU32(0x0F0F0F0F)); 1687 assign(mask[3], mkU32(0x00FF00FF)); 1688 assign(mask[4], mkU32(0x0000FFFF)); 1689 old = src1; 1690 for (i = 0; i < WORD; i++) { 1691 nyu1 = newTemp(Ity_I32); 1692 assign(nyu1, 1693 binop(Iop_Add32, 1694 binop(Iop_And32, 1695 mkexpr(old), 1696 mkexpr(mask[i])), 1697 binop(Iop_And32, 1698 binop(Iop_Shr32, mkexpr(old), mkU8(shift[i])), 1699 mkexpr(mask[i])))); 1700 old = nyu1; 1701 } 1702 1703 old = src2; 1704 for (i = 0; i < WORD; i++) { 1705 nyu2 = newTemp(Ity_I32); 1706 assign(nyu2, 1707 binop(Iop_Add32, 1708 binop(Iop_And32, 1709 mkexpr(old), 1710 mkexpr(mask[i])), 1711 binop(Iop_And32, 1712 binop(Iop_Shr32, mkexpr(old), mkU8(shift[i])), 1713 mkexpr(mask[i])))); 1714 old = nyu2; 1715 } 1716 assign(retval, unop(Iop_32Uto64, binop(Iop_Add32, mkexpr(nyu1), mkexpr(nyu2)))); 1717 return retval; 1718 } 1719 1720 1721 // ROTL(src32/64, rot_amt5/6) 1722 static IRExpr* /* :: Ity_I32/64 */ ROTL ( IRExpr* src, 1723 IRExpr* rot_amt ) 1724 { 1725 IRExpr *mask, *rot; 1726 vassert(typeOfIRExpr(irsb->tyenv,rot_amt) == Ity_I8); 1727 1728 if (typeOfIRExpr(irsb->tyenv,src) == Ity_I64) { 1729 // rot = (src << rot_amt) | (src >> (64-rot_amt)) 1730 mask = binop(Iop_And8, rot_amt, mkU8(63)); 1731 rot = binop(Iop_Or64, 1732 binop(Iop_Shl64, src, mask), 1733 binop(Iop_Shr64, src, binop(Iop_Sub8, mkU8(64), mask))); 1734 } else { 1735 // rot = (src << rot_amt) | (src >> (32-rot_amt)) 1736 mask = binop(Iop_And8, rot_amt, mkU8(31)); 1737 rot = binop(Iop_Or32, 1738 binop(Iop_Shl32, src, mask), 1739 binop(Iop_Shr32, src, binop(Iop_Sub8, mkU8(32), mask))); 1740 } 1741 /* Note: the ITE not merely an optimisation; it's needed 1742 because otherwise the Shr is a shift by the word size when 1743 mask denotes zero. For rotates by immediates, a lot of 1744 this junk gets folded out. */ 1745 return IRExpr_ITE( binop(Iop_CmpNE8, mask, mkU8(0)), 1746 /* non-zero rotate */ rot, 1747 /* zero rotate */ src); 1748 } 1749 1750 /* Standard effective address calc: (rA + rB) */ 1751 static IRExpr* ea_rA_idxd ( UInt rA, UInt rB ) 1752 { 1753 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1754 vassert(rA < 32); 1755 vassert(rB < 32); 1756 return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), getIReg(rB)); 1757 } 1758 1759 /* Standard effective address calc: (rA + simm) */ 1760 static IRExpr* ea_rA_simm ( UInt rA, UInt simm16 ) 1761 { 1762 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1763 vassert(rA < 32); 1764 return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), 1765 mkSzExtendS16(ty, simm16)); 1766 } 1767 1768 /* Standard effective address calc: (rA|0) */ 1769 static IRExpr* ea_rAor0 ( UInt rA ) 1770 { 1771 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1772 vassert(rA < 32); 1773 if (rA == 0) { 1774 return mkSzImm(ty, 0); 1775 } else { 1776 return getIReg(rA); 1777 } 1778 } 1779 1780 /* Standard effective address calc: (rA|0) + rB */ 1781 static IRExpr* ea_rAor0_idxd ( UInt rA, UInt rB ) 1782 { 1783 vassert(rA < 32); 1784 vassert(rB < 32); 1785 return (rA == 0) ? getIReg(rB) : ea_rA_idxd( rA, rB ); 1786 } 1787 1788 /* Standard effective address calc: (rA|0) + simm16 */ 1789 static IRExpr* ea_rAor0_simm ( UInt rA, UInt simm16 ) 1790 { 1791 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1792 vassert(rA < 32); 1793 if (rA == 0) { 1794 return mkSzExtendS16(ty, simm16); 1795 } else { 1796 return ea_rA_simm( rA, simm16 ); 1797 } 1798 } 1799 1800 1801 /* Align effective address */ 1802 static IRExpr* addr_align( IRExpr* addr, UChar align ) 1803 { 1804 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1805 ULong mask; 1806 switch (align) { 1807 case 1: return addr; // byte aligned 1808 case 2: mask = ~0ULL << 1; break; // half-word aligned 1809 case 4: mask = ~0ULL << 2; break; // word aligned 1810 case 16: mask = ~0ULL << 4; break; // quad-word aligned 1811 default: 1812 vex_printf("addr_align: align = %u\n", align); 1813 vpanic("addr_align(ppc)"); 1814 } 1815 1816 vassert(typeOfIRExpr(irsb->tyenv,addr) == ty); 1817 return binop( mkSzOp(ty, Iop_And8), addr, mkSzImm(ty, mask) ); 1818 } 1819 1820 1821 /* Exit the trace if ADDR (intended to be a guest memory address) is 1822 not ALIGN-aligned, generating a request for a SIGBUS followed by a 1823 restart of the current insn. */ 1824 static void gen_SIGBUS_if_misaligned ( IRTemp addr, UChar align ) 1825 { 1826 vassert(align == 2 || align == 4 || align == 8 || align == 16); 1827 if (mode64) { 1828 vassert(typeOfIRTemp(irsb->tyenv, addr) == Ity_I64); 1829 stmt( 1830 IRStmt_Exit( 1831 binop(Iop_CmpNE64, 1832 binop(Iop_And64, mkexpr(addr), mkU64(align-1)), 1833 mkU64(0)), 1834 Ijk_SigBUS, 1835 IRConst_U64( guest_CIA_curr_instr ), OFFB_CIA 1836 ) 1837 ); 1838 } else { 1839 vassert(typeOfIRTemp(irsb->tyenv, addr) == Ity_I32); 1840 stmt( 1841 IRStmt_Exit( 1842 binop(Iop_CmpNE32, 1843 binop(Iop_And32, mkexpr(addr), mkU32(align-1)), 1844 mkU32(0)), 1845 Ijk_SigBUS, 1846 IRConst_U32( guest_CIA_curr_instr ), OFFB_CIA 1847 ) 1848 ); 1849 } 1850 } 1851 1852 1853 /* Generate AbiHints which mark points at which the ELF or PowerOpen 1854 ABIs say that the stack red zone (viz, -N(r1) .. -1(r1), for some 1855 N) becomes undefined. That is at function calls and returns. ELF 1856 ppc32 doesn't have this "feature" (how fortunate for it). nia is 1857 the address of the next instruction to be executed. 1858 */ 1859 static void make_redzone_AbiHint ( const VexAbiInfo* vbi, 1860 IRTemp nia, const HChar* who ) 1861 { 1862 Int szB = vbi->guest_stack_redzone_size; 1863 if (0) vex_printf("AbiHint: %s\n", who); 1864 vassert(szB >= 0); 1865 if (szB > 0) { 1866 if (mode64) { 1867 vassert(typeOfIRTemp(irsb->tyenv, nia) == Ity_I64); 1868 stmt( IRStmt_AbiHint( 1869 binop(Iop_Sub64, getIReg(1), mkU64(szB)), 1870 szB, 1871 mkexpr(nia) 1872 )); 1873 } else { 1874 vassert(typeOfIRTemp(irsb->tyenv, nia) == Ity_I32); 1875 stmt( IRStmt_AbiHint( 1876 binop(Iop_Sub32, getIReg(1), mkU32(szB)), 1877 szB, 1878 mkexpr(nia) 1879 )); 1880 } 1881 } 1882 } 1883 1884 1885 /*------------------------------------------------------------*/ 1886 /*--- Helpers for condition codes. ---*/ 1887 /*------------------------------------------------------------*/ 1888 1889 /* Condition register layout. 1890 1891 In the hardware, CR is laid out like this. The leftmost end is the 1892 most significant bit in the register; however the IBM documentation 1893 numbers the bits backwards for some reason. 1894 1895 CR0 CR1 .......... CR6 CR7 1896 0 .. 3 ....................... 28 .. 31 (IBM bit numbering) 1897 31 28 3 0 (normal bit numbering) 1898 1899 Each CR field is 4 bits: [<,>,==,SO] 1900 1901 Hence in IBM's notation, BI=0 is CR7[SO], BI=1 is CR7[==], etc. 1902 1903 Indexing from BI to guest state: 1904 1905 let n = BI / 4 1906 off = BI % 4 1907 this references CR n: 1908 1909 off==0 -> guest_CRn_321 >> 3 1910 off==1 -> guest_CRn_321 >> 2 1911 off==2 -> guest_CRn_321 >> 1 1912 off==3 -> guest_CRn_SO 1913 1914 Bear in mind the only significant bit in guest_CRn_SO is bit 0 1915 (normal notation) and in guest_CRn_321 the significant bits are 1916 3, 2 and 1 (normal notation). 1917 */ 1918 1919 static void putCR321 ( UInt cr, IRExpr* e ) 1920 { 1921 vassert(cr < 8); 1922 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1923 stmt( IRStmt_Put(guestCR321offset(cr), e) ); 1924 } 1925 1926 static void putCR0 ( UInt cr, IRExpr* e ) 1927 { 1928 vassert(cr < 8); 1929 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1930 stmt( IRStmt_Put(guestCR0offset(cr), e) ); 1931 } 1932 1933 static void putC ( IRExpr* e ) 1934 { 1935 /* The assumption is that the value of the Floating-Point Result 1936 * Class Descriptor bit (C) is passed in the lower four bits of a 1937 * 32 bit value. 1938 * 1939 * Note, the C and FPCC bits which are fields in the FPSCR 1940 * register are stored in their own memory location of 1941 * memory. The FPCC bits are in the lower 4 bits. The C bit needs 1942 * to be shifted to bit 4 in the memory location that holds C and FPCC. 1943 * Note not all of the FPSCR register bits are supported. We are 1944 * only writing C bit. 1945 */ 1946 IRExpr* tmp; 1947 1948 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32); 1949 1950 /* Get the FPCC bit field */ 1951 tmp = binop( Iop_And32, 1952 mkU32( 0xF ), 1953 unop( Iop_8Uto32, IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ) ); 1954 1955 stmt( IRStmt_Put( OFFB_C_FPCC, 1956 unop( Iop_32to8, 1957 binop( Iop_Or32, tmp, 1958 binop( Iop_Shl32, 1959 binop( Iop_And32, mkU32( 0x1 ), e ), 1960 mkU8( 4 ) ) ) ) ) ); 1961 } 1962 1963 static IRExpr* /* :: Ity_I8 */ getCR0 ( UInt cr ) 1964 { 1965 vassert(cr < 8); 1966 return IRExpr_Get(guestCR0offset(cr), Ity_I8); 1967 } 1968 1969 static IRExpr* /* :: Ity_I8 */ getCR321 ( UInt cr ) 1970 { 1971 vassert(cr < 8); 1972 return IRExpr_Get(guestCR321offset(cr), Ity_I8); 1973 } 1974 1975 /* Fetch the specified CR bit (as per IBM/hardware notation) and 1976 return it at the bottom of an I32; the top 31 bits are guaranteed 1977 to be zero. */ 1978 static IRExpr* /* :: Ity_I32 */ getCRbit ( UInt bi ) 1979 { 1980 UInt n = bi / 4; 1981 UInt off = bi % 4; 1982 vassert(bi < 32); 1983 if (off == 3) { 1984 /* Fetch the SO bit for this CR field */ 1985 /* Note: And32 is redundant paranoia iff guest state only has 0 1986 or 1 in that slot. */ 1987 return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1)); 1988 } else { 1989 /* Fetch the <, > or == bit for this CR field */ 1990 return binop( Iop_And32, 1991 binop( Iop_Shr32, 1992 unop(Iop_8Uto32, getCR321(n)), 1993 mkU8(toUChar(3-off)) ), 1994 mkU32(1) ); 1995 } 1996 } 1997 1998 /* Dually, write the least significant bit of BIT to the specified CR 1999 bit. Indexing as per getCRbit. */ 2000 static void putCRbit ( UInt bi, IRExpr* bit ) 2001 { 2002 UInt n, off; 2003 IRExpr* safe; 2004 vassert(typeOfIRExpr(irsb->tyenv,bit) == Ity_I32); 2005 safe = binop(Iop_And32, bit, mkU32(1)); 2006 n = bi / 4; 2007 off = bi % 4; 2008 vassert(bi < 32); 2009 if (off == 3) { 2010 /* This is the SO bit for this CR field */ 2011 putCR0(n, unop(Iop_32to8, safe)); 2012 } else { 2013 off = 3 - off; 2014 vassert(off == 1 || off == 2 || off == 3); 2015 putCR321( 2016 n, 2017 unop( Iop_32to8, 2018 binop( Iop_Or32, 2019 /* old value with field masked out */ 2020 binop(Iop_And32, unop(Iop_8Uto32, getCR321(n)), 2021 mkU32(~(1 << off))), 2022 /* new value in the right place */ 2023 binop(Iop_Shl32, safe, mkU8(toUChar(off))) 2024 ) 2025 ) 2026 ); 2027 } 2028 } 2029 2030 /* Fetch the specified CR bit (as per IBM/hardware notation) and 2031 return it somewhere in an I32; it does not matter where, but 2032 whichever bit it is, all other bits are guaranteed to be zero. In 2033 other words, the I32-typed expression will be zero if the bit is 2034 zero and nonzero if the bit is 1. Write into *where the index 2035 of where the bit will be. */ 2036 2037 static 2038 IRExpr* /* :: Ity_I32 */ getCRbit_anywhere ( UInt bi, Int* where ) 2039 { 2040 UInt n = bi / 4; 2041 UInt off = bi % 4; 2042 vassert(bi < 32); 2043 if (off == 3) { 2044 /* Fetch the SO bit for this CR field */ 2045 /* Note: And32 is redundant paranoia iff guest state only has 0 2046 or 1 in that slot. */ 2047 *where = 0; 2048 return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1)); 2049 } else { 2050 /* Fetch the <, > or == bit for this CR field */ 2051 *where = 3-off; 2052 return binop( Iop_And32, 2053 unop(Iop_8Uto32, getCR321(n)), 2054 mkU32(1 << (3-off)) ); 2055 } 2056 } 2057 2058 /* Set the CR0 flags following an arithmetic operation. 2059 (Condition Register CR0 Field Definition, PPC32 p60) 2060 */ 2061 static IRExpr* getXER_SO ( void ); 2062 static void set_CR0 ( IRExpr* result ) 2063 { 2064 vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_I32 || 2065 typeOfIRExpr(irsb->tyenv,result) == Ity_I64); 2066 if (mode64) { 2067 putCR321( 0, unop(Iop_64to8, 2068 binop(Iop_CmpORD64S, result, mkU64(0))) ); 2069 } else { 2070 putCR321( 0, unop(Iop_32to8, 2071 binop(Iop_CmpORD32S, result, mkU32(0))) ); 2072 } 2073 putCR0( 0, getXER_SO() ); 2074 } 2075 2076 2077 /* Set the CR6 flags following an AltiVec compare operation. 2078 * NOTE: This also works for VSX single-precision compares. 2079 * */ 2080 static void set_AV_CR6 ( IRExpr* result, Bool test_all_ones ) 2081 { 2082 /* CR6[0:3] = {all_ones, 0, all_zeros, 0} 2083 all_ones = (v[0] && v[1] && v[2] && v[3]) 2084 all_zeros = ~(v[0] || v[1] || v[2] || v[3]) 2085 */ 2086 IRTemp v0 = newTemp(Ity_V128); 2087 IRTemp v1 = newTemp(Ity_V128); 2088 IRTemp v2 = newTemp(Ity_V128); 2089 IRTemp v3 = newTemp(Ity_V128); 2090 IRTemp rOnes = newTemp(Ity_I8); 2091 IRTemp rZeros = newTemp(Ity_I8); 2092 2093 vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_V128); 2094 2095 assign( v0, result ); 2096 assign( v1, binop(Iop_ShrV128, result, mkU8(32)) ); 2097 assign( v2, binop(Iop_ShrV128, result, mkU8(64)) ); 2098 assign( v3, binop(Iop_ShrV128, result, mkU8(96)) ); 2099 2100 assign( rZeros, unop(Iop_1Uto8, 2101 binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF), 2102 unop(Iop_Not32, 2103 unop(Iop_V128to32, 2104 binop(Iop_OrV128, 2105 binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)), 2106 binop(Iop_OrV128, mkexpr(v2), mkexpr(v3)))) 2107 ))) ); 2108 2109 if (test_all_ones) { 2110 assign( rOnes, unop(Iop_1Uto8, 2111 binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF), 2112 unop(Iop_V128to32, 2113 binop(Iop_AndV128, 2114 binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)), 2115 binop(Iop_AndV128, mkexpr(v2), mkexpr(v3))) 2116 ))) ); 2117 putCR321( 6, binop(Iop_Or8, 2118 binop(Iop_Shl8, mkexpr(rOnes), mkU8(3)), 2119 binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) ); 2120 } else { 2121 putCR321( 6, binop(Iop_Shl8, mkexpr(rZeros), mkU8(1)) ); 2122 } 2123 putCR0( 6, mkU8(0) ); 2124 } 2125 2126 2127 static IRExpr * create_DCM ( IRType size, IRTemp NaN, IRTemp inf, IRTemp zero, 2128 IRTemp dnorm, IRTemp pos) 2129 { 2130 /* This is a general function for creating the DCM for a 32-bit or 2131 64-bit expression based on the passes size. 2132 */ 2133 IRTemp neg; 2134 IROp opAND, opOR, opSHL, opXto1, op1UtoX; 2135 2136 vassert( ( size == Ity_I32 ) || ( size == Ity_I64 ) ); 2137 2138 if ( size == Ity_I32 ) { 2139 opSHL = Iop_Shl32; 2140 opAND = Iop_And32; 2141 opOR = Iop_Or32; 2142 opXto1 = Iop_32to1; 2143 op1UtoX = Iop_1Uto32; 2144 neg = newTemp( Ity_I32 ); 2145 2146 } else { 2147 opSHL = Iop_Shl64; 2148 opAND = Iop_And64; 2149 opOR = Iop_Or64; 2150 opXto1 = Iop_64to1; 2151 op1UtoX = Iop_1Uto64; 2152 neg = newTemp( Ity_I64 ); 2153 } 2154 2155 assign( neg, unop( op1UtoX, mkNOT1( unop( opXto1, 2156 mkexpr ( pos ) ) ) ) ); 2157 2158 return binop( opOR, 2159 binop( opSHL, mkexpr( NaN ), mkU8( 6 ) ), 2160 binop( opOR, 2161 binop( opOR, 2162 binop( opOR, 2163 binop( opSHL, 2164 binop( opAND, 2165 mkexpr( pos ), 2166 mkexpr( inf ) ), 2167 mkU8( 5 ) ), 2168 binop( opSHL, 2169 binop( opAND, 2170 mkexpr( neg ), 2171 mkexpr( inf ) ), 2172 mkU8( 4 ) ) ), 2173 binop( opOR, 2174 binop( opSHL, 2175 binop( opAND, 2176 mkexpr( pos ), 2177 mkexpr( zero ) ), 2178 mkU8( 3 ) ), 2179 binop( opSHL, 2180 binop( opAND, 2181 mkexpr( neg ), 2182 mkexpr( zero ) ), 2183 mkU8( 2 ) ) ) ), 2184 binop( opOR, 2185 binop( opSHL, 2186 binop( opAND, 2187 mkexpr( pos ), 2188 mkexpr( dnorm ) ), 2189 mkU8( 1 ) ), 2190 binop( opAND, 2191 mkexpr( neg ), 2192 mkexpr( dnorm ) ) ) ) ); 2193 } 2194 2195 /*------------------------------------------------------------*/ 2196 /*--- Helpers for XER flags. ---*/ 2197 /*------------------------------------------------------------*/ 2198 2199 static void putXER_SO ( IRExpr* e ) 2200 { 2201 IRExpr* so; 2202 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2203 so = binop(Iop_And8, e, mkU8(1)); 2204 stmt( IRStmt_Put( OFFB_XER_SO, so ) ); 2205 } 2206 2207 static void putXER_OV ( IRExpr* e ) 2208 { 2209 /* Interface to write XER[OV] */ 2210 IRExpr* ov; 2211 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2212 ov = binop(Iop_And8, e, mkU8(1)); 2213 stmt( IRStmt_Put( OFFB_XER_OV, ov ) ); 2214 } 2215 2216 static void putXER_OV32 ( IRExpr* e ) 2217 { 2218 /*Interface to write XER[OV32] */ 2219 IRExpr* ov; 2220 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2221 ov = binop(Iop_And8, e, mkU8(1)); 2222 2223 /* The OV32 bit was added to XER in ISA 3.0. Do not write unless we 2224 * ISA 3.0 or beyond is supported. */ 2225 if( OV32_CA32_supported ) 2226 stmt( IRStmt_Put( OFFB_XER_OV32, ov ) ); 2227 } 2228 2229 static void putXER_CA ( IRExpr* e ) 2230 { 2231 /* Interface to write XER[CA] */ 2232 IRExpr* ca; 2233 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2234 ca = binop(Iop_And8, e, mkU8(1)); 2235 stmt( IRStmt_Put( OFFB_XER_CA, ca ) ); 2236 } 2237 2238 static void putXER_CA32 ( IRExpr* e ) 2239 { 2240 /* Interface to write XER[CA32] */ 2241 IRExpr* ca; 2242 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2243 ca = binop(Iop_And8, e, mkU8(1)); 2244 2245 /* The CA32 bit was added to XER in ISA 3.0. Do not write unless we 2246 * ISA 3.0 or beyond is supported. */ 2247 if( OV32_CA32_supported ) 2248 stmt( IRStmt_Put( OFFB_XER_CA32, ca ) ); 2249 } 2250 2251 static void putXER_BC ( IRExpr* e ) 2252 { 2253 IRExpr* bc; 2254 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 2255 bc = binop(Iop_And8, e, mkU8(0x7F)); 2256 stmt( IRStmt_Put( OFFB_XER_BC, bc ) ); 2257 } 2258 2259 static IRExpr* /* :: Ity_I8 */ getXER_SO ( void ) 2260 { 2261 return IRExpr_Get( OFFB_XER_SO, Ity_I8 ); 2262 } 2263 2264 static IRExpr* /* :: Ity_I32 */ getXER_SO_32 ( void ) 2265 { 2266 return binop( Iop_And32, unop(Iop_8Uto32, getXER_SO()), mkU32(1) ); 2267 } 2268 2269 static IRExpr* /* :: Ity_I8 */ getXER_OV ( void ) 2270 { 2271 return IRExpr_Get( OFFB_XER_OV, Ity_I8 ); 2272 } 2273 2274 static IRExpr* /* :: Ity_I8 */ getXER_OV32 ( void ) 2275 { 2276 return IRExpr_Get( OFFB_XER_OV32, Ity_I8 ); 2277 } 2278 2279 static IRExpr* /* :: Ity_I32 */ getXER_OV_32 ( void ) 2280 { 2281 /* get XER[OV], 32-bit interface */ 2282 return binop( Iop_And32, unop(Iop_8Uto32, getXER_OV()), mkU32(1) ); 2283 } 2284 2285 static IRExpr* /* :: Ity_I32 */ getXER_OV32_32 ( void ) 2286 { 2287 /* get XER[OV32], 32-bit interface */ 2288 return binop( Iop_And32, unop(Iop_8Uto32, getXER_OV32()), mkU32(1) ); 2289 } 2290 2291 static IRExpr* /* :: Ity_I32 */ getXER_CA_32 ( void ) 2292 { 2293 /* get XER[CA], 32-bit interface */ 2294 IRExpr* ca = IRExpr_Get( OFFB_XER_CA, Ity_I8 ); 2295 return binop( Iop_And32, unop(Iop_8Uto32, ca ), mkU32(1) ); 2296 } 2297 2298 static IRExpr* /* :: Ity_I32 */ getXER_CA32_32 ( void ) 2299 { 2300 /* get XER[CA32], 32-bit interface */ 2301 IRExpr* ca = IRExpr_Get( OFFB_XER_CA32, Ity_I8 ); 2302 return binop( Iop_And32, unop(Iop_8Uto32, ca ), mkU32(1) ); 2303 } 2304 2305 static IRExpr* /* :: Ity_I8 */ getXER_BC ( void ) 2306 { 2307 return IRExpr_Get( OFFB_XER_BC, Ity_I8 ); 2308 } 2309 2310 static IRExpr* /* :: Ity_I32 */ getXER_BC_32 ( void ) 2311 { 2312 IRExpr* bc = IRExpr_Get( OFFB_XER_BC, Ity_I8 ); 2313 return binop( Iop_And32, unop(Iop_8Uto32, bc), mkU32(0x7F) ); 2314 } 2315 2316 2317 /* RES is the result of doing OP on ARGL and ARGR. Set %XER.OV and 2318 %XER.SO accordingly. */ 2319 2320 static IRExpr* calculate_XER_OV_32( UInt op, IRExpr* res, 2321 IRExpr* argL, IRExpr* argR ) 2322 { 2323 IRTemp t64; 2324 IRExpr* xer_ov; 2325 2326 # define INT32_MIN 0x80000000 2327 2328 # define XOR2(_aa,_bb) \ 2329 binop(Iop_Xor32,(_aa),(_bb)) 2330 2331 # define XOR3(_cc,_dd,_ee) \ 2332 binop(Iop_Xor32,binop(Iop_Xor32,(_cc),(_dd)),(_ee)) 2333 2334 # define AND3(_ff,_gg,_hh) \ 2335 binop(Iop_And32,binop(Iop_And32,(_ff),(_gg)),(_hh)) 2336 2337 #define NOT(_jj) \ 2338 unop(Iop_Not32, (_jj)) 2339 2340 switch (op) { 2341 case /* 0 */ PPCG_FLAG_OP_ADD: 2342 case /* 1 */ PPCG_FLAG_OP_ADDE: 2343 /* (argL^argR^-1) & (argL^res) & (1<<31) ?1:0 */ 2344 // i.e. ((both_same_sign) & (sign_changed) & (sign_mask)) 2345 xer_ov 2346 = AND3( XOR3(argL,argR,mkU32(-1)), 2347 XOR2(argL,res), 2348 mkU32(INT32_MIN) ); 2349 /* xer_ov can only be 0 or 1<<31 */ 2350 xer_ov 2351 = binop(Iop_Shr32, xer_ov, mkU8(31) ); 2352 break; 2353 2354 case /* 2 */ PPCG_FLAG_OP_DIVW: 2355 /* (argL == INT32_MIN && argR == -1) || argR == 0 */ 2356 xer_ov 2357 = mkOR1( 2358 mkAND1( 2359 binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)), 2360 binop(Iop_CmpEQ32, argR, mkU32(-1)) 2361 ), 2362 binop(Iop_CmpEQ32, argR, mkU32(0) ) 2363 ); 2364 xer_ov 2365 = unop(Iop_1Uto32, xer_ov); 2366 break; 2367 2368 case /* 3 */ PPCG_FLAG_OP_DIVWU: 2369 /* argR == 0 */ 2370 xer_ov 2371 = unop(Iop_1Uto32, binop(Iop_CmpEQ32, argR, mkU32(0))); 2372 break; 2373 2374 case /* 4 */ PPCG_FLAG_OP_MULLW: 2375 /* OV true if result can't be represented in 32 bits 2376 i.e sHi != sign extension of sLo */ 2377 t64 = newTemp(Ity_I64); 2378 assign( t64, binop(Iop_MullS32, argL, argR) ); 2379 xer_ov 2380 = binop( Iop_CmpNE32, 2381 unop(Iop_64HIto32, mkexpr(t64)), 2382 binop( Iop_Sar32, 2383 unop(Iop_64to32, mkexpr(t64)), 2384 mkU8(31)) 2385 ); 2386 xer_ov 2387 = unop(Iop_1Uto32, xer_ov); 2388 break; 2389 2390 case /* 5 */ PPCG_FLAG_OP_NEG: 2391 /* argL == INT32_MIN */ 2392 xer_ov 2393 = unop( Iop_1Uto32, 2394 binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)) ); 2395 break; 2396 2397 case /* 6 */ PPCG_FLAG_OP_SUBF: 2398 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2399 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2400 /* ((~argL)^argR^-1) & ((~argL)^res) & (1<<31) ?1:0; */ 2401 xer_ov 2402 = AND3( XOR3(NOT(argL),argR,mkU32(-1)), 2403 XOR2(NOT(argL),res), 2404 mkU32(INT32_MIN) ); 2405 /* xer_ov can only be 0 or 1<<31 */ 2406 xer_ov 2407 = binop(Iop_Shr32, xer_ov, mkU8(31) ); 2408 break; 2409 2410 case PPCG_FLAG_OP_DIVWEU: 2411 xer_ov 2412 = binop( Iop_Or32, 2413 unop( Iop_1Uto32, binop( Iop_CmpEQ32, argR, mkU32( 0 ) ) ), 2414 unop( Iop_1Uto32, binop( Iop_CmpLT32U, argR, argL ) ) ); 2415 break; 2416 2417 case PPCG_FLAG_OP_DIVWE: 2418 2419 /* If argR == 0 of if the result cannot fit in the 32-bit destination register, 2420 * then OV <- 1. If dest reg is 0 AND both dividend and divisor are non-zero, 2421 * an overflow is implied. 2422 */ 2423 xer_ov = binop( Iop_Or32, 2424 unop( Iop_1Uto32, binop( Iop_CmpEQ32, argR, mkU32( 0 ) ) ), 2425 unop( Iop_1Uto32, mkAND1( binop( Iop_CmpEQ32, res, mkU32( 0 ) ), 2426 mkAND1( binop( Iop_CmpNE32, argL, mkU32( 0 ) ), 2427 binop( Iop_CmpNE32, argR, mkU32( 0 ) ) ) ) ) ); 2428 break; 2429 2430 2431 2432 default: 2433 vex_printf("calculate_XER_OV_32: op = %u\n", op); 2434 vpanic("calculate_XER_OV_32(ppc)"); 2435 } 2436 2437 return xer_ov; 2438 2439 # undef INT32_MIN 2440 # undef AND3 2441 # undef XOR3 2442 # undef XOR2 2443 # undef NOT 2444 } 2445 2446 static void set_XER_OV_OV32_32( UInt op, IRExpr* res, 2447 IRExpr* argL, IRExpr* argR ) 2448 { 2449 IRExpr* xer_ov; 2450 2451 vassert(op < PPCG_FLAG_OP_NUMBER); 2452 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I32); 2453 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I32); 2454 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I32); 2455 2456 xer_ov = calculate_XER_OV_32( op, res, argL, argR ); 2457 2458 /* xer_ov MUST denote either 0 or 1, no other value allowed */ 2459 putXER_OV( unop(Iop_32to8, xer_ov) ); 2460 putXER_OV32( unop(Iop_32to8, xer_ov) ); 2461 } 2462 2463 static IRExpr* calculate_XER_OV_64( UInt op, IRExpr* res, 2464 IRExpr* argL, IRExpr* argR ) 2465 { 2466 IRExpr* xer_ov; 2467 2468 # define INT64_MIN 0x8000000000000000ULL 2469 2470 # define XOR2(_aa,_bb) \ 2471 binop(Iop_Xor64,(_aa),(_bb)) 2472 2473 # define XOR3(_cc,_dd,_ee) \ 2474 binop(Iop_Xor64,binop(Iop_Xor64,(_cc),(_dd)),(_ee)) 2475 2476 # define AND3(_ff,_gg,_hh) \ 2477 binop(Iop_And64,binop(Iop_And64,(_ff),(_gg)),(_hh)) 2478 2479 #define NOT(_jj) \ 2480 unop(Iop_Not64, (_jj)) 2481 2482 switch (op) { 2483 case /* 0 */ PPCG_FLAG_OP_ADD: 2484 case /* 1 */ PPCG_FLAG_OP_ADDE: 2485 /* (argL^argR^-1) & (argL^res) & (1<<63) ? 1:0 */ 2486 // i.e. ((both_same_sign) & (sign_changed) & (sign_mask)) 2487 xer_ov 2488 = AND3( XOR3(argL,argR,mkU64(-1)), 2489 XOR2(argL,res), 2490 mkU64(INT64_MIN) ); 2491 /* xer_ov can only be 0 or 1<<63 */ 2492 xer_ov 2493 = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63))); 2494 break; 2495 2496 case /* 2 */ PPCG_FLAG_OP_DIVW: 2497 /* (argL == INT64_MIN && argR == -1) || argR == 0 */ 2498 xer_ov 2499 = mkOR1( 2500 mkAND1( 2501 binop(Iop_CmpEQ64, argL, mkU64(INT64_MIN)), 2502 binop(Iop_CmpEQ64, argR, mkU64(-1)) 2503 ), 2504 binop(Iop_CmpEQ64, argR, mkU64(0) ) 2505 ); 2506 break; 2507 2508 case /* 3 */ PPCG_FLAG_OP_DIVWU: 2509 /* argR == 0 */ 2510 xer_ov 2511 = binop(Iop_CmpEQ64, argR, mkU64(0)); 2512 break; 2513 2514 case /* 4 */ PPCG_FLAG_OP_MULLW: { 2515 /* OV true if result can't be represented in 64 bits 2516 i.e sHi != sign extension of sLo */ 2517 xer_ov 2518 = binop( Iop_CmpNE32, 2519 unop(Iop_64HIto32, res), 2520 binop( Iop_Sar32, 2521 unop(Iop_64to32, res), 2522 mkU8(31)) 2523 ); 2524 break; 2525 } 2526 2527 case /* 5 */ PPCG_FLAG_OP_NEG: 2528 /* argL == INT64_MIN */ 2529 xer_ov 2530 = binop(Iop_CmpEQ64, argL, mkU64(INT64_MIN)); 2531 break; 2532 2533 case /* 6 */ PPCG_FLAG_OP_SUBF: 2534 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2535 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2536 /* ((~argL)^argR^-1) & ((~argL)^res) & (1<<63) ?1:0; */ 2537 xer_ov 2538 = AND3( XOR3(NOT(argL),argR,mkU64(-1)), 2539 XOR2(NOT(argL),res), 2540 mkU64(INT64_MIN) ); 2541 /* xer_ov can only be 0 or 1<<63 */ 2542 xer_ov 2543 = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63))); 2544 break; 2545 2546 case /* 14 */ PPCG_FLAG_OP_DIVDE: 2547 2548 /* If argR == 0, we must set the OV bit. But there's another condition 2549 * where we can get overflow set for divde . . . when the 2550 * result cannot fit in the 64-bit destination register. If dest reg is 0 AND 2551 * both dividend and divisor are non-zero, it implies an overflow. 2552 */ 2553 xer_ov 2554 = mkOR1( binop( Iop_CmpEQ64, argR, mkU64( 0 ) ), 2555 mkAND1( binop( Iop_CmpEQ64, res, mkU64( 0 ) ), 2556 mkAND1( binop( Iop_CmpNE64, argL, mkU64( 0 ) ), 2557 binop( Iop_CmpNE64, argR, mkU64( 0 ) ) ) ) ); 2558 break; 2559 2560 case /* 17 */ PPCG_FLAG_OP_DIVDEU: 2561 /* If argR == 0 or if argL >= argR, set OV. */ 2562 xer_ov = mkOR1( binop( Iop_CmpEQ64, argR, mkU64( 0 ) ), 2563 binop( Iop_CmpLE64U, argR, argL ) ); 2564 break; 2565 2566 case /* 18 */ PPCG_FLAG_OP_MULLD: { 2567 IRTemp t128; 2568 /* OV true if result can't be represented in 64 bits 2569 i.e sHi != sign extension of sLo */ 2570 t128 = newTemp(Ity_I128); 2571 assign( t128, binop(Iop_MullS64, argL, argR) ); 2572 xer_ov 2573 = binop( Iop_CmpNE64, 2574 unop(Iop_128HIto64, mkexpr(t128)), 2575 binop( Iop_Sar64, 2576 unop(Iop_128to64, mkexpr(t128)), 2577 mkU8(63)) 2578 ); 2579 break; 2580 } 2581 2582 default: 2583 vex_printf("calculate_XER_OV_64: op = %u\n", op); 2584 vpanic("calculate_XER_OV_64(ppc64)"); 2585 } 2586 2587 return xer_ov; 2588 2589 # undef INT64_MIN 2590 # undef AND3 2591 # undef XOR3 2592 # undef XOR2 2593 # undef NOT 2594 } 2595 2596 static void set_XER_OV_64( UInt op, IRExpr* res, 2597 IRExpr* argL, IRExpr* argR ) 2598 { 2599 IRExpr* xer_ov; 2600 vassert(op < PPCG_FLAG_OP_NUMBER); 2601 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I64); 2602 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I64); 2603 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I64); 2604 2605 /* xer_ov MUST denote either 0 or 1, no other value allowed */ 2606 xer_ov = calculate_XER_OV_64( op, res, argL, argR); 2607 putXER_OV( unop(Iop_1Uto8, xer_ov) ); 2608 2609 /* Update the summary overflow */ 2610 putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) ); 2611 } 2612 2613 static void update_SO( void ) { 2614 /* Update the summary overflow bit */ 2615 putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) ); 2616 } 2617 2618 static void copy_OV_to_OV32( void ) { 2619 /* Update the OV32 to match OV */ 2620 putXER_OV32( getXER_OV() ); 2621 } 2622 2623 static void set_XER_OV_OV32 ( IRType ty, UInt op, IRExpr* res, 2624 IRExpr* argL, IRExpr* argR ) 2625 { 2626 if (ty == Ity_I32) { 2627 set_XER_OV_OV32_32( op, res, argL, argR ); 2628 } else { 2629 IRExpr* xer_ov_32; 2630 set_XER_OV_64( op, res, argL, argR ); 2631 xer_ov_32 = calculate_XER_OV_32( op, unop(Iop_64to32, res), 2632 unop(Iop_64to32, argL), 2633 unop(Iop_64to32, argR)); 2634 putXER_OV32( unop(Iop_32to8, xer_ov_32) ); 2635 } 2636 } 2637 2638 static void set_XER_OV_OV32_SO ( IRType ty, UInt op, IRExpr* res, 2639 IRExpr* argL, IRExpr* argR ) 2640 { 2641 if (ty == Ity_I32) { 2642 set_XER_OV_OV32_32( op, res, argL, argR ); 2643 } else { 2644 IRExpr* xer_ov_32; 2645 set_XER_OV_64( op, res, argL, argR ); 2646 xer_ov_32 = calculate_XER_OV_32( op, unop(Iop_64to32, res), 2647 unop(Iop_64to32, argL), 2648 unop(Iop_64to32, argR)); 2649 putXER_OV32( unop(Iop_32to8, xer_ov_32) ); 2650 } 2651 update_SO(); 2652 } 2653 2654 2655 2656 /* RES is the result of doing OP on ARGL and ARGR with the old %XER.CA 2657 value being OLDCA. Set %XER.CA accordingly. */ 2658 2659 static IRExpr* calculate_XER_CA_32 ( UInt op, IRExpr* res, 2660 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2661 { 2662 IRExpr* xer_ca; 2663 2664 switch (op) { 2665 case /* 0 */ PPCG_FLAG_OP_ADD: 2666 /* res <u argL */ 2667 xer_ca 2668 = unop(Iop_1Uto32, binop(Iop_CmpLT32U, res, argL)); 2669 break; 2670 2671 case /* 1 */ PPCG_FLAG_OP_ADDE: 2672 /* res <u argL || (old_ca==1 && res==argL) */ 2673 xer_ca 2674 = mkOR1( 2675 binop(Iop_CmpLT32U, res, argL), 2676 mkAND1( 2677 binop(Iop_CmpEQ32, oldca, mkU32(1)), 2678 binop(Iop_CmpEQ32, res, argL) 2679 ) 2680 ); 2681 xer_ca 2682 = unop(Iop_1Uto32, xer_ca); 2683 break; 2684 2685 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2686 /* res <u argR || (old_ca==1 && res==argR) */ 2687 xer_ca 2688 = mkOR1( 2689 binop(Iop_CmpLT32U, res, argR), 2690 mkAND1( 2691 binop(Iop_CmpEQ32, oldca, mkU32(1)), 2692 binop(Iop_CmpEQ32, res, argR) 2693 ) 2694 ); 2695 xer_ca 2696 = unop(Iop_1Uto32, xer_ca); 2697 break; 2698 2699 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2700 case /* 9 */ PPCG_FLAG_OP_SUBFI: 2701 /* res <=u argR */ 2702 xer_ca 2703 = unop(Iop_1Uto32, binop(Iop_CmpLE32U, res, argR)); 2704 break; 2705 2706 case /* 10 */ PPCG_FLAG_OP_SRAW: 2707 /* The shift amount is guaranteed to be in 0 .. 63 inclusive. 2708 If it is <= 31, behave like SRAWI; else XER.CA is the sign 2709 bit of argL. */ 2710 /* This term valid for shift amount < 32 only */ 2711 xer_ca 2712 = binop( 2713 Iop_And32, 2714 binop(Iop_Sar32, argL, mkU8(31)), 2715 binop( Iop_And32, 2716 argL, 2717 binop( Iop_Sub32, 2718 binop(Iop_Shl32, mkU32(1), 2719 unop(Iop_32to8,argR)), 2720 mkU32(1) ) 2721 ) 2722 ); 2723 xer_ca 2724 = IRExpr_ITE( 2725 /* shift amt > 31 ? */ 2726 binop(Iop_CmpLT32U, mkU32(31), argR), 2727 /* yes -- get sign bit of argL */ 2728 binop(Iop_Shr32, argL, mkU8(31)), 2729 /* no -- be like srawi */ 2730 unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))) 2731 ); 2732 break; 2733 2734 case /* 11 */ PPCG_FLAG_OP_SRAWI: 2735 /* xer_ca is 1 iff src was negative and bits_shifted_out != 2736 0. Since the shift amount is known to be in the range 2737 0 .. 31 inclusive the following seems viable: 2738 xer.ca == 1 iff the following is nonzero: 2739 (argL >>s 31) -- either all 0s or all 1s 2740 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2741 xer_ca 2742 = binop( 2743 Iop_And32, 2744 binop(Iop_Sar32, argL, mkU8(31)), 2745 binop( Iop_And32, 2746 argL, 2747 binop( Iop_Sub32, 2748 binop(Iop_Shl32, mkU32(1), 2749 unop(Iop_32to8,argR)), 2750 mkU32(1) ) 2751 ) 2752 ); 2753 xer_ca 2754 = unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))); 2755 break; 2756 2757 default: 2758 vex_printf("set_XER_CA: op = %u\n", op); 2759 vpanic("set_XER_CA(ppc)"); 2760 } 2761 2762 return xer_ca; 2763 } 2764 2765 static void set_XER_CA_32 ( UInt op, IRExpr* res, 2766 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2767 { 2768 IRExpr* xer_ca; 2769 vassert(op < PPCG_FLAG_OP_NUMBER); 2770 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I32); 2771 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I32); 2772 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I32); 2773 vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I32); 2774 2775 /* Incoming oldca is assumed to hold the values 0 or 1 only. This 2776 seems reasonable given that it's always generated by 2777 getXER_CA_32(), which masks it accordingly. In any case it being 2778 0 or 1 is an invariant of the ppc guest state representation; 2779 if it has any other value, that invariant has been violated. */ 2780 2781 xer_ca = calculate_XER_CA_32( op, res, argL, argR, oldca); 2782 2783 /* xer_ca MUST denote either 0 or 1, no other value allowed */ 2784 putXER_CA( unop(Iop_32to8, xer_ca) ); 2785 } 2786 2787 static IRExpr* calculate_XER_CA_64 ( UInt op, IRExpr* res, 2788 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2789 { 2790 IRExpr* xer_ca; 2791 2792 switch (op) { 2793 case /* 0 */ PPCG_FLAG_OP_ADD: 2794 /* res <u argL */ 2795 xer_ca 2796 = unop(Iop_1Uto32, binop(Iop_CmpLT64U, res, argL)); 2797 break; 2798 2799 case /* 1 */ PPCG_FLAG_OP_ADDE: 2800 /* res <u argL || (old_ca==1 && res==argL) */ 2801 xer_ca 2802 = mkOR1( 2803 binop(Iop_CmpLT64U, res, argL), 2804 mkAND1( 2805 binop(Iop_CmpEQ64, oldca, mkU64(1)), 2806 binop(Iop_CmpEQ64, res, argL) 2807 ) 2808 ); 2809 xer_ca 2810 = unop(Iop_1Uto32, xer_ca); 2811 break; 2812 2813 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2814 /* res <u argR || (old_ca==1 && res==argR) */ 2815 xer_ca 2816 = mkOR1( 2817 binop(Iop_CmpLT64U, res, argR), 2818 mkAND1( 2819 binop(Iop_CmpEQ64, oldca, mkU64(1)), 2820 binop(Iop_CmpEQ64, res, argR) 2821 ) 2822 ); 2823 xer_ca 2824 = unop(Iop_1Uto32, xer_ca); 2825 break; 2826 2827 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2828 case /* 9 */ PPCG_FLAG_OP_SUBFI: 2829 /* res <=u argR */ 2830 xer_ca 2831 = unop(Iop_1Uto32, binop(Iop_CmpLE64U, res, argR)); 2832 break; 2833 2834 2835 case /* 10 */ PPCG_FLAG_OP_SRAW: 2836 /* The shift amount is guaranteed to be in 0 .. 31 inclusive. 2837 If it is <= 31, behave like SRAWI; else XER.CA is the sign 2838 bit of argL. */ 2839 /* This term valid for shift amount < 31 only */ 2840 2841 xer_ca 2842 = binop( 2843 Iop_And64, 2844 binop(Iop_Sar64, argL, mkU8(31)), 2845 binop( Iop_And64, 2846 argL, 2847 binop( Iop_Sub64, 2848 binop(Iop_Shl64, mkU64(1), 2849 unop(Iop_64to8,argR)), 2850 mkU64(1) ) 2851 ) 2852 ); 2853 xer_ca 2854 = IRExpr_ITE( 2855 /* shift amt > 31 ? */ 2856 binop(Iop_CmpLT64U, mkU64(31), argR), 2857 /* yes -- get sign bit of argL */ 2858 unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63))), 2859 /* no -- be like srawi */ 2860 unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))) 2861 ); 2862 break; 2863 2864 case /* 11 */ PPCG_FLAG_OP_SRAWI: 2865 /* xer_ca is 1 iff src was negative and bits_shifted_out != 0. 2866 Since the shift amount is known to be in the range 0 .. 31 2867 inclusive the following seems viable: 2868 xer.ca == 1 iff the following is nonzero: 2869 (argL >>s 31) -- either all 0s or all 1s 2870 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2871 2872 xer_ca 2873 = binop( 2874 Iop_And64, 2875 binop(Iop_Sar64, argL, mkU8(31)), 2876 binop( Iop_And64, 2877 argL, 2878 binop( Iop_Sub64, 2879 binop(Iop_Shl64, mkU64(1), 2880 unop(Iop_64to8,argR)), 2881 mkU64(1) ) 2882 ) 2883 ); 2884 xer_ca 2885 = unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))); 2886 break; 2887 2888 2889 case /* 12 */ PPCG_FLAG_OP_SRAD: 2890 /* The shift amount is guaranteed to be in 0 .. 63 inclusive. 2891 If it is <= 63, behave like SRADI; else XER.CA is the sign 2892 bit of argL. */ 2893 /* This term valid for shift amount < 63 only */ 2894 2895 xer_ca 2896 = binop( 2897 Iop_And64, 2898 binop(Iop_Sar64, argL, mkU8(63)), 2899 binop( Iop_And64, 2900 argL, 2901 binop( Iop_Sub64, 2902 binop(Iop_Shl64, mkU64(1), 2903 unop(Iop_64to8,argR)), 2904 mkU64(1) ) 2905 ) 2906 ); 2907 xer_ca 2908 = IRExpr_ITE( 2909 /* shift amt > 63 ? */ 2910 binop(Iop_CmpLT64U, mkU64(63), argR), 2911 /* yes -- get sign bit of argL */ 2912 unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63))), 2913 /* no -- be like sradi */ 2914 unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))) 2915 ); 2916 break; 2917 2918 2919 case /* 13 */ PPCG_FLAG_OP_SRADI: 2920 /* xer_ca is 1 iff src was negative and bits_shifted_out != 0. 2921 Since the shift amount is known to be in the range 0 .. 63 2922 inclusive, the following seems viable: 2923 xer.ca == 1 iff the following is nonzero: 2924 (argL >>s 63) -- either all 0s or all 1s 2925 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2926 2927 xer_ca 2928 = binop( 2929 Iop_And64, 2930 binop(Iop_Sar64, argL, mkU8(63)), 2931 binop( Iop_And64, 2932 argL, 2933 binop( Iop_Sub64, 2934 binop(Iop_Shl64, mkU64(1), 2935 unop(Iop_64to8,argR)), 2936 mkU64(1) ) 2937 ) 2938 ); 2939 xer_ca 2940 = unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))); 2941 break; 2942 2943 default: 2944 vex_printf("set_XER_CA: op = %u\n", op); 2945 vpanic("set_XER_CA(ppc64)"); 2946 } 2947 2948 return xer_ca; 2949 } 2950 2951 static void set_XER_CA_64 ( UInt op, IRExpr* res, 2952 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2953 { 2954 IRExpr* xer_ca; 2955 vassert(op < PPCG_FLAG_OP_NUMBER); 2956 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I64); 2957 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I64); 2958 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I64); 2959 vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I64); 2960 2961 /* Incoming oldca is assumed to hold the values 0 or 1 only. This 2962 seems reasonable given that it's always generated by 2963 getXER_CA_32(), which masks it accordingly. In any case it being 2964 0 or 1 is an invariant of the ppc guest state representation; 2965 if it has any other value, that invariant has been violated. */ 2966 2967 xer_ca = calculate_XER_CA_64( op, res, argL, argR, oldca ); 2968 2969 /* xer_ca MUST denote either 0 or 1, no other value allowed */ 2970 putXER_CA( unop(Iop_32to8, xer_ca) ); 2971 } 2972 2973 static void set_XER_CA_CA32 ( IRType ty, UInt op, IRExpr* res, 2974 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2975 { 2976 if (ty == Ity_I32) { 2977 set_XER_CA_32( op, res, argL, argR, oldca ); 2978 } else { 2979 set_XER_CA_64( op, res, argL, argR, oldca ); 2980 } 2981 } 2982 2983 2984 2985 /*------------------------------------------------------------*/ 2986 /*--- Read/write to guest-state --- */ 2987 /*------------------------------------------------------------*/ 2988 2989 static IRExpr* /* :: Ity_I32/64 */ getGST ( PPC_GST reg ) 2990 { 2991 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2992 switch (reg) { 2993 case PPC_GST_SPRG3_RO: 2994 return IRExpr_Get( OFFB_SPRG3_RO, ty ); 2995 2996 case PPC_GST_CIA: 2997 return IRExpr_Get( OFFB_CIA, ty ); 2998 2999 case PPC_GST_LR: 3000 return IRExpr_Get( OFFB_LR, ty ); 3001 3002 case PPC_GST_CTR: 3003 return IRExpr_Get( OFFB_CTR, ty ); 3004 3005 case PPC_GST_VRSAVE: 3006 return IRExpr_Get( OFFB_VRSAVE, Ity_I32 ); 3007 3008 case PPC_GST_VSCR: 3009 return binop(Iop_And32, IRExpr_Get( OFFB_VSCR,Ity_I32 ), 3010 mkU32(MASK_VSCR_VALID)); 3011 3012 case PPC_GST_CR: { 3013 /* Synthesise the entire CR into a single word. Expensive. */ 3014 # define FIELD(_n) \ 3015 binop(Iop_Shl32, \ 3016 unop(Iop_8Uto32, \ 3017 binop(Iop_Or8, \ 3018 binop(Iop_And8, getCR321(_n), mkU8(7<<1)), \ 3019 binop(Iop_And8, getCR0(_n), mkU8(1)) \ 3020 ) \ 3021 ), \ 3022 mkU8(4 * (7-(_n))) \ 3023 ) 3024 return binop(Iop_Or32, 3025 binop(Iop_Or32, 3026 binop(Iop_Or32, FIELD(0), FIELD(1)), 3027 binop(Iop_Or32, FIELD(2), FIELD(3)) 3028 ), 3029 binop(Iop_Or32, 3030 binop(Iop_Or32, FIELD(4), FIELD(5)), 3031 binop(Iop_Or32, FIELD(6), FIELD(7)) 3032 ) 3033 ); 3034 # undef FIELD 3035 } 3036 3037 case PPC_GST_XER: 3038 return binop(Iop_Or32, 3039 binop(Iop_Or32, 3040 binop(Iop_Or32, 3041 binop( Iop_Shl32, getXER_SO_32(), mkU8(31)), 3042 binop( Iop_Shl32, getXER_OV_32(), mkU8(30))), 3043 binop(Iop_Or32, 3044 binop( Iop_Shl32, getXER_CA_32(), mkU8(29)), 3045 getXER_BC_32())), 3046 binop(Iop_Or32, 3047 binop( Iop_Shl32, getXER_OV32_32(), mkU8(19)), 3048 binop( Iop_Shl32, getXER_CA32_32(), mkU8(18)))); 3049 3050 case PPC_GST_TFHAR: 3051 return IRExpr_Get( OFFB_TFHAR, ty ); 3052 3053 case PPC_GST_TEXASR: 3054 return IRExpr_Get( OFFB_TEXASR, ty ); 3055 3056 case PPC_GST_TEXASRU: 3057 return IRExpr_Get( OFFB_TEXASRU, ty ); 3058 3059 case PPC_GST_TFIAR: 3060 return IRExpr_Get( OFFB_TFIAR, ty ); 3061 3062 case PPC_GST_PPR: 3063 return IRExpr_Get( OFFB_PPR, ty ); 3064 3065 case PPC_GST_PPR32: 3066 return unop( Iop_64HIto32, IRExpr_Get( OFFB_PPR, ty ) ); 3067 3068 case PPC_GST_PSPB: 3069 return IRExpr_Get( OFFB_PSPB, ty ); 3070 3071 default: 3072 vex_printf("getGST(ppc): reg = %u", reg); 3073 vpanic("getGST(ppc)"); 3074 } 3075 } 3076 3077 /* Get a masked word from the given reg */ 3078 static IRExpr* /* ::Ity_I32 */ getGST_masked ( PPC_GST reg, ULong mask ) 3079 { 3080 IRTemp val = newTemp(Ity_I32); 3081 vassert( reg < PPC_GST_MAX ); 3082 3083 switch (reg) { 3084 3085 case PPC_GST_FPSCR: { 3086 /* Vex-generated code expects the FPSCR to be set as follows: 3087 all exceptions masked, round-to-nearest. 3088 This corresponds to a FPSCR value of 0x0. */ 3089 3090 /* In the lower 32 bits of FPSCR, we're keeping track of the binary 3091 * floating point rounding mode and Floating-point Condition code, so 3092 * if the mask isn't asking for either of these, just return 0x0. 3093 */ 3094 if ( mask & ( MASK_FPSCR_C_FPCC | MASK_FPSCR_RN ) ) { 3095 assign( val, binop( Iop_Or32, 3096 unop( Iop_8Uto32, IRExpr_Get( OFFB_FPROUND, Ity_I8 ) ), 3097 binop( Iop_Shl32, 3098 unop( Iop_8Uto32, 3099 IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ), 3100 mkU8( 12 ) ) ) ); 3101 } else { 3102 assign( val, mkU32(0x0) ); 3103 } 3104 3105 break; 3106 } 3107 3108 default: 3109 vex_printf("getGST_masked(ppc): reg = %u", reg); 3110 vpanic("getGST_masked(ppc)"); 3111 } 3112 3113 if ( mask != 0xFFFFFFFF ) { 3114 return binop(Iop_And32, mkexpr(val), mkU32(mask)); 3115 } else { 3116 return mkexpr(val); 3117 } 3118 } 3119 3120 /* Get a masked word from the given reg */ 3121 static IRExpr* /* ::Ity_I32 */getGST_masked_upper(PPC_GST reg, ULong mask) { 3122 IRExpr * val; 3123 vassert( reg < PPC_GST_MAX ); 3124 3125 switch (reg) { 3126 3127 case PPC_GST_FPSCR: { 3128 /* In the upper 32 bits of FPSCR, we're only keeping track 3129 * of the decimal floating point rounding mode, so if the mask 3130 * isn't asking for this, just return 0x0. 3131 */ 3132 if (mask & MASK_FPSCR_DRN) { 3133 val = binop( Iop_And32, 3134 unop( Iop_8Uto32, IRExpr_Get( OFFB_DFPROUND, Ity_I8 ) ), 3135 unop( Iop_64HIto32, mkU64( mask ) ) ); 3136 } else { 3137 val = mkU32( 0x0ULL ); 3138 } 3139 break; 3140 } 3141 3142 default: 3143 vex_printf( "getGST_masked_upper(ppc): reg = %u", reg ); 3144 vpanic( "getGST_masked_upper(ppc)" ); 3145 } 3146 return val; 3147 } 3148 3149 3150 /* Fetch the specified REG[FLD] nibble (as per IBM/hardware notation) 3151 and return it at the bottom of an I32; the top 27 bits are 3152 guaranteed to be zero. */ 3153 static IRExpr* /* ::Ity_I32 */ getGST_field ( PPC_GST reg, UInt fld ) 3154 { 3155 UInt shft, mask; 3156 3157 vassert( fld < 8 ); 3158 vassert( reg < PPC_GST_MAX ); 3159 3160 shft = 4*(7-fld); 3161 mask = 0xF<<shft; 3162 3163 switch (reg) { 3164 case PPC_GST_XER: 3165 vassert(fld ==7); 3166 return binop(Iop_Or32, 3167 binop(Iop_Or32, 3168 binop(Iop_Shl32, getXER_SO_32(), mkU8(3)), 3169 binop(Iop_Shl32, getXER_OV_32(), mkU8(2))), 3170 binop( Iop_Shl32, getXER_CA_32(), mkU8(1))); 3171 break; 3172 3173 default: 3174 if (shft == 0) 3175 return getGST_masked( reg, mask ); 3176 else 3177 return binop(Iop_Shr32, 3178 getGST_masked( reg, mask ), 3179 mkU8(toUChar( shft ))); 3180 } 3181 } 3182 3183 static void putGST ( PPC_GST reg, IRExpr* src ) 3184 { 3185 IRType ty = mode64 ? Ity_I64 : Ity_I32; 3186 IRType ty_src = typeOfIRExpr(irsb->tyenv,src ); 3187 vassert( reg < PPC_GST_MAX ); 3188 switch (reg) { 3189 case PPC_GST_IP_AT_SYSCALL: 3190 vassert( ty_src == ty ); 3191 stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, src ) ); 3192 break; 3193 case PPC_GST_CIA: 3194 vassert( ty_src == ty ); 3195 stmt( IRStmt_Put( OFFB_CIA, src ) ); 3196 break; 3197 case PPC_GST_LR: 3198 vassert( ty_src == ty ); 3199 stmt( IRStmt_Put( OFFB_LR, src ) ); 3200 break; 3201 case PPC_GST_CTR: 3202 vassert( ty_src == ty ); 3203 stmt( IRStmt_Put( OFFB_CTR, src ) ); 3204 break; 3205 case PPC_GST_VRSAVE: 3206 vassert( ty_src == Ity_I32 ); 3207 stmt( IRStmt_Put( OFFB_VRSAVE,src)); 3208 break; 3209 case PPC_GST_VSCR: 3210 vassert( ty_src == Ity_I32 ); 3211 stmt( IRStmt_Put( OFFB_VSCR, 3212 binop(Iop_And32, src, 3213 mkU32(MASK_VSCR_VALID)) ) ); 3214 break; 3215 case PPC_GST_XER: 3216 vassert( ty_src == Ity_I32 ); 3217 putXER_SO( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(31))) ); 3218 putXER_OV( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(30))) ); 3219 putXER_CA( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(29))) ); 3220 putXER_OV32( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(19))) ); 3221 putXER_CA32( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(18))) ); 3222 putXER_BC( unop(Iop_32to8, src) ); 3223 break; 3224 3225 case PPC_GST_EMWARN: 3226 vassert( ty_src == Ity_I32 ); 3227 stmt( IRStmt_Put( OFFB_EMNOTE,src) ); 3228 break; 3229 3230 case PPC_GST_CMSTART: 3231 vassert( ty_src == ty ); 3232 stmt( IRStmt_Put( OFFB_CMSTART, src) ); 3233 break; 3234 3235 case PPC_GST_CMLEN: 3236 vassert( ty_src == ty ); 3237 stmt( IRStmt_Put( OFFB_CMLEN, src) ); 3238 break; 3239 3240 case PPC_GST_TEXASR: 3241 vassert( ty_src == Ity_I64 ); 3242 stmt( IRStmt_Put( OFFB_TEXASR, src ) ); 3243 break; 3244 3245 case PPC_GST_TEXASRU: 3246 vassert( ty_src == Ity_I32 ); 3247 stmt( IRStmt_Put( OFFB_TEXASRU, src ) ); 3248 break; 3249 3250 case PPC_GST_TFIAR: 3251 vassert( ty_src == Ity_I64 ); 3252 stmt( IRStmt_Put( OFFB_TFIAR, src ) ); 3253 break; 3254 case PPC_GST_TFHAR: 3255 vassert( ty_src == Ity_I64 ); 3256 stmt( IRStmt_Put( OFFB_TFHAR, src ) ); 3257 break; 3258 3259 case PPC_GST_PPR32: 3260 case PPC_GST_PPR: 3261 { 3262 /* The Program Priority Register (PPR) stores the priority in 3263 * bits [52:50]. The user setable priorities are: 3264 * 3265 * 001 very low 3266 * 010 low 3267 * 011 medium low 3268 * 100 medium 3269 * 101 medium high 3270 * 3271 * If the argument is not between 0b001 and 0b100 the priority is set 3272 * to 0b100. The priority can only be set to 0b101 if the the Problem 3273 * State Boost Register is non-zero. The value of the PPR is not 3274 * changed if the input is not valid. 3275 */ 3276 3277 IRTemp not_valid = newTemp(Ity_I64); 3278 IRTemp has_perm = newTemp(Ity_I64); 3279 IRTemp new_src = newTemp(Ity_I64); 3280 IRTemp PSPB_val = newTemp(Ity_I64); 3281 IRTemp value = newTemp(Ity_I64); 3282 3283 vassert(( ty_src == Ity_I64 ) || ( ty_src == Ity_I32 )); 3284 assign( PSPB_val, binop( Iop_32HLto64, 3285 mkU32( 0 ), 3286 IRExpr_Get( OFFB_PSPB, Ity_I32 ) ) ); 3287 if( reg == PPC_GST_PPR32 ) { 3288 vassert( ty_src == Ity_I32 ); 3289 assign( value, binop( Iop_32HLto64, 3290 mkU32(0), 3291 binop( Iop_And32, 3292 binop( Iop_Shr32, src, mkU8( 18 ) ), 3293 mkU32( 0x7 ) ) ) ); 3294 } else { 3295 vassert( ty_src == Ity_I64 ); 3296 assign( value, binop( Iop_And64, 3297 binop( Iop_Shr64, src, mkU8( 50 ) ), 3298 mkU64( 0x7 ) ) ); 3299 } 3300 assign( has_perm, 3301 binop( Iop_And64, 3302 unop( Iop_1Sto64, 3303 binop( Iop_CmpEQ64, 3304 mkexpr( PSPB_val ), 3305 mkU64( 0 ) ) ), 3306 unop( Iop_1Sto64, 3307 binop( Iop_CmpEQ64, 3308 mkU64( 0x5 ), 3309 mkexpr( value ) ) ) ) ); 3310 assign( not_valid, 3311 binop( Iop_Or64, 3312 unop( Iop_1Sto64, 3313 binop( Iop_CmpEQ64, 3314 mkexpr( value ), 3315 mkU64( 0 ) ) ), 3316 unop( Iop_1Sto64, 3317 binop( Iop_CmpLT64U, 3318 mkU64( 0x5 ), 3319 mkexpr( value ) ) ) ) ); 3320 assign( new_src, 3321 binop( Iop_Or64, 3322 binop( Iop_And64, 3323 unop( Iop_Not64, 3324 mkexpr( not_valid ) ), 3325 src ), 3326 binop( Iop_And64, 3327 mkexpr( not_valid ), 3328 binop( Iop_Or64, 3329 binop( Iop_And64, 3330 mkexpr( has_perm), 3331 binop( Iop_Shl64, 3332 mkexpr( value ), 3333 mkU8( 50 ) ) ), 3334 binop( Iop_And64, 3335 IRExpr_Get( OFFB_PPR, ty ), 3336 unop( Iop_Not64, 3337 mkexpr( has_perm ) 3338 ) ) ) ) ) ); 3339 3340 /* make sure we only set the valid bit field [52:50] */ 3341 stmt( IRStmt_Put( OFFB_PPR, 3342 binop( Iop_And64, 3343 mkexpr( new_src ), 3344 mkU64( 0x1C000000000000) ) ) ); 3345 break; 3346 } 3347 default: 3348 vex_printf("putGST(ppc): reg = %u", reg); 3349 vpanic("putGST(ppc)"); 3350 } 3351 } 3352 3353 /* Write masked src to the given reg */ 3354 static void putGST_masked ( PPC_GST reg, IRExpr* src, ULong mask ) 3355 { 3356 IRType ty = mode64 ? Ity_I64 : Ity_I32; 3357 vassert( reg < PPC_GST_MAX ); 3358 vassert( typeOfIRExpr( irsb->tyenv,src ) == Ity_I64 ); 3359 3360 switch (reg) { 3361 case PPC_GST_FPSCR: { 3362 /* Allow writes to either binary or decimal floating point 3363 Rounding Mode. 3364 */ 3365 /* If any part of |mask| covers FPSCR.RN, update the bits of 3366 FPSCR.RN by copying in |src| for locations where the 3367 corresponding bit in |mask| is 1, and leaving it unchanged 3368 for corresponding |mask| zero bits. */ 3369 if (mask & MASK_FPSCR_RN) { 3370 stmt( 3371 IRStmt_Put( 3372 OFFB_FPROUND, 3373 unop( 3374 Iop_32to8, 3375 binop( 3376 Iop_Or32, 3377 binop( 3378 Iop_And32, 3379 unop(Iop_64to32, src), 3380 mkU32(MASK_FPSCR_RN & mask) 3381 ), 3382 binop( 3383 Iop_And32, 3384 unop(Iop_8Uto32, IRExpr_Get(OFFB_FPROUND,Ity_I8)), 3385 mkU32(MASK_FPSCR_RN & ~mask) 3386 ) 3387 ) 3388 ) 3389 ) 3390 ); 3391 } 3392 3393 if (mask & MASK_FPSCR_C_FPCC) { 3394 /* FPCC bits are in [47:51] */ 3395 stmt( 3396 IRStmt_Put( 3397 OFFB_C_FPCC, 3398 unop( 3399 Iop_32to8, 3400 binop(Iop_Shr32, 3401 binop( 3402 Iop_Or32, 3403 binop( 3404 Iop_And32, 3405 unop(Iop_64to32, src), 3406 mkU32(MASK_FPSCR_C_FPCC & mask) ), 3407 binop( 3408 Iop_And32, 3409 unop(Iop_8Uto32, 3410 IRExpr_Get(OFFB_C_FPCC,Ity_I8)), 3411 mkU32(MASK_FPSCR_C_FPCC & ~mask) 3412 ) ), 3413 mkU8( 12 ) ) 3414 ) ) ); 3415 } 3416 3417 /* Similarly, update FPSCR.DRN if any bits of |mask| 3418 corresponding to FPSCR.DRN are set. */ 3419 if (mask & MASK_FPSCR_DRN) { 3420 stmt( 3421 IRStmt_Put( 3422 OFFB_DFPROUND, 3423 unop( 3424 Iop_32to8, 3425 binop( 3426 Iop_Or32, 3427 binop( 3428 Iop_And32, 3429 unop(Iop_64HIto32, src), 3430 mkU32((MASK_FPSCR_DRN & mask) >> 32) 3431 ), 3432 binop( 3433 Iop_And32, 3434 unop(Iop_8Uto32, IRExpr_Get(OFFB_DFPROUND,Ity_I8)), 3435 mkU32((MASK_FPSCR_DRN & ~mask) >> 32) 3436 ) 3437 ) 3438 ) 3439 ) 3440 ); 3441 } 3442 3443 /* Give EmNote for attempted writes to: 3444 - Exception Controls 3445 - Non-IEEE Mode 3446 */ 3447 if (mask & 0xFC) { // Exception Control, Non-IEE mode 3448 VexEmNote ew = EmWarn_PPCexns; 3449 3450 /* If any of the src::exception_control bits are actually set, 3451 side-exit to the next insn, reporting the warning, 3452 so that Valgrind's dispatcher sees the warning. */ 3453 putGST( PPC_GST_EMWARN, mkU32(ew) ); 3454 stmt( 3455 IRStmt_Exit( 3456 binop(Iop_CmpNE32, mkU32(ew), mkU32(EmNote_NONE)), 3457 Ijk_EmWarn, 3458 mkSzConst( ty, nextInsnAddr()), OFFB_CIA )); 3459 } 3460 3461 /* Ignore all other writes */ 3462 break; 3463 } 3464 3465 default: 3466 vex_printf("putGST_masked(ppc): reg = %u", reg); 3467 vpanic("putGST_masked(ppc)"); 3468 } 3469 } 3470 3471 /* Write the least significant nibble of src to the specified 3472 REG[FLD] (as per IBM/hardware notation). */ 3473 static void putGST_field ( PPC_GST reg, IRExpr* src, UInt fld ) 3474 { 3475 UInt shft; 3476 ULong mask; 3477 3478 vassert( typeOfIRExpr(irsb->tyenv,src ) == Ity_I32 ); 3479 vassert( fld < 16 ); 3480 vassert( reg < PPC_GST_MAX ); 3481 3482 if (fld < 8) 3483 shft = 4*(7-fld); 3484 else 3485 shft = 4*(15-fld); 3486 mask = 0xF; 3487 mask = mask << shft; 3488 3489 switch (reg) { 3490 case PPC_GST_CR: 3491 putCR0 (fld, binop(Iop_And8, mkU8(1 ), unop(Iop_32to8, src))); 3492 putCR321(fld, binop(Iop_And8, mkU8(7<<1), unop(Iop_32to8, src))); 3493 break; 3494 3495 default: 3496 { 3497 IRExpr * src64 = unop( Iop_32Uto64, src ); 3498 3499 if (shft == 0) { 3500 putGST_masked( reg, src64, mask ); 3501 } else { 3502 putGST_masked( reg, 3503 binop( Iop_Shl64, src64, mkU8( toUChar( shft ) ) ), 3504 mask ); 3505 } 3506 } 3507 } 3508 } 3509 3510 static void putFPCC ( IRExpr* e ) 3511 { 3512 /* The assumption is that the value of the FPCC are passed in the lower 3513 * four bits of a 32 bit value. 3514 * 3515 * Note, the C and FPCC bits which are a field of the FPSCR 3516 * register are stored in their own "register" in 3517 * memory. The FPCC bits are in the lower 4 bits. We don't need to 3518 * shift it to the bits to their location in the FPSCR register. Note, 3519 * not all of the FPSCR register bits are supported. We are writing all 3520 * of the bits in the FPCC field but not the C field. 3521 */ 3522 IRExpr* tmp; 3523 3524 vassert( typeOfIRExpr( irsb->tyenv, e ) == Ity_I32 ); 3525 /* Get the C bit field */ 3526 tmp = binop( Iop_And32, 3527 mkU32( 0x10 ), 3528 unop( Iop_8Uto32, IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ) ); 3529 3530 stmt( IRStmt_Put( OFFB_C_FPCC, 3531 unop( Iop_32to8, 3532 binop( Iop_Or32, tmp, 3533 binop( Iop_And32, mkU32( 0xF ), e ) ) ) ) ); 3534 3535 } 3536 3537 static IRExpr* /* ::Ity_I32 */ getC ( void ) 3538 { 3539 /* Note, the Floating-Point Result Class Descriptor (C) bit is a field of 3540 * the FPSCR registered are stored in its own "register" in guest state 3541 * with the FPCC bit field. C | FPCC 3542 */ 3543 IRTemp val = newTemp(Ity_I32); 3544 3545 assign( val, binop( Iop_Shr32, 3546 unop( Iop_8Uto32, IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ), 3547 mkU8( 4 ) ) ); 3548 return mkexpr(val); 3549 } 3550 3551 static IRExpr* /* ::Ity_I32 */ getFPCC ( void ) 3552 { 3553 /* Note, the FPCC bits are a field of the FPSCR 3554 * register are stored in their own "register" in 3555 * guest state with the C bit field. C | FPCC 3556 */ 3557 IRTemp val = newTemp( Ity_I32 ); 3558 3559 assign( val, binop( Iop_And32, unop( Iop_8Uto32, 3560 IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ), 3561 mkU32( 0xF ) )); 3562 return mkexpr(val); 3563 } 3564 3565 /*------------------------------------------------------------*/ 3566 /* Helpers for VSX instructions that do floating point 3567 * operations and need to determine if a src contains a 3568 * special FP value. 3569 * 3570 *------------------------------------------------------------*/ 3571 3572 #define NONZERO_FRAC_MASK 0x000fffffffffffffULL 3573 #define FP_FRAC_PART(x) binop( Iop_And64, \ 3574 mkexpr( x ), \ 3575 mkU64( NONZERO_FRAC_MASK ) ) 3576 3577 #define NONZERO_FRAC_MASK32 0x007fffffULL 3578 #define FP_FRAC_PART32(x) binop( Iop_And32, \ 3579 mkexpr( x ), \ 3580 mkU32( NONZERO_FRAC_MASK32 ) ) 3581 3582 // Returns exponent part of floating point src as I32 3583 static IRExpr * fp_exp_part( IRType size, IRTemp src ) 3584 { 3585 IRExpr *shift_by, *mask, *tsrc; 3586 3587 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 ) 3588 || ( size == Ity_I64 ) ); 3589 3590 if( size == Ity_I16 ) { 3591 /* The 16-bit floating point value is in the lower 16-bits 3592 * of the 32-bit input value. 3593 */ 3594 tsrc = mkexpr( src ); 3595 mask = mkU32( 0x1F ); 3596 shift_by = mkU8( 10 ); 3597 3598 } else if( size == Ity_I32 ) { 3599 tsrc = mkexpr( src ); 3600 mask = mkU32( 0xFF ); 3601 shift_by = mkU8( 23 ); 3602 3603 } else if( size == Ity_I64 ) { 3604 tsrc = unop( Iop_64HIto32, mkexpr( src ) ); 3605 mask = mkU32( 0x7FF ); 3606 shift_by = mkU8( 52 - 32 ); 3607 3608 } else { 3609 /*NOTREACHED*/ 3610 vassert(0); // Stops gcc complaining at "-Og" 3611 } 3612 3613 return binop( Iop_And32, binop( Iop_Shr32, tsrc, shift_by ), mask ); 3614 } 3615 3616 /* The following functions check the floating point value to see if it 3617 is zero, infinity, NaN, Normalized, Denormalized. 3618 */ 3619 /* 16-bit floating point number is stored in the lower 16-bits of 32-bit value */ 3620 #define I16_EXP_MASK 0x7C00 3621 #define I16_FRACTION_MASK 0x03FF 3622 #define I32_EXP_MASK 0x7F800000 3623 #define I32_FRACTION_MASK 0x007FFFFF 3624 #define I64_EXP_MASK 0x7FF0000000000000ULL 3625 #define I64_FRACTION_MASK 0x000FFFFFFFFFFFFFULL 3626 #define V128_EXP_MASK 0x7FFF000000000000ULL 3627 #define V128_FRACTION_MASK 0x0000FFFFFFFFFFFFULL /* upper 64-bit fractional mask */ 3628 3629 void setup_value_check_args( IRType size, IRTemp *exp_mask, IRTemp *frac_mask, 3630 IRTemp *zero ); 3631 3632 void setup_value_check_args( IRType size, IRTemp *exp_mask, IRTemp *frac_mask, 3633 IRTemp *zero ) { 3634 3635 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 ) 3636 || ( size == Ity_I64 ) || ( size == Ity_V128 ) ); 3637 3638 if( size == Ity_I16 ) { 3639 /* The 16-bit floating point value is in the lower 16-bits of 3640 the 32-bit input value */ 3641 *frac_mask = newTemp( Ity_I32 ); 3642 *exp_mask = newTemp( Ity_I32 ); 3643 *zero = newTemp( Ity_I32 ); 3644 assign( *exp_mask, mkU32( I16_EXP_MASK ) ); 3645 assign( *frac_mask, mkU32( I16_FRACTION_MASK ) ); 3646 assign( *zero, mkU32( 0 ) ); 3647 3648 } else if( size == Ity_I32 ) { 3649 *frac_mask = newTemp( Ity_I32 ); 3650 *exp_mask = newTemp( Ity_I32 ); 3651 *zero = newTemp( Ity_I32 ); 3652 assign( *exp_mask, mkU32( I32_EXP_MASK ) ); 3653 assign( *frac_mask, mkU32( I32_FRACTION_MASK ) ); 3654 assign( *zero, mkU32( 0 ) ); 3655 3656 } else if( size == Ity_I64 ) { 3657 *frac_mask = newTemp( Ity_I64 ); 3658 *exp_mask = newTemp( Ity_I64 ); 3659 *zero = newTemp( Ity_I64 ); 3660 assign( *exp_mask, mkU64( I64_EXP_MASK ) ); 3661 assign( *frac_mask, mkU64( I64_FRACTION_MASK ) ); 3662 assign( *zero, mkU64( 0 ) ); 3663 3664 } else { 3665 /* V128 is converted to upper and lower 64 bit values, */ 3666 /* uses 64-bit operators and temps */ 3667 *frac_mask = newTemp( Ity_I64 ); 3668 *exp_mask = newTemp( Ity_I64 ); 3669 *zero = newTemp( Ity_I64 ); 3670 assign( *exp_mask, mkU64( V128_EXP_MASK ) ); 3671 /* upper 64-bit fractional mask */ 3672 assign( *frac_mask, mkU64( V128_FRACTION_MASK ) ); 3673 assign( *zero, mkU64( 0 ) ); 3674 } 3675 } 3676 3677 /* Helper function for the various function which check the value of 3678 the floating point value. 3679 */ 3680 static IRExpr * exponent_compare( IRType size, IRTemp src, 3681 IRTemp exp_mask, IRExpr *exp_val ) 3682 { 3683 IROp opAND, opCmpEQ; 3684 3685 if( ( size == Ity_I16 ) || ( size == Ity_I32 ) ) { 3686 /* The 16-bit floating point value is in the lower 16-bits of 3687 the 32-bit input value */ 3688 opAND = Iop_And32; 3689 opCmpEQ = Iop_CmpEQ32; 3690 3691 } else { 3692 opAND = Iop_And64; 3693 opCmpEQ = Iop_CmpEQ64; 3694 } 3695 3696 if( size == Ity_V128 ) { 3697 return binop( opCmpEQ, 3698 binop ( opAND, 3699 unop( Iop_V128HIto64, mkexpr( src ) ), 3700 mkexpr( exp_mask ) ), 3701 exp_val ); 3702 3703 } else if( ( size == Ity_I16 ) || ( size == Ity_I32 ) ) { 3704 return binop( opCmpEQ, 3705 binop ( opAND, mkexpr( src ), mkexpr( exp_mask ) ), 3706 exp_val ); 3707 } else { 3708 /* 64-bit operands */ 3709 3710 if (mode64) { 3711 return binop( opCmpEQ, 3712 binop ( opAND, mkexpr( src ), mkexpr( exp_mask ) ), 3713 exp_val ); 3714 } else { 3715 /* No support for 64-bit compares in 32-bit mode, need to do upper 3716 * and lower parts using 32-bit compare operators. 3717 */ 3718 return 3719 mkAND1( binop( Iop_CmpEQ32, 3720 binop ( Iop_And32, 3721 unop(Iop_64HIto32, mkexpr( src ) ), 3722 unop(Iop_64HIto32, mkexpr( exp_mask ) ) ), 3723 unop(Iop_64HIto32, exp_val ) ), 3724 binop( Iop_CmpEQ32, 3725 binop ( Iop_And32, 3726 unop(Iop_64to32, mkexpr( src ) ), 3727 unop(Iop_64to32, mkexpr( exp_mask ) ) ), 3728 unop(Iop_64to32, exp_val ) ) ); 3729 } 3730 } 3731 } 3732 3733 static IRExpr *fractional_part_compare( IRType size, IRTemp src, 3734 IRTemp frac_mask, IRExpr *zero ) 3735 { 3736 IROp opAND, opCmpEQ; 3737 3738 if( ( size == Ity_I16 ) || ( size == Ity_I32 ) ) { 3739 /*The 16-bit floating point value is in the lower 16-bits of 3740 the 32-bit input value */ 3741 opAND = Iop_And32; 3742 opCmpEQ = Iop_CmpEQ32; 3743 3744 } else { 3745 opAND = Iop_And64; 3746 opCmpEQ = Iop_CmpEQ64; 3747 } 3748 3749 if( size == Ity_V128 ) { 3750 /* 128-bit, note we only care if the fractional part is zero so take upper 3751 52-bits of fractional part and lower 64-bits and OR them together and test 3752 for zero. This keeps the temp variables and operators all 64-bit. 3753 */ 3754 return binop( opCmpEQ, 3755 binop( Iop_Or64, 3756 binop( opAND, 3757 unop( Iop_V128HIto64, mkexpr( src ) ), 3758 mkexpr( frac_mask ) ), 3759 unop( Iop_V128to64, mkexpr( src ) ) ), 3760 zero ); 3761 3762 } else if( ( size == Ity_I16 ) || ( size == Ity_I32 ) ) { 3763 return binop( opCmpEQ, 3764 binop( opAND, mkexpr( src ), mkexpr( frac_mask ) ), 3765 zero ); 3766 } else { 3767 if (mode64) { 3768 return binop( opCmpEQ, 3769 binop( opAND, mkexpr( src ), mkexpr( frac_mask ) ), 3770 zero ); 3771 } else { 3772 /* No support for 64-bit compares in 32-bit mode, need to do upper 3773 * and lower parts using 32-bit compare operators. 3774 */ 3775 return 3776 mkAND1( binop( Iop_CmpEQ32, 3777 binop ( Iop_And32, 3778 unop(Iop_64HIto32, mkexpr( src ) ), 3779 unop(Iop_64HIto32, mkexpr( frac_mask ) ) ), 3780 mkU32 ( 0 ) ), 3781 binop( Iop_CmpEQ32, 3782 binop ( Iop_And32, 3783 unop(Iop_64to32, mkexpr( src ) ), 3784 unop(Iop_64to32, mkexpr( frac_mask ) ) ), 3785 mkU32 ( 0 ) ) ); 3786 } 3787 } 3788 } 3789 3790 // Infinity: exp has all bits set, and fraction is zero; s = 0/1 3791 static IRExpr * is_Inf( IRType size, IRTemp src ) 3792 { 3793 IRExpr *max_exp, *zero_frac; 3794 IRTemp exp_mask, frac_mask, zero; 3795 3796 setup_value_check_args( size, &exp_mask, &frac_mask, &zero ); 3797 3798 /* check exponent is all ones, i.e. (exp AND exp_mask) = exp_mask */ 3799 max_exp = exponent_compare( size, src, exp_mask, mkexpr( exp_mask ) ); 3800 3801 /* check fractional part is all zeros */ 3802 zero_frac = fractional_part_compare( size, src, frac_mask, mkexpr( zero ) ); 3803 3804 return mkAND1( max_exp, zero_frac ); 3805 } 3806 3807 // Zero: exp is zero and fraction is zero; s = 0/1 3808 static IRExpr * is_Zero( IRType size, IRTemp src ) 3809 { 3810 IRExpr *zero_exp, *zero_frac; 3811 IRTemp exp_mask, frac_mask, zero; 3812 3813 setup_value_check_args( size, &exp_mask, &frac_mask, &zero ); 3814 3815 /* check the exponent is all zeros, i.e. (exp AND exp_mask) = zero */ 3816 zero_exp = exponent_compare( size, src, exp_mask, mkexpr( zero ) ); 3817 3818 /* check fractional part is all zeros */ 3819 zero_frac = fractional_part_compare( size, src, frac_mask, mkexpr( zero ) ); 3820 3821 return mkAND1( zero_exp, zero_frac ); 3822 } 3823 3824 /* SNAN: s = 1/0; exp all 1's; fraction is nonzero, with highest bit '1' 3825 * QNAN: s = 1/0; exp all 1's; fraction is nonzero, with highest bit '0' 3826 */ 3827 static IRExpr * is_NaN( IRType size, IRTemp src ) 3828 { 3829 IRExpr *max_exp, *not_zero_frac; 3830 IRTemp exp_mask, frac_mask, zero; 3831 3832 setup_value_check_args( size, &exp_mask, &frac_mask, &zero ); 3833 3834 /* check exponent is all ones, i.e. (exp AND exp_mask) = exp_mask */ 3835 max_exp = exponent_compare( size, src, exp_mask, mkexpr( exp_mask ) ); 3836 3837 /* check fractional part is not zero */ 3838 not_zero_frac = unop( Iop_Not1, 3839 fractional_part_compare( size, src, frac_mask, 3840 mkexpr( zero ) ) ); 3841 3842 return mkAND1( max_exp, not_zero_frac ); 3843 } 3844 3845 /* Denormalized number has a zero exponent and non zero fraction. */ 3846 static IRExpr * is_Denorm( IRType size, IRTemp src ) 3847 { 3848 IRExpr *zero_exp, *not_zero_frac; 3849 IRTemp exp_mask, frac_mask, zero; 3850 3851 setup_value_check_args( size, &exp_mask, &frac_mask, &zero ); 3852 3853 /* check exponent is all ones, i.e. (exp AND exp_mask) = exp_mask */ 3854 zero_exp = exponent_compare( size, src, exp_mask, mkexpr( zero ) ); 3855 3856 /* check fractional part is not zero */ 3857 not_zero_frac = unop( Iop_Not1, 3858 fractional_part_compare( size, src, frac_mask, 3859 mkexpr( zero ) ) ); 3860 3861 return mkAND1( zero_exp, not_zero_frac ); 3862 } 3863 3864 /* Normalized number has exponent between 1 and max_exp -1, or in other words 3865 the exponent is not zero and not equal to the max exponent value. */ 3866 static IRExpr * is_Norm( IRType size, IRTemp src ) 3867 { 3868 IRExpr *not_zero_exp, *not_max_exp; 3869 IRTemp exp_mask, zero; 3870 3871 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 ) 3872 || ( size == Ity_I64 ) || ( size == Ity_V128 ) ); 3873 3874 if( size == Ity_I16 ) { 3875 /* The 16-bit floating point value is in the lower 16-bits of 3876 the 32-bit input value */ 3877 exp_mask = newTemp( Ity_I32 ); 3878 zero = newTemp( Ity_I32 ); 3879 assign( exp_mask, mkU32( I16_EXP_MASK ) ); 3880 assign( zero, mkU32( 0 ) ); 3881 3882 } else if( size == Ity_I32 ) { 3883 exp_mask = newTemp( Ity_I32 ); 3884 zero = newTemp( Ity_I32 ); 3885 assign( exp_mask, mkU32( I32_EXP_MASK ) ); 3886 assign( zero, mkU32( 0 ) ); 3887 3888 } else if( size == Ity_I64 ) { 3889 exp_mask = newTemp( Ity_I64 ); 3890 zero = newTemp( Ity_I64 ); 3891 assign( exp_mask, mkU64( I64_EXP_MASK ) ); 3892 assign( zero, mkU64( 0 ) ); 3893 3894 } else { 3895 /* V128 is converted to upper and lower 64 bit values, */ 3896 /* uses 64-bit operators and temps */ 3897 exp_mask = newTemp( Ity_I64 ); 3898 zero = newTemp( Ity_I64 ); 3899 assign( exp_mask, mkU64( V128_EXP_MASK ) ); 3900 assign( zero, mkU64( 0 ) ); 3901 } 3902 3903 not_zero_exp = unop( Iop_Not1, 3904 exponent_compare( size, src, 3905 exp_mask, mkexpr( zero ) ) ); 3906 not_max_exp = unop( Iop_Not1, 3907 exponent_compare( size, src, 3908 exp_mask, mkexpr( exp_mask ) ) ); 3909 3910 return mkAND1( not_zero_exp, not_max_exp ); 3911 } 3912 3913 3914 static IRExpr * create_FPCC( IRTemp NaN, IRTemp inf, 3915 IRTemp zero, IRTemp norm, 3916 IRTemp dnorm, IRTemp pos, 3917 IRTemp neg ) { 3918 IRExpr *bit0, *bit1, *bit2, *bit3; 3919 3920 /* If the result is NaN then must force bits 1, 2 and 3 to zero 3921 * to get correct result. 3922 */ 3923 bit0 = unop( Iop_1Uto32, mkOR1( mkexpr( NaN ), mkexpr( inf ) ) ); 3924 bit1 = unop( Iop_1Uto32, mkAND1( mkNOT1( mkexpr( NaN ) ), mkexpr( zero ) ) ); 3925 bit2 = unop( Iop_1Uto32, 3926 mkAND1( mkNOT1( mkexpr( NaN ) ), 3927 mkAND1( mkOR1( mkOR1( mkAND1( mkexpr( pos ), 3928 mkexpr( dnorm ) ), 3929 mkAND1( mkexpr( pos ), 3930 mkexpr( norm ) ) ), 3931 mkAND1( mkexpr( pos ), 3932 mkexpr( inf ) ) ), 3933 mkAND1( mkNOT1 ( mkexpr( zero ) ), 3934 mkNOT1( mkexpr( NaN ) ) ) ) ) ); 3935 bit3 = unop( Iop_1Uto32, 3936 mkAND1( mkNOT1( mkexpr( NaN ) ), 3937 mkAND1( mkOR1( mkOR1( mkAND1( mkexpr( neg ), 3938 mkexpr( dnorm ) ), 3939 mkAND1( mkexpr( neg ), 3940 mkexpr( norm ) ) ), 3941 mkAND1( mkexpr( neg ), 3942 mkexpr( inf ) ) ), 3943 mkAND1( mkNOT1 ( mkexpr( zero ) ), 3944 mkNOT1( mkexpr( NaN ) ) ) ) ) ); 3945 3946 return binop( Iop_Or32, 3947 binop( Iop_Or32, 3948 bit0, 3949 binop( Iop_Shl32, bit1, mkU8( 1 ) ) ), 3950 binop( Iop_Or32, 3951 binop( Iop_Shl32, bit2, mkU8( 2 ) ), 3952 binop( Iop_Shl32, bit3, mkU8( 3 ) ) ) ); 3953 } 3954 3955 static IRExpr * create_C( IRTemp NaN, IRTemp zero, 3956 IRTemp dnorm, IRTemp pos, 3957 IRTemp neg ) 3958 { 3959 3960 return unop( Iop_1Uto32, 3961 mkOR1( mkOR1( mkexpr( NaN ), 3962 mkAND1( mkexpr( neg ), mkexpr( dnorm ) ) ), 3963 mkOR1( mkAND1( mkexpr( neg ), mkexpr( zero ) ), 3964 mkAND1( mkexpr( pos ), mkexpr( dnorm ) ) ) ) ); 3965 } 3966 3967 static void generate_store_FPRF( IRType size, IRTemp src ) 3968 { 3969 IRExpr *FPCC, *C; 3970 IRTemp NaN = newTemp( Ity_I1 ), inf = newTemp( Ity_I1 ); 3971 IRTemp dnorm = newTemp( Ity_I1 ), norm = newTemp( Ity_I1 ); 3972 IRTemp pos = newTemp( Ity_I1 ), neg = newTemp( Ity_I1 ); 3973 IRTemp zero = newTemp( Ity_I1 ); 3974 3975 IRTemp sign_bit = newTemp( Ity_I1 ); 3976 IRTemp value; 3977 3978 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 ) 3979 || ( size == Ity_I64 ) || ( size == Ity_F128 ) ); 3980 3981 vassert( ( typeOfIRExpr(irsb->tyenv, mkexpr( src ) ) == Ity_I32 ) 3982 || ( typeOfIRExpr(irsb->tyenv, mkexpr( src ) ) == Ity_I64 ) 3983 || ( typeOfIRExpr(irsb->tyenv, mkexpr( src ) ) == Ity_F128 ) ); 3984 3985 if( size == Ity_I16 ) { 3986 /* The 16-bit floating point value is in the lower 16-bits of 3987 the 32-bit input value */ 3988 value = newTemp( Ity_I32 ); 3989 assign( value, mkexpr( src ) ); 3990 assign( sign_bit, 3991 unop ( Iop_32to1, 3992 binop( Iop_And32, 3993 binop( Iop_Shr32, mkexpr( value ), mkU8( 15 ) ), 3994 mkU32( 0x1 ) ) ) ); 3995 3996 } else if( size == Ity_I32 ) { 3997 value = newTemp( size ); 3998 assign( value, mkexpr( src ) ); 3999 assign( sign_bit, 4000 unop ( Iop_32to1, 4001 binop( Iop_And32, 4002 binop( Iop_Shr32, mkexpr( value ), mkU8( 31 ) ), 4003 mkU32( 0x1 ) ) ) ); 4004 4005 } else if( size == Ity_I64 ) { 4006 value = newTemp( size ); 4007 assign( value, mkexpr( src ) ); 4008 assign( sign_bit, 4009 unop ( Iop_64to1, 4010 binop( Iop_And64, 4011 binop( Iop_Shr64, mkexpr( value ), mkU8( 63 ) ), 4012 mkU64( 0x1 ) ) ) ); 4013 4014 } else { 4015 /* Move the F128 bit pattern to an integer V128 bit pattern */ 4016 value = newTemp( Ity_V128 ); 4017 assign( value, 4018 binop( Iop_64HLtoV128, 4019 unop( Iop_ReinterpF64asI64, 4020 unop( Iop_F128HItoF64, mkexpr( src ) ) ), 4021 unop( Iop_ReinterpF64asI64, 4022 unop( Iop_F128LOtoF64, mkexpr( src ) ) ) ) ); 4023 4024 size = Ity_V128; 4025 assign( sign_bit, 4026 unop ( Iop_64to1, 4027 binop( Iop_And64, 4028 binop( Iop_Shr64, 4029 unop( Iop_V128HIto64, mkexpr( value ) ), 4030 mkU8( 63 ) ), 4031 mkU64( 0x1 ) ) ) ); 4032 } 4033 4034 /* Calculate the floating point result field FPRF */ 4035 assign( NaN, is_NaN( size, value ) ); 4036 assign( inf, is_Inf( size, value ) ); 4037 assign( zero, is_Zero( size, value ) ); 4038 assign( norm, is_Norm( size, value ) ); 4039 assign( dnorm, is_Denorm( size, value ) ); 4040 assign( pos, mkAND1( mkNOT1( mkexpr( sign_bit ) ), mkU1( 1 ) ) ); 4041 assign( neg, mkAND1( mkexpr( sign_bit ), mkU1( 1 ) ) ); 4042 4043 /* create the FPRF bit field 4044 * 4045 * FPRF field[4:0] type of value 4046 * 10001 QNaN 4047 * 01001 - infininity 4048 * 01000 - Normalized 4049 * 11000 - Denormalized 4050 * 10010 - zero 4051 * 00010 + zero 4052 * 10100 + Denormalized 4053 * 00100 + Normalized 4054 * 00101 + infinity 4055 */ 4056 FPCC = create_FPCC( NaN, inf, zero, norm, dnorm, pos, neg ); 4057 C = create_C( NaN, zero, dnorm, pos, neg ); 4058 4059 /* Write the C and FPCC fields of the FPRF field */ 4060 putC( C ); 4061 putFPCC( FPCC ); 4062 } 4063 4064 /* This function takes an Ity_I32 input argument interpreted 4065 as a single-precision floating point value. If src is a 4066 SNaN, it is changed to a QNaN and returned; otherwise, 4067 the original value is returned. */ 4068 static IRExpr * handle_SNaN_to_QNaN_32(IRExpr * src) 4069 { 4070 #define SNAN_MASK32 0x00400000 4071 IRTemp tmp = newTemp(Ity_I32); 4072 IRTemp mask = newTemp(Ity_I32); 4073 IRTemp is_SNAN = newTemp(Ity_I1); 4074 4075 vassert( typeOfIRExpr(irsb->tyenv, src ) == Ity_I32 ); 4076 assign(tmp, src); 4077 4078 /* check if input is SNaN, if it is convert to QNaN */ 4079 assign( is_SNAN, 4080 mkAND1( is_NaN( Ity_I32, tmp ), 4081 binop( Iop_CmpEQ32, 4082 binop( Iop_And32, mkexpr( tmp ), 4083 mkU32( SNAN_MASK32 ) ), 4084 mkU32( 0 ) ) ) ); 4085 /* create mask with QNaN bit set to make it a QNaN if tmp is SNaN */ 4086 assign ( mask, binop( Iop_And32, 4087 unop( Iop_1Sto32, mkexpr( is_SNAN ) ), 4088 mkU32( SNAN_MASK32 ) ) ); 4089 return binop( Iop_Or32, mkexpr( mask ), mkexpr( tmp) ); 4090 } 4091 4092 4093 /* This helper function performs the negation part of operations of the form: 4094 * "Negate Multiply-<op>" 4095 * where "<op>" is either "Add" or "Sub". 4096 * 4097 * This function takes one argument -- the floating point intermediate result (converted to 4098 * Ity_I64 via Iop_ReinterpF64asI64) that was obtained from the "Multip-<op>" part of 4099 * the operation described above. 4100 */ 4101 static IRTemp getNegatedResult(IRTemp intermediateResult) 4102 { 4103 ULong signbit_mask = 0x8000000000000000ULL; 4104 IRTemp signbit_32 = newTemp(Ity_I32); 4105 IRTemp resultantSignbit = newTemp(Ity_I1); 4106 IRTemp negatedResult = newTemp(Ity_I64); 4107 assign( signbit_32, binop( Iop_Shr32, 4108 unop( Iop_64HIto32, 4109 binop( Iop_And64, mkexpr( intermediateResult ), 4110 mkU64( signbit_mask ) ) ), 4111 mkU8( 31 ) ) ); 4112 /* We negate the signbit if and only if the intermediate result from the 4113 * multiply-<op> was NOT a NaN. This is an XNOR predicate. 4114 */ 4115 assign( resultantSignbit, 4116 unop( Iop_Not1, 4117 binop( Iop_CmpEQ32, 4118 binop( Iop_Xor32, 4119 mkexpr( signbit_32 ), 4120 unop( Iop_1Uto32, is_NaN( Ity_I64, 4121 intermediateResult ) ) ), 4122 mkU32( 1 ) ) ) ); 4123 4124 assign( negatedResult, 4125 binop( Iop_Or64, 4126 binop( Iop_And64, 4127 mkexpr( intermediateResult ), 4128 mkU64( ~signbit_mask ) ), 4129 binop( Iop_32HLto64, 4130 binop( Iop_Shl32, 4131 unop( Iop_1Uto32, mkexpr( resultantSignbit ) ), 4132 mkU8( 31 ) ), 4133 mkU32( 0 ) ) ) ); 4134 4135 return negatedResult; 4136 } 4137 4138 /* This helper function performs the negation part of operations of the form: 4139 * "Negate Multiply-<op>" 4140 * where "<op>" is either "Add" or "Sub". 4141 * 4142 * This function takes one argument -- the floating point intermediate result (converted to 4143 * Ity_I32 via Iop_ReinterpF32asI32) that was obtained from the "Multip-<op>" part of 4144 * the operation described above. 4145 */ 4146 static IRTemp getNegatedResult_32(IRTemp intermediateResult) 4147 { 4148 UInt signbit_mask = 0x80000000; 4149 IRTemp signbit_32 = newTemp(Ity_I32); 4150 IRTemp resultantSignbit = newTemp(Ity_I1); 4151 IRTemp negatedResult = newTemp(Ity_I32); 4152 assign( signbit_32, binop( Iop_Shr32, 4153 binop( Iop_And32, mkexpr( intermediateResult ), 4154 mkU32( signbit_mask ) ), 4155 mkU8( 31 ) ) ); 4156 /* We negate the signbit if and only if the intermediate result from the 4157 * multiply-<op> was NOT a NaN. This is an XNOR predicate. 4158 */ 4159 assign( resultantSignbit, 4160 unop( Iop_Not1, 4161 binop( Iop_CmpEQ32, 4162 binop( Iop_Xor32, 4163 mkexpr( signbit_32 ), 4164 unop( Iop_1Uto32, is_NaN( Ity_I32, 4165 intermediateResult ) ) ), 4166 mkU32( 1 ) ) ) ); 4167 4168 assign( negatedResult, 4169 binop( Iop_Or32, 4170 binop( Iop_And32, 4171 mkexpr( intermediateResult ), 4172 mkU32( ~signbit_mask ) ), 4173 binop( Iop_Shl32, 4174 unop( Iop_1Uto32, mkexpr( resultantSignbit ) ), 4175 mkU8( 31 ) ) ) ); 4176 4177 return negatedResult; 4178 } 4179 4180 /* This function takes two quad_precision floating point numbers of type 4181 V128 and return 1 if src_A > src_B, 0 otherwise. */ 4182 static IRExpr * Quad_precision_gt ( IRTemp src_A, IRTemp src_B ) 4183 { 4184 #define FRAC_MASK64Hi 0x0000ffffffffffffULL 4185 #define MASK 0x7FFFFFFFFFFFFFFFULL /* exclude sign bit in upper 64 bits */ 4186 #define EXP_MASK 0x7fff 4187 4188 IRType ty = Ity_I64; 4189 IRTemp sign_A = newTemp( ty ); 4190 IRTemp sign_B = newTemp( ty ); 4191 IRTemp exp_A = newTemp( ty ); 4192 IRTemp exp_B = newTemp( ty ); 4193 IRTemp frac_A_hi = newTemp( ty ); 4194 IRTemp frac_B_hi = newTemp( ty ); 4195 IRTemp frac_A_lo = newTemp( ty ); 4196 IRTemp frac_B_lo = newTemp( ty ); 4197 4198 4199 /* extract exponents, and fractional parts so they can be compared */ 4200 assign( sign_A, binop( Iop_Shr64, 4201 unop( Iop_V128HIto64, mkexpr( src_A ) ), 4202 mkU8( 63 ) ) ); 4203 assign( sign_B, binop( Iop_Shr64, 4204 unop( Iop_V128HIto64, mkexpr( src_B ) ), 4205 mkU8( 63 ) ) ); 4206 assign( exp_A, binop( Iop_And64, 4207 binop( Iop_Shr64, 4208 unop( Iop_V128HIto64, mkexpr( src_A ) ), 4209 mkU8( 48 ) ), 4210 mkU64( EXP_MASK ) ) ); 4211 assign( exp_B, binop( Iop_And64, 4212 binop( Iop_Shr64, 4213 unop( Iop_V128HIto64, mkexpr( src_B ) ), 4214 mkU8( 48 ) ), 4215 mkU64( EXP_MASK ) ) ); 4216 assign( frac_A_hi, binop( Iop_And64, 4217 unop( Iop_V128HIto64, mkexpr( src_A ) ), 4218 mkU64( FRAC_MASK64Hi ) ) ); 4219 assign( frac_B_hi, binop( Iop_And64, 4220 unop( Iop_V128HIto64, mkexpr( src_B ) ), 4221 mkU64( FRAC_MASK64Hi ) ) ); 4222 assign( frac_A_lo, unop( Iop_V128to64, mkexpr( src_A ) ) ); 4223 assign( frac_B_lo, unop( Iop_V128to64, mkexpr( src_B ) ) ); 4224 4225 IRExpr * A_zero = mkAND1( binop( Iop_CmpEQ64, 4226 binop( Iop_And64, 4227 unop( Iop_V128HIto64, 4228 mkexpr( src_A ) ), 4229 mkU64( MASK ) ), 4230 mkU64( 0 ) ), 4231 binop( Iop_CmpEQ64, 4232 unop( Iop_V128to64, mkexpr( src_A ) ), 4233 mkU64( 0 ) ) ); 4234 IRExpr * B_zero = mkAND1( binop( Iop_CmpEQ64, 4235 binop( Iop_And64, 4236 unop( Iop_V128HIto64, 4237 mkexpr( src_B ) ), 4238 mkU64( MASK ) ), 4239 mkU64( 0 ) ), 4240 binop( Iop_CmpEQ64, 4241 unop( Iop_V128to64, mkexpr( src_B ) ), 4242 mkU64( 0 ) ) ); 4243 IRExpr * A_B_zero = mkAND1( A_zero, B_zero ); 4244 4245 /* Compare numbers */ 4246 IRExpr * both_pos = mkAND1( binop( Iop_CmpEQ64, mkexpr( sign_A ), 4247 mkU64( 0 ) ), 4248 binop( Iop_CmpEQ64, mkexpr( sign_B ), 4249 mkU64( 0 ) ) ); 4250 IRExpr * both_neg = mkAND1( binop( Iop_CmpEQ64, mkexpr( sign_A ), 4251 mkU64( 1 ) ), 4252 binop( Iop_CmpEQ64, mkexpr( sign_B ), 4253 mkU64( 1 ) ) ); 4254 IRExpr * sign_eq = binop( Iop_CmpEQ64, mkexpr( sign_A ), mkexpr( sign_B ) ); 4255 IRExpr * sign_gt = binop( Iop_CmpLT64U, mkexpr( sign_A ), 4256 mkexpr( sign_B ) ); /* A pos, B neg */ 4257 4258 IRExpr * exp_eq = binop( Iop_CmpEQ64, mkexpr( exp_A ), mkexpr( exp_B ) ); 4259 IRExpr * exp_gt = binop( Iop_CmpLT64U, mkexpr( exp_B ), mkexpr( exp_A ) ); 4260 IRExpr * exp_lt = binop( Iop_CmpLT64U, mkexpr( exp_A ), mkexpr( exp_B ) ); 4261 4262 IRExpr * frac_hi_eq = binop( Iop_CmpEQ64, mkexpr( frac_A_hi), 4263 mkexpr( frac_B_hi ) ); 4264 IRExpr * frac_hi_gt = binop( Iop_CmpLT64U, mkexpr( frac_B_hi ), 4265 mkexpr( frac_A_hi ) ); 4266 IRExpr * frac_hi_lt = binop( Iop_CmpLT64U, mkexpr( frac_A_hi ), 4267 mkexpr( frac_B_hi ) ); 4268 4269 IRExpr * frac_lo_gt = binop( Iop_CmpLT64U, mkexpr( frac_B_lo ), 4270 mkexpr( frac_A_lo ) ); 4271 IRExpr * frac_lo_lt = binop( Iop_CmpLT64U, mkexpr( frac_A_lo ), 4272 mkexpr( frac_B_lo ) ); 4273 4274 /* src_A and src_B both positive */ 4275 IRExpr *pos_cmp = mkOR1( exp_gt, 4276 mkAND1( exp_eq, 4277 mkOR1( frac_hi_gt, 4278 mkAND1( frac_hi_eq, frac_lo_gt ) ) 4279 ) ); 4280 4281 /* src_A and src_B both negative */ 4282 IRExpr *neg_cmp = mkOR1( exp_lt, 4283 mkAND1( exp_eq, 4284 mkOR1( frac_hi_lt, 4285 mkAND1( frac_hi_eq, frac_lo_lt ) ) 4286 ) ); 4287 4288 /* Need to check the case where one value is a positive 4289 * zero and the other value is a negative zero 4290 */ 4291 return mkAND1( mkNOT1( A_B_zero ), 4292 mkOR1( sign_gt, 4293 mkAND1( sign_eq, 4294 mkOR1( mkAND1( both_pos, pos_cmp ), 4295 mkAND1( both_neg, neg_cmp ) ) ) ) ); 4296 } 4297 4298 /*----------------------------------------------------------- 4299 * Helpers for VX instructions that work on National decimal values, 4300 * Zoned decimal values and BCD values. 4301 * 4302 *------------------------------------------------------------*/ 4303 static IRExpr * is_National_decimal (IRTemp src) 4304 { 4305 /* The src is a 128-bit value containing a sign code in half word 7 4306 * and seven digits in halfwords 0 to 6 (IBM numbering). A valid 4307 * national decimal value has the following: 4308 * - the sign code must be 0x002B (positive) or 0x002D (negative) 4309 * - the digits must be in the range 0x0030 to 0x0039 4310 */ 4311 Int i; 4312 IRExpr * valid_pos_sign; 4313 IRExpr * valid_neg_sign; 4314 IRTemp valid_num[8]; 4315 IRTemp digit[7]; 4316 4317 valid_pos_sign = binop( Iop_CmpEQ64, 4318 binop( Iop_And64, 4319 mkU64( 0xFFFF ), 4320 unop( Iop_V128to64, mkexpr( src ) ) ), 4321 mkU64( 0x002B ) ); 4322 4323 valid_neg_sign = binop( Iop_CmpEQ64, 4324 binop( Iop_And64, 4325 mkU64( 0xFFFF ), 4326 unop( Iop_V128to64, mkexpr( src ) ) ), 4327 mkU64( 0x002D ) ); 4328 4329 valid_num[0] = newTemp( Ity_I1 ); 4330 digit[0] = newTemp( Ity_I64 ); 4331 assign( valid_num[0], mkU1( 1 ) ); // Assume true to start 4332 4333 for(i = 0; i < 7; i++) { 4334 valid_num[i+1] = newTemp( Ity_I1 ); 4335 digit[i] = newTemp( Ity_I64 ); 4336 assign( digit[i], binop( Iop_And64, 4337 unop( Iop_V128to64, 4338 binop( Iop_ShrV128, 4339 mkexpr( src ), 4340 mkU8( (7-i)*16 ) ) ), 4341 mkU64( 0xFFFF ) ) ); 4342 4343 assign( valid_num[i+1], 4344 mkAND1( mkexpr( valid_num[i] ), 4345 mkAND1( binop( Iop_CmpLE64U, 4346 mkexpr( digit[i] ), 4347 mkU64( 0x39 ) ), 4348 binop( Iop_CmpLE64U, 4349 mkU64( 0x30 ), 4350 mkexpr( digit[i] ) ) ) ) ); 4351 } 4352 4353 return mkAND1( mkOR1( valid_pos_sign, valid_neg_sign), 4354 mkexpr( valid_num[7] ) ); 4355 } 4356 4357 static IRExpr * is_Zoned_decimal (IRTemp src, UChar ps) 4358 { 4359 /* The src is a 128-bit value containing a sign code the least significant 4360 * two bytes. The upper pairs of bytes contain digits. A valid Zoned 4361 * decimal value has the following: 4362 * - the sign code must be between 0x0X to 0xFX inclusive (X - don't care) 4363 * - bits [0:3] of each digit must be equal to 0x3 4364 * - bits [4:7] of each digit must be between 0x0 and 0x9 4365 * 4366 * If ps = 0 4367 * Positive sign codes are: 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xA, 0xB 4368 * (note 0bX0XX XXXX is positive) 4369 * 4370 * Negative sign codes are 0x4, 0x5, 0x6, 0x7, 0xC, 0xD, 0xE, 0xF 4371 * (note 0bX1XX XXXX is negative) 4372 * 4373 * If ps = 1, then the sign code must be in the range 0xA to 0xF 4374 * Positive sign codes are: 0xA, 0xC, 0xE, 0xF 4375 * 4376 * Negative sign codes are 0xB, 0xD 4377 */ 4378 Int i, mask_hi, mask_lo; 4379 IRExpr *valid_range; 4380 IRTemp valid_num[16]; 4381 IRTemp digit[15]; 4382 4383 /* check the range of the sign value based on the value of ps */ 4384 valid_range = mkOR1( 4385 mkAND1( binop( Iop_CmpEQ64, 4386 mkU64( 1 ), 4387 mkU64( ps ) ), 4388 mkAND1( binop( Iop_CmpLE64U, 4389 binop( Iop_And64, 4390 mkU64( 0xF0 ), 4391 unop( Iop_V128to64, 4392 mkexpr( src ) ) ), 4393 4394 mkU64( 0xF0 ) ), 4395 binop( Iop_CmpLE64U, 4396 mkU64( 0xA0 ), 4397 binop( Iop_And64, 4398 mkU64( 0xF0 ), 4399 unop( Iop_V128to64, 4400 mkexpr( src ) ))))), 4401 binop( Iop_CmpEQ64, 4402 mkU64( 0 ), 4403 mkU64( ps ) ) ); 4404 4405 valid_num[0] = newTemp( Ity_I1 ); 4406 assign( valid_num[0], mkU1( 1) ); // Assume true to start 4407 4408 if (ps == 0) { 4409 mask_hi = 0x39; 4410 mask_lo = 0x30; 4411 } else { 4412 mask_hi = 0xF9; 4413 mask_lo = 0xF0; 4414 } 4415 4416 for(i = 0; i < 15; i++) { 4417 valid_num[i+1] = newTemp( Ity_I1 ); 4418 digit[i] = newTemp( Ity_I64 ); 4419 assign( digit[i], binop( Iop_And64, 4420 unop( Iop_V128to64, 4421 binop( Iop_ShrV128, 4422 mkexpr( src ), 4423 mkU8( (15-i)*8 ) ) ), 4424 mkU64( 0xFF ) ) ); 4425 4426 assign( valid_num[i+1], 4427 mkAND1( mkexpr( valid_num[i] ), 4428 mkAND1( binop( Iop_CmpLE64U, 4429 mkexpr( digit[i] ), 4430 mkU64( mask_hi ) ), 4431 binop( Iop_CmpLE64U, 4432 mkU64( mask_lo ), 4433 mkexpr( digit[i] ) ) ) ) ); 4434 } 4435 4436 return mkAND1( valid_range, mkexpr( valid_num[15] ) ); 4437 } 4438 4439 static IRExpr * CmpGT128U ( IRExpr *src1, IRExpr *src2 ) 4440 { 4441 /* Unsigend compare of two 128-bit values */ 4442 IRExpr *pos_upper_gt, *pos_upper_eq, *pos_lower_gt; 4443 4444 pos_upper_gt = binop( Iop_CmpLT64U, 4445 unop( Iop_V128HIto64, src2 ), 4446 unop( Iop_V128HIto64, src1 ) ); 4447 pos_upper_eq = binop( Iop_CmpEQ64, 4448 unop( Iop_V128HIto64, src1 ), 4449 unop( Iop_V128HIto64, src2 ) ); 4450 pos_lower_gt = binop( Iop_CmpLT64U, 4451 unop( Iop_V128to64, src2), 4452 unop( Iop_V128to64, src1) ); 4453 return mkOR1( pos_upper_gt, 4454 mkAND1( pos_upper_eq, 4455 pos_lower_gt ) ); 4456 } 4457 4458 4459 static IRExpr * is_BCDstring128 ( const VexAbiInfo* vbi, 4460 UInt Signed, IRExpr *src ) 4461 { 4462 4463 IRTemp valid = newTemp( Ity_I64 ); 4464 4465 /* The src is a 128-bit value containing a MAX_DIGITS BCD digits and 4466 * a sign. The upper bytes are BCD values between 0x0 and 0x9. The sign 4467 * byte is the least significant byte. This function returns 64-bit 1 4468 * value if sign and digits are valid, 0 otherwise. 4469 * 4470 * This function was originally written using IR code. It has been 4471 * replaced with a clean helper due to the large amount of IR code 4472 * needed by this function. 4473 */ 4474 assign( valid, 4475 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4476 "is_BCDstring128_helper", 4477 fnptr_to_fnentry( vbi, &is_BCDstring128_helper ), 4478 mkIRExprVec_3( mkU64( Signed ), 4479 unop( Iop_V128HIto64, src ), 4480 unop( Iop_V128to64, src ) ) ) ); 4481 return mkexpr( valid ); 4482 } 4483 4484 static IRExpr * BCDstring_zero (IRExpr *src) 4485 { 4486 /* The src is a 128-bit value containing a BCD string. The function 4487 * returns a 1 if the BCD string values are all zero, 0 otherwise. 4488 */ 4489 IRTemp tsrc = newTemp( Ity_V128 ); 4490 assign( tsrc, src); 4491 4492 if ( mode64 ) { 4493 return mkAND1( binop( Iop_CmpEQ64, 4494 mkU64( 0 ), 4495 unop( Iop_V128HIto64, 4496 mkexpr( tsrc ) ) ), 4497 binop( Iop_CmpEQ64, 4498 mkU64( 0 ), 4499 unop( Iop_V128to64, 4500 mkexpr( tsrc ) ) ) ); 4501 } else { 4502 /* make this work in 32-bit mode */ 4503 return mkAND1( 4504 mkAND1( binop( Iop_CmpEQ32, 4505 mkU32( 0 ), 4506 unop( Iop_64HIto32, 4507 unop( Iop_V128HIto64, 4508 mkexpr( tsrc ) ) ) ), 4509 binop( Iop_CmpEQ32, 4510 mkU32( 0 ), 4511 unop( Iop_64to32, 4512 unop( Iop_V128HIto64, 4513 mkexpr( tsrc ) ) ) ) ), 4514 mkAND1( binop( Iop_CmpEQ32, 4515 mkU32( 0 ), 4516 unop( Iop_64HIto32, 4517 unop( Iop_V128to64, 4518 mkexpr( tsrc ) ) ) ), 4519 binop( Iop_CmpEQ32, 4520 mkU32( 0 ), 4521 unop( Iop_64to32, 4522 unop( Iop_V128to64, 4523 mkexpr( tsrc ) ) ) ) ) ); 4524 } 4525 } 4526 4527 static IRExpr * check_BCD_round (IRExpr *src, IRTemp shift) 4528 { 4529 /* The src is a 128-bit value containing 31 BCD digits with the sign in 4530 * the least significant byte. The bytes are BCD values between 0x0 and 0x9. 4531 * This routine checks the BCD digit in position shift (counting from 4532 * the least significant digit). If the digit is greater then five, 4533 * a 1 is returned indicating the string needs to be rounded up, 4534 * otherwise, 0 is returned. The value of shift (I64) is the index of 4535 * the BCD digit times four bits. 4536 */ 4537 return binop( Iop_CmpLE64U, 4538 mkU64( 6 ), 4539 binop( Iop_And64, 4540 unop( Iop_V128to64, 4541 binop( Iop_ShrV128, 4542 src, 4543 unop( Iop_64to8, mkexpr( shift ) ) ) ), 4544 mkU64( 0xF ) ) ); 4545 } 4546 4547 static IRTemp increment_BCDstring ( const VexAbiInfo* vbi, 4548 IRExpr *src, IRExpr *carry_in ) 4549 { 4550 /* The src is a 128-bit value containing 31 BCD digits with the sign in 4551 * the least significant byte. The bytes are BCD values between 0x0 and 0x9. 4552 * This function returns the BCD string incremented by 1. 4553 * 4554 * Call a clean helper to do the computation as it requires a lot of 4555 * IR code to do this. 4556 * 4557 * The helper function takes a 32-bit BCD string, in a 64-bit value, and 4558 * increments the string by the 32-bi carry in value. 4559 * 4560 * The incremented value is returned in the lower 32-bits of the result. 4561 * The carry out is returned in bits [35:32] of the result. The 4562 * helper function will be called for each of the four 32-bit strings 4563 * that make up the src string passing the returned carry out to the 4564 * next call. 4565 */ 4566 IRTemp bcd_result = newTemp( Ity_V128 ); 4567 IRTemp bcd_result0 = newTemp( Ity_I64 ); 4568 IRTemp bcd_result1 = newTemp( Ity_I64 ); 4569 IRTemp bcd_result2 = newTemp( Ity_I64 ); 4570 IRTemp bcd_result3 = newTemp( Ity_I64 ); 4571 IRExpr *bcd_string0, *bcd_string1, *bcd_string2, *bcd_string3; 4572 4573 bcd_string0 = binop( Iop_And64, 4574 mkU64( 0xFFFFFFFF ), unop( Iop_V128to64, src ) ); 4575 bcd_string1 = binop( Iop_Shr64, unop( Iop_V128to64, src ), mkU8( 32 ) ); 4576 bcd_string2 = binop( Iop_And64, 4577 mkU64( 0xFFFFFFFF ), unop( Iop_V128HIto64, src ) ); 4578 bcd_string3 = binop( Iop_Shr64, unop( Iop_V128HIto64, src ), mkU8( 32 ) ); 4579 4580 assign( bcd_result0, 4581 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4582 "increment_BCDstring32_helper", 4583 fnptr_to_fnentry( vbi, 4584 &increment_BCDstring32_helper ), 4585 mkIRExprVec_3( mkU64( True /*Signed*/ ), 4586 bcd_string0, 4587 binop( Iop_32HLto64, mkU32( 0 ), 4588 carry_in ) ) ) ); 4589 4590 assign( bcd_result1, 4591 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4592 "increment_BCDstring32_helper", 4593 fnptr_to_fnentry( vbi, 4594 &increment_BCDstring32_helper ), 4595 mkIRExprVec_3( mkU64( False /*Unsigned*/ ), 4596 bcd_string1, 4597 binop( Iop_Shr64, 4598 mkexpr( bcd_result0 ), 4599 mkU8( 32 ) ) ) ) ); 4600 assign( bcd_result2, 4601 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4602 "increment_BCDstring32_helper", 4603 fnptr_to_fnentry( vbi, 4604 &increment_BCDstring32_helper ), 4605 mkIRExprVec_3( mkU64( False /*Unsigned*/ ), 4606 bcd_string2, 4607 binop( Iop_Shr64, 4608 mkexpr( bcd_result1 ), 4609 mkU8( 32 ) ) ) ) ); 4610 assign( bcd_result3, 4611 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4612 "increment_BCDstring32_helper", 4613 fnptr_to_fnentry( vbi, 4614 &increment_BCDstring32_helper ), 4615 mkIRExprVec_3( mkU64( False /*Unsigned*/ ), 4616 bcd_string3, 4617 binop( Iop_Shr64, 4618 mkexpr( bcd_result2 ), 4619 mkU8( 32 ) ) ) ) ); 4620 4621 /* Put the 128-bit result together from the intermediate results. Remember 4622 * to mask out the carry out from the upper 32 bits of the results. 4623 */ 4624 assign( bcd_result, 4625 binop( Iop_64HLtoV128, 4626 binop( Iop_Or64, 4627 binop( Iop_And64, 4628 mkU64( 0xFFFFFFFF ), mkexpr (bcd_result2 ) ), 4629 binop( Iop_Shl64, 4630 mkexpr (bcd_result3 ), mkU8( 32 ) ) ), 4631 binop( Iop_Or64, 4632 binop( Iop_And64, 4633 mkU64( 0xFFFFFFFF ), mkexpr (bcd_result0 ) ), 4634 binop( Iop_Shl64, 4635 mkexpr (bcd_result1 ), mkU8( 32 ) ) ) ) ); 4636 return bcd_result; 4637 } 4638 4639 static IRExpr * convert_to_zoned ( const VexAbiInfo* vbi, 4640 IRExpr *src, IRExpr *upper_byte ) 4641 { 4642 /* The function takes a V128 packed decimal value and returns 4643 * the value in zoned format. Note, the sign of the value is ignored. 4644 */ 4645 IRTemp result_low = newTemp( Ity_I64 ); 4646 IRTemp result_hi = newTemp( Ity_I64 ); 4647 IRTemp result = newTemp( Ity_V128 ); 4648 4649 /* Since we can only return 64-bits from a clean helper, we will 4650 * have to get the lower and upper 64-bits separately. 4651 */ 4652 4653 assign( result_low, 4654 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4655 "convert_to_zoned_helper", 4656 fnptr_to_fnentry( vbi, &convert_to_zoned_helper ), 4657 mkIRExprVec_4( unop( Iop_V128HIto64, src ), 4658 unop( Iop_V128to64, src ), 4659 upper_byte, 4660 mkU64( 0 ) ) ) ); 4661 4662 assign( result_hi, 4663 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4664 "convert_to_zoned_helper", 4665 fnptr_to_fnentry( vbi, &convert_to_zoned_helper ), 4666 mkIRExprVec_4( unop( Iop_V128HIto64, src ), 4667 unop( Iop_V128to64, src ), 4668 upper_byte, 4669 mkU64( 1 ) ) ) ); 4670 4671 4672 assign( result, 4673 binop( Iop_64HLtoV128, mkexpr( result_hi ), mkexpr( result_low ) ) ); 4674 4675 return mkexpr( result ); 4676 } 4677 4678 static IRExpr * convert_to_national ( const VexAbiInfo* vbi, IRExpr *src ) { 4679 /* The function takes 128-bit value which has a 64-bit packed decimal 4680 * value in the lower 64-bits of the source. The packed decimal is 4681 * converted to the national format via a clean helper. The clean 4682 * helper is used to to the large amount of IR code needed to do the 4683 * conversion. The helper returns the upper 64-bits of the 128-bit 4684 * result if return_upper != 0. Otherwise, the lower 64-bits of the 4685 * result is returned. 4686 */ 4687 IRTemp result_low = newTemp( Ity_I64 ); 4688 IRTemp result_hi = newTemp( Ity_I64 ); 4689 IRTemp result = newTemp( Ity_V128 ); 4690 4691 /* Since we can only return 64-bits from a clean helper, we will 4692 * have to get the lower and upper 64-bits separately. 4693 */ 4694 4695 assign( result_low, 4696 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4697 "convert_to_national_helper", 4698 fnptr_to_fnentry( vbi, &convert_to_national_helper ), 4699 mkIRExprVec_2( unop( Iop_V128to64, src ), 4700 mkU64( 0 ) ) ) ); 4701 4702 assign( result_hi, 4703 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4704 "convert_to_national_helper", 4705 fnptr_to_fnentry( vbi, &convert_to_national_helper ), 4706 mkIRExprVec_2( unop( Iop_V128to64, src ), 4707 mkU64( 1 ) ) ) ); 4708 4709 assign( result, 4710 binop( Iop_64HLtoV128, mkexpr( result_hi ), mkexpr( result_low ) ) ); 4711 4712 return mkexpr( result ); 4713 } 4714 4715 static IRExpr * convert_from_zoned ( const VexAbiInfo* vbi, IRExpr *src ) { 4716 /* The function takes 128-bit zoned value and returns a signless 64-bit 4717 * packed decimal value in the lower 64-bits of the 128-bit result. 4718 */ 4719 IRTemp result = newTemp( Ity_V128 ); 4720 4721 assign( result, 4722 binop( Iop_ShlV128, 4723 binop( Iop_64HLtoV128, 4724 mkU64( 0 ), 4725 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4726 "convert_from_zoned_helper", 4727 fnptr_to_fnentry( vbi, 4728 &convert_from_zoned_helper ), 4729 mkIRExprVec_2( unop( Iop_V128HIto64, 4730 src ), 4731 unop( Iop_V128to64, 4732 src ) ) ) ), 4733 mkU8( 4 ) ) ); 4734 4735 return mkexpr( result ); 4736 } 4737 4738 static IRExpr * convert_from_national ( const VexAbiInfo* vbi, IRExpr *src ) { 4739 /* The function takes 128-bit national value and returns a 64-bit 4740 * packed decimal value. 4741 */ 4742 IRTemp result = newTemp( Ity_I64); 4743 4744 assign( result, 4745 mkIRExprCCall( Ity_I64, 0 /*regparms*/, 4746 "convert_from_national_helper", 4747 fnptr_to_fnentry( vbi, 4748 &convert_from_national_helper ), 4749 mkIRExprVec_2( unop( Iop_V128HIto64, 4750 src ), 4751 unop( Iop_V128to64, 4752 src ) ) ) ); 4753 4754 return mkexpr( result ); 4755 } 4756 4757 static IRExpr * UNSIGNED_CMP_GT_V128 ( IRExpr *vA, IRExpr *vB ) { 4758 /* This function does an unsigned compare of two V128 values. The 4759 * function is for use in 32-bit mode only as it is expensive. The 4760 * issue is that compares (GT, LT, EQ) are not supported for operands 4761 * larger then 32-bits when running in 32-bit mode. The function returns 4762 * a 1-bit expression, 1 for TRUE and 0 for FALSE. 4763 */ 4764 IRTemp vA_word0 = newTemp( Ity_I32); 4765 IRTemp vA_word1 = newTemp( Ity_I32); 4766 IRTemp vA_word2 = newTemp( Ity_I32); 4767 IRTemp vA_word3 = newTemp( Ity_I32); 4768 IRTemp vB_word0 = newTemp( Ity_I32); 4769 IRTemp vB_word1 = newTemp( Ity_I32); 4770 IRTemp vB_word2 = newTemp( Ity_I32); 4771 IRTemp vB_word3 = newTemp( Ity_I32); 4772 4773 IRTemp eq_word1 = newTemp( Ity_I1); 4774 IRTemp eq_word2 = newTemp( Ity_I1); 4775 IRTemp eq_word3 = newTemp( Ity_I1); 4776 4777 4778 IRExpr *gt_word0, *gt_word1, *gt_word2, *gt_word3; 4779 IRExpr *eq_word3_2, *eq_word3_2_1; 4780 IRTemp result = newTemp( Ity_I1 ); 4781 4782 assign( vA_word0, unop( Iop_64to32, unop( Iop_V128to64, vA ) ) ); 4783 assign( vA_word1, unop( Iop_64HIto32, unop( Iop_V128to64, vA ) ) ); 4784 assign( vA_word2, unop( Iop_64to32, unop( Iop_V128HIto64, vA ) ) ); 4785 assign( vA_word3, unop( Iop_64HIto32, unop( Iop_V128HIto64, vA ) ) ); 4786 4787 assign( vB_word0, unop( Iop_64to32, unop( Iop_V128to64, vB ) ) ); 4788 assign( vB_word1, unop( Iop_64HIto32, unop( Iop_V128to64, vB ) ) ); 4789 assign( vB_word2, unop( Iop_64to32, unop( Iop_V128HIto64, vB ) ) ); 4790 assign( vB_word3, unop( Iop_64HIto32, unop( Iop_V128HIto64, vB ) ) ); 4791 4792 assign( eq_word3, binop( Iop_CmpEQ32, mkexpr( vA_word3 ), 4793 mkexpr( vB_word3 ) ) ); 4794 assign( eq_word2, binop( Iop_CmpEQ32, mkexpr( vA_word2 ), 4795 mkexpr( vB_word2 ) ) ); 4796 assign( eq_word1, binop( Iop_CmpEQ32, mkexpr( vA_word1 ), 4797 mkexpr( vB_word1 ) ) ); 4798 4799 gt_word3 = binop( Iop_CmpLT32U, mkexpr( vB_word3 ), mkexpr( vA_word3 ) ); 4800 gt_word2 = binop( Iop_CmpLT32U, mkexpr( vB_word2 ), mkexpr( vA_word2 ) ); 4801 gt_word1 = binop( Iop_CmpLT32U, mkexpr( vB_word1 ), mkexpr( vA_word1 ) ); 4802 gt_word0 = binop( Iop_CmpLT32U, mkexpr( vB_word0 ), mkexpr( vA_word0 ) ); 4803 4804 eq_word3_2 = mkAND1( mkexpr( eq_word3 ), mkexpr( eq_word2 ) ); 4805 eq_word3_2_1 = mkAND1( mkexpr( eq_word1 ), eq_word3_2 ); 4806 4807 assign( result, mkOR1( 4808 mkOR1( gt_word3, 4809 mkAND1( mkexpr( eq_word3 ), gt_word2 ) ), 4810 mkOR1( mkAND1( eq_word3_2, gt_word1 ), 4811 mkAND1( eq_word3_2_1, gt_word0 ) ) ) ); 4812 return mkexpr( result ); 4813 } 4814 4815 /*------------------------------------------------------------*/ 4816 /* Transactional memory helpers 4817 * 4818 *------------------------------------------------------------*/ 4819 4820 static ULong generate_TMreason( UInt failure_code, 4821 UInt persistant, 4822 UInt nest_overflow, 4823 UInt tm_exact ) 4824 { 4825 ULong tm_err_code = 4826 ( (ULong) 0) << (63-6) /* Failure code */ 4827 | ( (ULong) persistant) << (63-7) /* Failure persistant */ 4828 | ( (ULong) 0) << (63-8) /* Disallowed */ 4829 | ( (ULong) nest_overflow) << (63-9) /* Nesting Overflow */ 4830 | ( (ULong) 0) << (63-10) /* Footprint Overflow */ 4831 | ( (ULong) 0) << (63-11) /* Self-Induced Conflict */ 4832 | ( (ULong) 0) << (63-12) /* Non-Transactional Conflict */ 4833 | ( (ULong) 0) << (63-13) /* Transactional Conflict */ 4834 | ( (ULong) 0) << (63-14) /* Translation Invalidation Conflict */ 4835 | ( (ULong) 0) << (63-15) /* Implementation-specific */ 4836 | ( (ULong) 0) << (63-16) /* Instruction Fetch Conflict */ 4837 | ( (ULong) 0) << (63-30) /* Reserved */ 4838 | ( (ULong) 0) << (63-31) /* Abort */ 4839 | ( (ULong) 0) << (63-32) /* Suspend */ 4840 | ( (ULong) 0) << (63-33) /* Reserved */ 4841 | ( (ULong) 0) << (63-35) /* Privilege */ 4842 | ( (ULong) 0) << (63-36) /* Failure Summary */ 4843 | ( (ULong) tm_exact) << (63-37) /* TFIAR Exact */ 4844 | ( (ULong) 0) << (63-38) /* ROT */ 4845 | ( (ULong) 0) << (63-51) /* Reserved */ 4846 | ( (ULong) 0) << (63-63); /* Transaction Level */ 4847 4848 return tm_err_code; 4849 } 4850 4851 static void storeTMfailure( Addr64 err_address, ULong tm_reason, 4852 Addr64 handler_address ) 4853 { 4854 putGST( PPC_GST_TFIAR, mkU64( err_address ) ); 4855 putGST( PPC_GST_TEXASR, mkU64( tm_reason ) ); 4856 putGST( PPC_GST_TEXASRU, mkU32( 0 ) ); 4857 putGST( PPC_GST_TFHAR, mkU64( handler_address ) ); 4858 } 4859 4860 /*------------------------------------------------------------*/ 4861 /*--- Integer Instruction Translation --- */ 4862 /*------------------------------------------------------------*/ 4863 4864 /* 4865 Integer Arithmetic Instructions 4866 */ 4867 static Bool dis_int_mult_add ( UInt theInstr ) 4868 { 4869 /* VA-Form */ 4870 UChar rD_addr = ifieldRegDS( theInstr ); 4871 UChar rA_addr = ifieldRegA( theInstr ); 4872 UChar rB_addr = ifieldRegB( theInstr ); 4873 UChar rC_addr = ifieldRegC( theInstr ); 4874 UInt opc2 = IFIELD( theInstr, 0, 6 ); 4875 IRType ty = Ity_I64; 4876 IRTemp rA = newTemp( ty ); 4877 IRTemp rB = newTemp( ty ); 4878 IRTemp rC = newTemp( ty ); 4879 IRTemp rD = newTemp( ty ); 4880 IRTemp tmpLo = newTemp( Ity_I64 ); 4881 IRTemp tmpHi = newTemp( Ity_I64 ); 4882 IRTemp tmp2Hi = newTemp( Ity_I64 ); 4883 IRTemp result = newTemp( Ity_I128 ); 4884 IRTemp resultLo = newTemp( Ity_I64 ); 4885 IRExpr* carryout; 4886 4887 assign( rA, getIReg( rA_addr ) ); 4888 assign( rB, getIReg( rB_addr ) ); 4889 assign( rC, getIReg( rC_addr ) ); 4890 4891 switch (opc2) { 4892 case 0x30: // maddhd multiply-add High doubleword signed 4893 DIP("maddhd r%u,r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr, rC_addr); 4894 4895 assign( result, binop( Iop_MullS64, mkexpr( rA ), mkexpr( rB ) ) ); 4896 assign( tmpLo, unop( Iop_128to64, mkexpr( result ) ) ); 4897 assign( tmpHi, unop( Iop_128HIto64, mkexpr( result ) ) ); 4898 4899 /* Multiply rA and rB then add rC. If the lower 32-bits of the result 4900 * is less then rC and the result rA * rB, a carry out of the lower 32 4901 * bits occurred and the upper 32 bits must be incremented by 1. Sign 4902 * extend rC and do the add to the upper 64 bits to handle the 4903 * negative case for rC. 4904 */ 4905 assign( resultLo, binop( Iop_Add64, mkexpr( tmpLo ), mkexpr( rC ) ) ); 4906 assign( tmp2Hi, binop( Iop_Add64, 4907 mkexpr( tmpHi ), 4908 unop( Iop_1Sto64, 4909 unop( Iop_64to1, 4910 binop( Iop_Shr64, 4911 mkexpr( rC ), 4912 mkU8( 63 ) ) ) ) ) ); 4913 4914 /* need to do calculation for the upper 32 bit result */ 4915 carryout = mkAND1( binop( Iop_CmpLT64U, 4916 mkexpr( resultLo ), mkexpr( rC ) ), 4917 binop( Iop_CmpLT64U, 4918 mkexpr( resultLo ), mkexpr( tmpLo ) ) ); 4919 assign( rD, binop( Iop_Add64, 4920 mkexpr( tmp2Hi ), 4921 unop( Iop_1Uto64, carryout ) ) ); 4922 break; 4923 4924 case 0x31: // maddhdu multiply-add High doubleword unsigned 4925 DIP("maddhdu r%u,r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr, rC_addr); 4926 4927 assign( result, binop( Iop_MullU64, mkexpr( rA ), mkexpr( rB ) ) ); 4928 assign( tmpLo, unop( Iop_128to64, mkexpr( result ) ) ); 4929 assign( tmpHi, unop( Iop_128HIto64, mkexpr( result ) ) ); 4930 4931 /* Add rC, if the lower 32-bits of the result is less then rC and 4932 * tmpLo, a carry out of the lower 32 bits occurred. Upper 32 bits 4933 * must be incremented by 1. 4934 */ 4935 assign( resultLo, binop( Iop_Add64, mkexpr( tmpLo ), mkexpr( rC ) ) ); 4936 4937 /* need to do calculation for the upper 32 bit result */ 4938 carryout = mkAND1( binop( Iop_CmpLT64U, 4939 mkexpr(resultLo), mkexpr( rC ) ), 4940 binop( Iop_CmpLT64U, 4941 mkexpr(resultLo), mkexpr( tmpLo ) ) ); 4942 assign( rD, binop( Iop_Add64, 4943 mkexpr( tmpHi ), 4944 unop( Iop_1Uto64, carryout ) ) ); 4945 break; 4946 4947 case 0x33: // maddld multiply-add Low doubleword 4948 DIP("maddld r%u,r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr, rC_addr); 4949 4950 assign( result, binop( Iop_MullS64, mkexpr( rA ), mkexpr( rB ) ) ); 4951 assign( tmpLo, unop( Iop_128to64, mkexpr( result ) ) ); 4952 assign( tmpHi, unop( Iop_128HIto64, mkexpr( result ) ) ); 4953 4954 assign( rD, binop( Iop_Add64, mkexpr( tmpLo ), mkexpr( rC ) ) ); 4955 break; 4956 4957 default: 4958 vex_printf("dis_int_mult(ppc): unrecognized instruction\n"); 4959 return False; 4960 } 4961 4962 putIReg( rD_addr, mkexpr(rD) ); 4963 4964 return True; 4965 } 4966 4967 static Bool dis_int_arith ( UInt theInstr ) 4968 { 4969 /* D-Form, XO-Form */ 4970 UChar opc1 = ifieldOPC(theInstr); 4971 UChar rD_addr = ifieldRegDS(theInstr); 4972 UChar rA_addr = ifieldRegA(theInstr); 4973 UInt uimm16 = ifieldUIMM16(theInstr); 4974 UChar rB_addr = ifieldRegB(theInstr); 4975 UChar flag_OE = ifieldBIT10(theInstr); 4976 UInt opc2 = ifieldOPClo9(theInstr); 4977 UChar flag_rC = ifieldBIT0(theInstr); 4978 4979 Long simm16 = extend_s_16to64(uimm16); 4980 IRType ty = mode64 ? Ity_I64 : Ity_I32; 4981 IRTemp rA = newTemp(ty); 4982 IRTemp rB = newTemp(ty); 4983 IRTemp rD = newTemp(ty); 4984 4985 Bool do_rc = False; 4986 4987 assign( rA, getIReg(rA_addr) ); 4988 assign( rB, getIReg(rB_addr) ); // XO-Form: rD, rA, rB 4989 4990 switch (opc1) { 4991 /* D-Form */ 4992 case 0x0C: // addic (Add Immediate Carrying, PPC32 p351 4993 DIP("addic r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 4994 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 4995 mkSzExtendS16(ty, uimm16) ) ); 4996 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADD, 4997 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 4998 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 4999 break; 5000 5001 case 0x0D: // addic. (Add Immediate Carrying and Record, PPC32 p352) 5002 DIP("addic. r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 5003 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5004 mkSzExtendS16(ty, uimm16) ) ); 5005 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADD, 5006 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 5007 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 5008 do_rc = True; // Always record to CR 5009 flag_rC = 1; 5010 break; 5011 5012 case 0x0E: // addi (Add Immediate, PPC32 p350) 5013 // li rD,val == addi rD,0,val 5014 // la disp(rA) == addi rD,rA,disp 5015 if ( rA_addr == 0 ) { 5016 DIP("li r%u,%d\n", rD_addr, (Int)simm16); 5017 assign( rD, mkSzExtendS16(ty, uimm16) ); 5018 } else { 5019 DIP("addi r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 5020 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5021 mkSzExtendS16(ty, uimm16) ) ); 5022 } 5023 break; 5024 5025 case 0x0F: // addis (Add Immediate Shifted, PPC32 p353) 5026 // lis rD,val == addis rD,0,val 5027 if ( rA_addr == 0 ) { 5028 DIP("lis r%u,%d\n", rD_addr, (Int)simm16); 5029 assign( rD, mkSzExtendS32(ty, uimm16 << 16) ); 5030 } else { 5031 DIP("addis r%u,r%u,0x%x\n", rD_addr, rA_addr, (UInt)simm16); 5032 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5033 mkSzExtendS32(ty, uimm16 << 16) ) ); 5034 } 5035 break; 5036 5037 case 0x07: // mulli (Multiply Low Immediate, PPC32 p490) 5038 DIP("mulli r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 5039 if (mode64) 5040 assign( rD, unop(Iop_128to64, 5041 binop(Iop_MullS64, mkexpr(rA), 5042 mkSzExtendS16(ty, uimm16))) ); 5043 else 5044 assign( rD, unop(Iop_64to32, 5045 binop(Iop_MullS32, mkexpr(rA), 5046 mkSzExtendS16(ty, uimm16))) ); 5047 break; 5048 5049 case 0x08: // subfic (Subtract from Immediate Carrying, PPC32 p540) 5050 DIP("subfic r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 5051 // rD = simm16 - rA 5052 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 5053 mkSzExtendS16(ty, uimm16), 5054 mkexpr(rA)) ); 5055 set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFI, 5056 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 5057 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 5058 break; 5059 5060 /* XO-Form */ 5061 case 0x1F: 5062 do_rc = True; // All below record to CR 5063 5064 switch (opc2) { 5065 case 0x10A: // add (Add, PPC32 p347) 5066 DIP("add%s%s r%u,r%u,r%u\n", 5067 flag_OE ? "o" : "", flag_rC ? ".":"", 5068 rD_addr, rA_addr, rB_addr); 5069 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5070 mkexpr(rA), mkexpr(rB) ) ); 5071 if (flag_OE) { 5072 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_ADD, 5073 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5074 } 5075 break; 5076 5077 case 0x00A: // addc (Add Carrying, PPC32 p348) 5078 DIP("addc%s%s r%u,r%u,r%u\n", 5079 flag_OE ? "o" : "", flag_rC ? ".":"", 5080 rD_addr, rA_addr, rB_addr); 5081 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5082 mkexpr(rA), mkexpr(rB)) ); 5083 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADD, 5084 mkexpr(rD), mkexpr(rA), mkexpr(rB), 5085 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 5086 if (flag_OE) { 5087 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_ADD, 5088 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5089 } 5090 break; 5091 5092 case 0x08A: { // adde (Add Extended, PPC32 p349) 5093 IRTemp old_xer_ca = newTemp(ty); 5094 DIP("adde%s%s r%u,r%u,r%u\n", 5095 flag_OE ? "o" : "", flag_rC ? ".":"", 5096 rD_addr, rA_addr, rB_addr); 5097 // rD = rA + rB + XER[CA] 5098 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5099 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5100 binop( mkSzOp(ty, Iop_Add8), 5101 mkexpr(rB), mkexpr(old_xer_ca))) ); 5102 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADDE, 5103 mkexpr(rD), mkexpr(rA), mkexpr(rB), 5104 mkexpr(old_xer_ca) ); 5105 if (flag_OE) { 5106 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_ADDE, 5107 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5108 } 5109 break; 5110 } 5111 5112 case 0xAA: {// addex (Add Extended alternate carry bit Z23-form) 5113 DIP("addex r%u,r%u,r%u,%d\n", rD_addr, rA_addr, rB_addr, (Int)flag_OE); 5114 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5115 binop( mkSzOp(ty, Iop_Add8), mkexpr(rB), 5116 mkWidenFrom8( ty, getXER_OV(), False ) ) ) ); 5117 5118 /* CY bit is same as OE bit */ 5119 if (flag_OE == 0) { 5120 /* Exception, do not set SO bit */ 5121 set_XER_OV_OV32( ty, PPCG_FLAG_OP_ADDE, 5122 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5123 } else { 5124 /* CY=1, 2 and 3 (AKA flag_OE) are reserved */ 5125 vex_printf("addex instruction, CY = %d is reserved.\n", flag_OE); 5126 vpanic("addex instruction\n"); 5127 } 5128 break; 5129 } 5130 5131 case 0x0EA: { // addme (Add to Minus One Extended, PPC32 p354) 5132 IRTemp old_xer_ca = newTemp(ty); 5133 IRExpr *min_one; 5134 if (rB_addr != 0) { 5135 vex_printf("dis_int_arith(ppc)(addme,rB_addr)\n"); 5136 return False; 5137 } 5138 DIP("addme%s%s r%u,r%u,r%u\n", 5139 flag_OE ? "o" : "", flag_rC ? ".":"", 5140 rD_addr, rA_addr, rB_addr); 5141 // rD = rA + (-1) + XER[CA] 5142 // => Just another form of adde 5143 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5144 min_one = mkSzImm(ty, (Long)-1); 5145 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 5146 binop( mkSzOp(ty, Iop_Add8), 5147 min_one, mkexpr(old_xer_ca)) )); 5148 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADDE, 5149 mkexpr(rD), mkexpr(rA), min_one, 5150 mkexpr(old_xer_ca) ); 5151 if (flag_OE) { 5152 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_ADDE, 5153 mkexpr(rD), mkexpr(rA), min_one ); 5154 } 5155 break; 5156 } 5157 5158 case 0x0CA: { // addze (Add to Zero Extended, PPC32 p355) 5159 IRTemp old_xer_ca = newTemp(ty); 5160 if (rB_addr != 0) { 5161 vex_printf("dis_int_arith(ppc)(addze,rB_addr)\n"); 5162 return False; 5163 } 5164 DIP("addze%s%s r%u,r%u,r%u\n", 5165 flag_OE ? "o" : "", flag_rC ? ".":"", 5166 rD_addr, rA_addr, rB_addr); 5167 // rD = rA + (0) + XER[CA] 5168 // => Just another form of adde 5169 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5170 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5171 mkexpr(rA), mkexpr(old_xer_ca)) ); 5172 set_XER_CA_CA32( ty, PPCG_FLAG_OP_ADDE, 5173 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0), 5174 mkexpr(old_xer_ca) ); 5175 if (flag_OE) { 5176 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_ADDE, 5177 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0) ); 5178 } 5179 break; 5180 } 5181 5182 case 0x1EB: // divw (Divide Word, PPC32 p388) 5183 DIP("divw%s%s r%u,r%u,r%u\n", 5184 flag_OE ? "o" : "", flag_rC ? ".":"", 5185 rD_addr, rA_addr, rB_addr); 5186 if (mode64) { 5187 /* Note: 5188 XER settings are mode independent, and reflect the 5189 overflow of the low-order 32bit result 5190 CR0[LT|GT|EQ] are undefined if flag_rC && mode64 5191 */ 5192 /* rD[hi32] are undefined: setting them to sign of lo32 5193 - makes set_CR0 happy */ 5194 IRExpr* dividend = mk64lo32Sto64( mkexpr(rA) ); 5195 IRExpr* divisor = mk64lo32Sto64( mkexpr(rB) ); 5196 assign( rD, mk64lo32Uto64( binop(Iop_DivS64, dividend, 5197 divisor) ) ); 5198 if (flag_OE) { 5199 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVW, 5200 mkexpr(rD), dividend, divisor ); 5201 } 5202 } else { 5203 assign( rD, binop(Iop_DivS32, mkexpr(rA), mkexpr(rB)) ); 5204 if (flag_OE) { 5205 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVW, 5206 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5207 } 5208 } 5209 /* Note: 5210 if (0x8000_0000 / -1) or (x / 0) 5211 => rD=undef, if(flag_rC) CR7=undef, if(flag_OE) XER_OV=1 5212 => But _no_ exception raised. */ 5213 break; 5214 5215 case 0x1CB: // divwu (Divide Word Unsigned, PPC32 p389) 5216 DIP("divwu%s%s r%u,r%u,r%u\n", 5217 flag_OE ? "o" : "", flag_rC ? ".":"", 5218 rD_addr, rA_addr, rB_addr); 5219 if (mode64) { 5220 /* Note: 5221 XER settings are mode independent, and reflect the 5222 overflow of the low-order 32bit result 5223 CR0[LT|GT|EQ] are undefined if flag_rC && mode64 5224 */ 5225 IRExpr* dividend = mk64lo32Uto64( mkexpr(rA) ); 5226 IRExpr* divisor = mk64lo32Uto64( mkexpr(rB) ); 5227 assign( rD, mk64lo32Uto64( binop(Iop_DivU64, dividend, 5228 divisor) ) ); 5229 if (flag_OE) { 5230 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVWU, 5231 mkexpr(rD), dividend, divisor ); 5232 } 5233 } else { 5234 assign( rD, binop(Iop_DivU32, mkexpr(rA), mkexpr(rB)) ); 5235 if (flag_OE) { 5236 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVWU, 5237 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5238 } 5239 } 5240 /* Note: ditto comment divw, for (x / 0) */ 5241 break; 5242 5243 case 0x04B: // mulhw (Multiply High Word, PPC32 p488) 5244 if (flag_OE != 0) { 5245 vex_printf("dis_int_arith(ppc)(mulhw,flag_OE)\n"); 5246 return False; 5247 } 5248 DIP("mulhw%s r%u,r%u,r%u\n", flag_rC ? ".":"", 5249 rD_addr, rA_addr, rB_addr); 5250 if (mode64) { 5251 /* rD[hi32] are undefined: setting them to sign of lo32 5252 - makes set_CR0 happy */ 5253 assign( rD, binop(Iop_Sar64, 5254 binop(Iop_Mul64, 5255 mk64lo32Sto64( mkexpr(rA) ), 5256 mk64lo32Sto64( mkexpr(rB) )), 5257 mkU8(32)) ); 5258 } else { 5259 assign( rD, unop(Iop_64HIto32, 5260 binop(Iop_MullS32, 5261 mkexpr(rA), mkexpr(rB))) ); 5262 } 5263 break; 5264 5265 case 0x00B: // mulhwu (Multiply High Word Unsigned, PPC32 p489) 5266 if (flag_OE != 0) { 5267 vex_printf("dis_int_arith(ppc)(mulhwu,flag_OE)\n"); 5268 return False; 5269 } 5270 DIP("mulhwu%s r%u,r%u,r%u\n", flag_rC ? ".":"", 5271 rD_addr, rA_addr, rB_addr); 5272 if (mode64) { 5273 /* rD[hi32] are undefined: setting them to sign of lo32 5274 - makes set_CR0 happy */ 5275 assign( rD, binop(Iop_Sar64, 5276 binop(Iop_Mul64, 5277 mk64lo32Uto64( mkexpr(rA) ), 5278 mk64lo32Uto64( mkexpr(rB) ) ), 5279 mkU8(32)) ); 5280 } else { 5281 assign( rD, unop(Iop_64HIto32, 5282 binop(Iop_MullU32, 5283 mkexpr(rA), mkexpr(rB))) ); 5284 } 5285 break; 5286 5287 case 0x0EB: // mullw (Multiply Low Word, PPC32 p491) 5288 DIP("mullw%s%s r%u,r%u,r%u\n", 5289 flag_OE ? "o" : "", flag_rC ? ".":"", 5290 rD_addr, rA_addr, rB_addr); 5291 if (mode64) { 5292 /* rD[hi32] are undefined: setting them to sign of lo32 5293 - set_XER_OV() and set_CR0() depend on this */ 5294 IRExpr *a = unop(Iop_64to32, mkexpr(rA) ); 5295 IRExpr *b = unop(Iop_64to32, mkexpr(rB) ); 5296 assign( rD, binop(Iop_MullS32, a, b) ); 5297 if (flag_OE) { 5298 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_MULLW, 5299 mkexpr(rD), 5300 unop(Iop_32Uto64, a), unop(Iop_32Uto64, b) ); 5301 } 5302 } else { 5303 assign( rD, unop(Iop_64to32, 5304 binop(Iop_MullU32, 5305 mkexpr(rA), mkexpr(rB))) ); 5306 if (flag_OE) { 5307 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_MULLW, 5308 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5309 } 5310 } 5311 break; 5312 5313 case 0x068: // neg (Negate, PPC32 p493) 5314 if (rB_addr != 0) { 5315 vex_printf("dis_int_arith(ppc)(neg,rB_addr)\n"); 5316 return False; 5317 } 5318 DIP("neg%s%s r%u,r%u\n", 5319 flag_OE ? "o" : "", flag_rC ? ".":"", 5320 rD_addr, rA_addr); 5321 // rD = (~rA) + 1 5322 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5323 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA) ), 5324 mkSzImm(ty, 1)) ); 5325 if (flag_OE) { 5326 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_NEG, 5327 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5328 } 5329 break; 5330 5331 case 0x028: // subf (Subtract From, PPC32 p537) 5332 DIP("subf%s%s r%u,r%u,r%u\n", 5333 flag_OE ? "o" : "", flag_rC ? ".":"", 5334 rD_addr, rA_addr, rB_addr); 5335 // rD = rB - rA 5336 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 5337 mkexpr(rB), mkexpr(rA)) ); 5338 if (flag_OE) { 5339 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_SUBF, 5340 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5341 } 5342 break; 5343 5344 case 0x008: // subfc (Subtract from Carrying, PPC32 p538) 5345 DIP("subfc%s%s r%u,r%u,r%u\n", 5346 flag_OE ? "o" : "", flag_rC ? ".":"", 5347 rD_addr, rA_addr, rB_addr); 5348 // rD = rB - rA 5349 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 5350 mkexpr(rB), mkexpr(rA)) ); 5351 set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFC, 5352 mkexpr(rD), mkexpr(rA), mkexpr(rB), 5353 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 5354 if (flag_OE) { 5355 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_SUBFC, 5356 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5357 } 5358 break; 5359 5360 case 0x088: {// subfe (Subtract from Extended, PPC32 p539) 5361 IRTemp old_xer_ca = newTemp(ty); 5362 DIP("subfe%s%s r%u,r%u,r%u\n", 5363 flag_OE ? "o" : "", flag_rC ? ".":"", 5364 rD_addr, rA_addr, rB_addr); 5365 // rD = (log not)rA + rB + XER[CA] 5366 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5367 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5368 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA)), 5369 binop( mkSzOp(ty, Iop_Add8), 5370 mkexpr(rB), mkexpr(old_xer_ca))) ); 5371 set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFE, 5372 mkexpr(rD), mkexpr(rA), mkexpr(rB), 5373 mkexpr(old_xer_ca) ); 5374 if (flag_OE) { 5375 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_SUBFE, 5376 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5377 } 5378 break; 5379 } 5380 5381 case 0x0E8: { // subfme (Subtract from -1 Extended, PPC32 p541) 5382 IRTemp old_xer_ca = newTemp(ty); 5383 IRExpr *min_one; 5384 if (rB_addr != 0) { 5385 vex_printf("dis_int_arith(ppc)(subfme,rB_addr)\n"); 5386 return False; 5387 } 5388 DIP("subfme%s%s r%u,r%u\n", 5389 flag_OE ? "o" : "", flag_rC ? ".":"", 5390 rD_addr, rA_addr); 5391 // rD = (log not)rA + (-1) + XER[CA] 5392 // => Just another form of subfe 5393 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5394 min_one = mkSzImm(ty, (Long)-1); 5395 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5396 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA)), 5397 binop( mkSzOp(ty, Iop_Add8), 5398 min_one, mkexpr(old_xer_ca))) ); 5399 set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFE, 5400 mkexpr(rD), mkexpr(rA), min_one, 5401 mkexpr(old_xer_ca) ); 5402 if (flag_OE) { 5403 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_SUBFE, 5404 mkexpr(rD), mkexpr(rA), min_one ); 5405 } 5406 break; 5407 } 5408 5409 case 0x0C8: { // subfze (Subtract from Zero Extended, PPC32 p542) 5410 IRTemp old_xer_ca = newTemp(ty); 5411 if (rB_addr != 0) { 5412 vex_printf("dis_int_arith(ppc)(subfze,rB_addr)\n"); 5413 return False; 5414 } 5415 DIP("subfze%s%s r%u,r%u\n", 5416 flag_OE ? "o" : "", flag_rC ? ".":"", 5417 rD_addr, rA_addr); 5418 // rD = (log not)rA + (0) + XER[CA] 5419 // => Just another form of subfe 5420 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); 5421 assign( rD, binop( mkSzOp(ty, Iop_Add8), 5422 unop( mkSzOp(ty, Iop_Not8), 5423 mkexpr(rA)), mkexpr(old_xer_ca)) ); 5424 set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFE, 5425 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0), 5426 mkexpr(old_xer_ca) ); 5427 if (flag_OE) { 5428 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_SUBFE, 5429 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0) ); 5430 } 5431 break; 5432 } 5433 5434 5435 /* 64bit Arithmetic */ 5436 case 0x49: // mulhd (Multiply High DWord, PPC64 p539) 5437 if (flag_OE != 0) { 5438 vex_printf("dis_int_arith(ppc)(mulhd,flagOE)\n"); 5439 return False; 5440 } 5441 DIP("mulhd%s r%u,r%u,r%u\n", flag_rC ? ".":"", 5442 rD_addr, rA_addr, rB_addr); 5443 assign( rD, unop(Iop_128HIto64, 5444 binop(Iop_MullS64, 5445 mkexpr(rA), mkexpr(rB))) ); 5446 5447 break; 5448 5449 case 0x9: // mulhdu (Multiply High DWord Unsigned, PPC64 p540) 5450 if (flag_OE != 0) { 5451 vex_printf("dis_int_arith(ppc)(mulhdu,flagOE)\n"); 5452 return False; 5453 } 5454 DIP("mulhdu%s r%u,r%u,r%u\n", flag_rC ? ".":"", 5455 rD_addr, rA_addr, rB_addr); 5456 assign( rD, unop(Iop_128HIto64, 5457 binop(Iop_MullU64, 5458 mkexpr(rA), mkexpr(rB))) ); 5459 break; 5460 5461 case 0xE9: // mulld (Multiply Low DWord, PPC64 p543) 5462 DIP("mulld%s%s r%u,r%u,r%u\n", 5463 flag_OE ? "o" : "", flag_rC ? ".":"", 5464 rD_addr, rA_addr, rB_addr); 5465 assign( rD, binop(Iop_Mul64, mkexpr(rA), mkexpr(rB)) ); 5466 if (flag_OE) { 5467 set_XER_OV_64( PPCG_FLAG_OP_MULLD, 5468 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5469 /* OV is set to 1 if product isn't representable. 5470 * In this case also need to set OV32 and SO to 1, 5471 * i.e. copy OV to OV32 and SO. 5472 */ 5473 copy_OV_to_OV32(); 5474 update_SO(); 5475 } 5476 break; 5477 5478 case 0x1E9: // divd (Divide DWord, PPC64 p419) 5479 DIP("divd%s%s r%u,r%u,r%u\n", 5480 flag_OE ? "o" : "", flag_rC ? ".":"", 5481 rD_addr, rA_addr, rB_addr); 5482 assign( rD, binop(Iop_DivS64, mkexpr(rA), mkexpr(rB)) ); 5483 if (flag_OE) { 5484 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVW, 5485 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5486 } 5487 break; 5488 /* Note: 5489 if (0x8000_0000_0000_0000 / -1) or (x / 0) 5490 => rD=undef, if(flag_rC) CR7=undef, if(flag_OE) XER_OV=1 5491 => But _no_ exception raised. */ 5492 5493 case 0x1C9: // divdu (Divide DWord Unsigned, PPC64 p420) 5494 DIP("divdu%s%s r%u,r%u,r%u\n", 5495 flag_OE ? "o" : "", flag_rC ? ".":"", 5496 rD_addr, rA_addr, rB_addr); 5497 assign( rD, binop(Iop_DivU64, mkexpr(rA), mkexpr(rB)) ); 5498 if (flag_OE) { 5499 set_XER_OV_OV32_SO( ty, PPCG_FLAG_OP_DIVWU, 5500 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 5501 } 5502 break; 5503 /* Note: ditto comment divd, for (x / 0) */ 5504 5505 case 0x18B: // divweu (Divide Word Extended Unsigned) 5506 { 5507 /* 5508 * If (RA) >= (RB), or if an attempt is made to perform the division 5509 * <anything> / 0 5510 * then the contents of register RD are undefined as are (if Rc=1) the contents of 5511 * the LT, GT, and EQ bits of CR Field 0. In these cases, if OE=1 then OV is set 5512 * to 1. 5513 */ 5514 IRTemp res = newTemp(Ity_I32); 5515 IRExpr * dividend, * divisor; 5516 DIP("divweu%s%s r%u,r%u,r%u\n", 5517 flag_OE ? "o" : "", flag_rC ? ".":"", 5518 rD_addr, rA_addr, rB_addr); 5519 if (mode64) { 5520 dividend = unop( Iop_64to32, mkexpr( rA ) ); 5521 divisor = unop( Iop_64to32, mkexpr( rB ) ); 5522 assign( res, binop( Iop_DivU32E, dividend, divisor ) ); 5523 assign( rD, binop( Iop_32HLto64, mkU32( 0 ), mkexpr( res ) ) ); 5524 } else { 5525 dividend = mkexpr( rA ); 5526 divisor = mkexpr( rB ); 5527 assign( res, binop( Iop_DivU32E, dividend, divisor ) ); 5528 assign( rD, mkexpr( res) ); 5529 } 5530 5531 if (flag_OE) { 5532 set_XER_OV_OV32_32( PPCG_FLAG_OP_DIVWEU, 5533 mkexpr(res), dividend, divisor ); 5534 update_SO( ); 5535 } 5536 break; 5537 } 5538 5539 case 0x1AB: // divwe (Divide Word Extended) 5540 { 5541 /* 5542 * If the quotient cannot be represented in 32 bits, or if an 5543 * attempt is made to perform the division 5544 * <anything> / 0 5545 * then the contents of register RD are undefined as are (if 5546 * Rc=1) the contents of the LT, GT, and EQ bits of CR 5547 * Field 0. In these cases, if OE=1 then OV is set to 1. 5548 */ 5549 5550 IRTemp res = newTemp(Ity_I32); 5551 IRExpr * dividend, * divisor; 5552 DIP("divwe%s%s r%u,r%u,r%u\n", 5553 flag_OE ? "o" : "", flag_rC ? ".":"", 5554 rD_addr, rA_addr, rB_addr); 5555 if (mode64) { 5556 dividend = unop( Iop_64to32, mkexpr( rA ) ); 5557 divisor = unop( Iop_64to32, mkexpr( rB ) ); 5558 assign( res, binop( Iop_DivS32E, dividend, divisor ) ); 5559 assign( rD, binop( Iop_32HLto64, mkU32( 0 ), mkexpr( res ) ) ); 5560 } else { 5561 dividend = mkexpr( rA ); 5562 divisor = mkexpr( rB ); 5563 assign( res, binop( Iop_DivS32E, dividend, divisor ) ); 5564 assign( rD, mkexpr( res) ); 5565 } 5566 5567 if (flag_OE) { 5568 set_XER_OV_OV32_32( PPCG_FLAG_OP_DIVWE, 5569 mkexpr(res), dividend, divisor ); 5570 update_SO( ); 5571 } 5572 break; 5573 } 5574 5575 5576 case 0x1A9: // divde (Divide Doubleword Extended) 5577 /* 5578 * If the quotient cannot be represented in 64 bits, or if an 5579 * attempt is made to perform the division 5580 * <anything> / 0 5581 * then the contents of register RD are undefined as are (if 5582 * Rc=1) the contents of the LT, GT, and EQ bits of CR 5583 * Field 0. In these cases, if OE=1 then OV is set to 1. 5584 */ 5585 DIP("divde%s%s r%u,r%u,r%u\n", 5586 flag_OE ? "o" : "", flag_rC ? ".":"", 5587 rD_addr, rA_addr, rB_addr); 5588 assign( rD, binop(Iop_DivS64E, mkexpr(rA), mkexpr(rB)) ); 5589 if (flag_OE) { 5590 set_XER_OV_64( PPCG_FLAG_OP_DIVDE, mkexpr( rD ), 5591 mkexpr( rA ), mkexpr( rB ) ); 5592 copy_OV_to_OV32(); 5593 update_SO(); 5594 } 5595 break; 5596 5597 case 0x189: // divdeuo (Divide Doubleword Extended Unsigned) 5598 // Same CR and OV rules as given for divweu above 5599 DIP("divdeu%s%s r%u,r%u,r%u\n", 5600 flag_OE ? "o" : "", flag_rC ? ".":"", 5601 rD_addr, rA_addr, rB_addr); 5602 assign( rD, binop(Iop_DivU64E, mkexpr(rA), mkexpr(rB)) ); 5603 if (flag_OE) { 5604 set_XER_OV_64( PPCG_FLAG_OP_DIVDEU, mkexpr( rD ), 5605 mkexpr( rA ), mkexpr( rB ) ); 5606 copy_OV_to_OV32(); 5607 update_SO(); 5608 } 5609 break; 5610 5611 default: 5612 vex_printf("dis_int_arith(ppc)(opc2)\n"); 5613 return False; 5614 } 5615 break; 5616 5617 default: 5618 vex_printf("dis_int_arith(ppc)(opc1)\n"); 5619 return False; 5620 } 5621 5622 putIReg( rD_addr, mkexpr(rD) );