1 2 3 /*--------------------------------------------------------------------*/ 4 /*--- begin guest_ppc_toIR.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2004-2012 OpenWorks LLP 12 info (at) open-works.net 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 27 02110-1301, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 31 Neither the names of the U.S. Department of Energy nor the 32 University of California nor the names of its contributors may be 33 used to endorse or promote products derived from this software 34 without prior written permission. 35 */ 36 37 /* TODO 18/Nov/05: 38 39 Spot rld... cases which are simply left/right shifts and emit 40 Shl64/Shr64 accordingly. 41 42 Altivec 43 - datastream insns 44 - lvxl,stvxl: load/store with 'least recently used' hint 45 - vexptefp, vlogefp 46 47 LIMITATIONS: 48 49 Various, including: 50 51 - Some invalid forms of lswi and lswx are accepted when they should 52 not be. 53 54 - Floating Point: 55 - All exceptions disabled in FPSCR 56 - condition codes not set in FPSCR 57 58 - Altivec floating point: 59 - vmaddfp, vnmsubfp 60 Because we're using Java/IEEE mode (FPSCR[NJ]), rather than the 61 system default of Non-Java mode, we get some small errors 62 (lowest bit only). 63 This is because Non-Java mode brutally hacks denormalised results 64 to zero, whereas we keep maximum accuracy. However, using 65 Non-Java mode would give us more inaccuracy, as our intermediate 66 results would then be zeroed, too. 67 68 - AbiHints for the stack red zone are only emitted for 69 unconditional calls and returns (bl, blr). They should also be 70 emitted for conditional calls and returns, but we don't have a 71 way to express that right now. Ah well. 72 */ 73 74 /* "Special" instructions. 75 76 This instruction decoder can decode four special instructions 77 which mean nothing natively (are no-ops as far as regs/mem are 78 concerned) but have meaning for supporting Valgrind. A special 79 instruction is flagged by a 16-byte preamble: 80 81 32-bit mode: 54001800 54006800 5400E800 54009800 82 (rlwinm 0,0,3,0,0; rlwinm 0,0,13,0,0; 83 rlwinm 0,0,29,0,0; rlwinm 0,0,19,0,0) 84 85 64-bit mode: 78001800 78006800 7800E802 78009802 86 (rotldi 0,0,3; rotldi 0,0,13; 87 rotldi 0,0,61; rotldi 0,0,51) 88 89 Following that, one of the following 3 are allowed 90 (standard interpretation in parentheses): 91 92 7C210B78 (or 1,1,1) %R3 = client_request ( %R4 ) 93 7C421378 (or 2,2,2) %R3 = guest_NRADDR 94 7C631B78 (or 3,3,3) branch-and-link-to-noredir %R11 95 7C842378 (or 4,4,4) %R3 = guest_NRADDR_GPR2 96 97 Any other bytes following the 16-byte preamble are illegal and 98 constitute a failure in instruction decoding. This all assumes 99 that the preamble will never occur except in specific code 100 fragments designed for Valgrind to catch. 101 */ 102 103 104 /* Translates PPC32/64 code to IR. */ 105 106 /* References 107 108 #define PPC32 109 "PowerPC Microprocessor Family: 110 The Programming Environments Manual for 32-Bit Microprocessors" 111 02/21/2000 112 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2 113 114 #define PPC64 115 "PowerPC Microprocessor Family: 116 Programming Environments Manual for 64-Bit Microprocessors" 117 06/10/2003 118 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/F7E732FF811F783187256FDD004D3797 119 120 #define AV 121 "PowerPC Microprocessor Family: 122 AltiVec(TM) Technology Programming Environments Manual" 123 07/10/2003 124 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/FBFA164F824370F987256D6A006F424D 125 */ 126 127 #include "libvex_basictypes.h" 128 #include "libvex_ir.h" 129 #include "libvex.h" 130 #include "libvex_guest_ppc32.h" 131 #include "libvex_guest_ppc64.h" 132 133 #include "main_util.h" 134 #include "main_globals.h" 135 #include "guest_generic_bb_to_IR.h" 136 #include "guest_ppc_defs.h" 137 138 139 /*------------------------------------------------------------*/ 140 /*--- Globals ---*/ 141 /*------------------------------------------------------------*/ 142 143 /* These are set at the start of the translation of an insn, right 144 down in disInstr_PPC, so that we don't have to pass them around 145 endlessly. They are all constant during the translation of any 146 given insn. */ 147 148 /* We need to know this to do sub-register accesses correctly. */ 149 static Bool host_is_bigendian; 150 151 /* Pointer to the guest code area. */ 152 static UChar* guest_code; 153 154 /* The guest address corresponding to guest_code[0]. */ 155 static Addr64 guest_CIA_bbstart; 156 157 /* The guest address for the instruction currently being 158 translated. */ 159 static Addr64 guest_CIA_curr_instr; 160 161 /* The IRSB* into which we're generating code. */ 162 static IRSB* irsb; 163 164 /* Is our guest binary 32 or 64bit? Set at each call to 165 disInstr_PPC below. */ 166 static Bool mode64 = False; 167 168 // Given a pointer to a function as obtained by "& functionname" in C, 169 // produce a pointer to the actual entry point for the function. For 170 // most platforms it's the identity function. Unfortunately, on 171 // ppc64-linux it isn't (sigh) and ditto for ppc32-aix5 and 172 // ppc64-aix5. 173 static void* fnptr_to_fnentry( VexAbiInfo* vbi, void* f ) 174 { 175 if (vbi->host_ppc_calls_use_fndescrs) { 176 /* f is a pointer to a 3-word function descriptor, of which the 177 first word is the entry address. */ 178 /* note, this is correct even with cross-jitting, since this is 179 purely a host issue, not a guest one. */ 180 HWord* fdescr = (HWord*)f; 181 return (void*)(fdescr[0]); 182 } else { 183 /* Simple; "& f" points directly at the code for f. */ 184 return f; 185 } 186 } 187 188 #define SIGN_BIT 0x8000000000000000ULL 189 #define SIGN_MASK 0x7fffffffffffffffULL 190 #define SIGN_BIT32 0x80000000 191 #define SIGN_MASK32 0x7fffffff 192 193 194 /*------------------------------------------------------------*/ 195 /*--- Debugging output ---*/ 196 /*------------------------------------------------------------*/ 197 198 #define DIP(format, args...) \ 199 if (vex_traceflags & VEX_TRACE_FE) \ 200 vex_printf(format, ## args) 201 202 #define DIS(buf, format, args...) \ 203 if (vex_traceflags & VEX_TRACE_FE) \ 204 vex_sprintf(buf, format, ## args) 205 206 207 /*------------------------------------------------------------*/ 208 /*--- Offsets of various parts of the ppc32/64 guest state ---*/ 209 /*------------------------------------------------------------*/ 210 211 #define offsetofPPCGuestState(_x) \ 212 (mode64 ? offsetof(VexGuestPPC64State, _x) : \ 213 offsetof(VexGuestPPC32State, _x)) 214 215 #define OFFB_CIA offsetofPPCGuestState(guest_CIA) 216 #define OFFB_IP_AT_SYSCALL offsetofPPCGuestState(guest_IP_AT_SYSCALL) 217 #define OFFB_SPRG3_RO offsetofPPCGuestState(guest_SPRG3_RO) 218 #define OFFB_LR offsetofPPCGuestState(guest_LR) 219 #define OFFB_CTR offsetofPPCGuestState(guest_CTR) 220 #define OFFB_XER_SO offsetofPPCGuestState(guest_XER_SO) 221 #define OFFB_XER_OV offsetofPPCGuestState(guest_XER_OV) 222 #define OFFB_XER_CA offsetofPPCGuestState(guest_XER_CA) 223 #define OFFB_XER_BC offsetofPPCGuestState(guest_XER_BC) 224 #define OFFB_FPROUND offsetofPPCGuestState(guest_FPROUND) 225 #define OFFB_DFPROUND offsetofPPCGuestState(guest_DFPROUND) 226 #define OFFB_VRSAVE offsetofPPCGuestState(guest_VRSAVE) 227 #define OFFB_VSCR offsetofPPCGuestState(guest_VSCR) 228 #define OFFB_EMWARN offsetofPPCGuestState(guest_EMWARN) 229 #define OFFB_TISTART offsetofPPCGuestState(guest_TISTART) 230 #define OFFB_TILEN offsetofPPCGuestState(guest_TILEN) 231 #define OFFB_NRADDR offsetofPPCGuestState(guest_NRADDR) 232 #define OFFB_NRADDR_GPR2 offsetofPPCGuestState(guest_NRADDR_GPR2) 233 234 235 /*------------------------------------------------------------*/ 236 /*--- Extract instruction fields --- */ 237 /*------------------------------------------------------------*/ 238 239 /* Extract field from insn, given idx (zero = lsb) and field length */ 240 #define IFIELD( insn, idx, len ) ((insn >> idx) & ((1<<len)-1)) 241 242 /* Extract primary opcode, instr[31:26] */ 243 static UChar ifieldOPC( UInt instr ) { 244 return toUChar( IFIELD( instr, 26, 6 ) ); 245 } 246 247 /* Extract 10-bit secondary opcode, instr[10:1] */ 248 static UInt ifieldOPClo10 ( UInt instr) { 249 return IFIELD( instr, 1, 10 ); 250 } 251 252 /* Extract 9-bit secondary opcode, instr[9:1] */ 253 static UInt ifieldOPClo9 ( UInt instr) { 254 return IFIELD( instr, 1, 9 ); 255 } 256 257 /* Extract 8-bit secondary opcode, instr[8:1] */ 258 static UInt ifieldOPClo8 ( UInt instr) { 259 return IFIELD( instr, 1, 8 ); 260 } 261 262 /* Extract 5-bit secondary opcode, instr[5:1] */ 263 static UInt ifieldOPClo5 ( UInt instr) { 264 return IFIELD( instr, 1, 5 ); 265 } 266 267 /* Extract RD (destination register) field, instr[25:21] */ 268 static UChar ifieldRegDS( UInt instr ) { 269 return toUChar( IFIELD( instr, 21, 5 ) ); 270 } 271 272 /* Extract XT (destination register) field, instr[0,25:21] */ 273 static UChar ifieldRegXT ( UInt instr ) 274 { 275 UChar upper_bit = toUChar (IFIELD (instr, 0, 1)); 276 UChar lower_bits = toUChar (IFIELD (instr, 21, 5)); 277 return (upper_bit << 5) | lower_bits; 278 } 279 280 /* Extract XS (store source register) field, instr[0,25:21] */ 281 static inline UChar ifieldRegXS ( UInt instr ) 282 { 283 return ifieldRegXT ( instr ); 284 } 285 286 /* Extract RA (1st source register) field, instr[20:16] */ 287 static UChar ifieldRegA ( UInt instr ) { 288 return toUChar( IFIELD( instr, 16, 5 ) ); 289 } 290 291 /* Extract XA (1st source register) field, instr[2,20:16] */ 292 static UChar ifieldRegXA ( UInt instr ) 293 { 294 UChar upper_bit = toUChar (IFIELD (instr, 2, 1)); 295 UChar lower_bits = toUChar (IFIELD (instr, 16, 5)); 296 return (upper_bit << 5) | lower_bits; 297 } 298 299 /* Extract RB (2nd source register) field, instr[15:11] */ 300 static UChar ifieldRegB ( UInt instr ) { 301 return toUChar( IFIELD( instr, 11, 5 ) ); 302 } 303 304 /* Extract XB (2nd source register) field, instr[1,15:11] */ 305 static UChar ifieldRegXB ( UInt instr ) 306 { 307 UChar upper_bit = toUChar (IFIELD (instr, 1, 1)); 308 UChar lower_bits = toUChar (IFIELD (instr, 11, 5)); 309 return (upper_bit << 5) | lower_bits; 310 } 311 312 /* Extract RC (3rd source register) field, instr[10:6] */ 313 static UChar ifieldRegC ( UInt instr ) { 314 return toUChar( IFIELD( instr, 6, 5 ) ); 315 } 316 317 /* Extract XC (3rd source register) field, instr[3,10:6] */ 318 static UChar ifieldRegXC ( UInt instr ) 319 { 320 UChar upper_bit = toUChar (IFIELD (instr, 3, 1)); 321 UChar lower_bits = toUChar (IFIELD (instr, 6, 5)); 322 return (upper_bit << 5) | lower_bits; 323 } 324 325 /* Extract bit 10, instr[10] */ 326 static UChar ifieldBIT10 ( UInt instr ) { 327 return toUChar( IFIELD( instr, 10, 1 ) ); 328 } 329 330 /* Extract 2nd lowest bit, instr[1] */ 331 static UChar ifieldBIT1 ( UInt instr ) { 332 return toUChar( IFIELD( instr, 1, 1 ) ); 333 } 334 335 /* Extract lowest bit, instr[0] */ 336 static UChar ifieldBIT0 ( UInt instr ) { 337 return toUChar( instr & 0x1 ); 338 } 339 340 /* Extract unsigned bottom half, instr[15:0] */ 341 static UInt ifieldUIMM16 ( UInt instr ) { 342 return instr & 0xFFFF; 343 } 344 345 /* Extract unsigned bottom 26 bits, instr[25:0] */ 346 static UInt ifieldUIMM26 ( UInt instr ) { 347 return instr & 0x3FFFFFF; 348 } 349 350 /* Extract DM field, instr[9:8] */ 351 static UChar ifieldDM ( UInt instr ) { 352 return toUChar( IFIELD( instr, 8, 2 ) ); 353 } 354 355 /* Extract SHW field, instr[9:8] */ 356 static inline UChar ifieldSHW ( UInt instr ) 357 { 358 return ifieldDM ( instr ); 359 } 360 361 /*------------------------------------------------------------*/ 362 /*--- Guest-state identifiers ---*/ 363 /*------------------------------------------------------------*/ 364 365 typedef enum { 366 PPC_GST_CIA, // Current Instruction Address 367 PPC_GST_LR, // Link Register 368 PPC_GST_CTR, // Count Register 369 PPC_GST_XER, // Overflow, carry flags, byte count 370 PPC_GST_CR, // Condition Register 371 PPC_GST_FPSCR, // Floating Point Status/Control Register 372 PPC_GST_VRSAVE, // Vector Save/Restore Register 373 PPC_GST_VSCR, // Vector Status and Control Register 374 PPC_GST_EMWARN, // Emulation warnings 375 PPC_GST_TISTART,// For icbi: start of area to invalidate 376 PPC_GST_TILEN, // For icbi: length of area to invalidate 377 PPC_GST_IP_AT_SYSCALL, // the CIA of the most recently executed SC insn 378 PPC_GST_SPRG3_RO, // SPRG3 379 PPC_GST_MAX 380 } PPC_GST; 381 382 #define MASK_FPSCR_RN 0x3ULL // Binary floating point rounding mode 383 #define MASK_FPSCR_DRN 0x700000000ULL // Decimal floating point rounding mode 384 #define MASK_VSCR_VALID 0x00010001 385 386 387 /*------------------------------------------------------------*/ 388 /*--- FP Helpers ---*/ 389 /*------------------------------------------------------------*/ 390 391 /* Produce the 32-bit pattern corresponding to the supplied 392 float. */ 393 static UInt float_to_bits ( Float f ) 394 { 395 union { UInt i; Float f; } u; 396 vassert(4 == sizeof(UInt)); 397 vassert(4 == sizeof(Float)); 398 vassert(4 == sizeof(u)); 399 u.f = f; 400 return u.i; 401 } 402 403 404 /*------------------------------------------------------------*/ 405 /*--- Misc Helpers ---*/ 406 /*------------------------------------------------------------*/ 407 408 /* Generate mask with 1's from 'begin' through 'end', 409 wrapping if begin > end. 410 begin->end works from right to left, 0=lsb 411 */ 412 static UInt MASK32( UInt begin, UInt end ) 413 { 414 UInt m1, m2, mask; 415 vassert(begin < 32); 416 vassert(end < 32); 417 m1 = ((UInt)(-1)) << begin; 418 m2 = ((UInt)(-1)) << end << 1; 419 mask = m1 ^ m2; 420 if (begin > end) mask = ~mask; // wrap mask 421 return mask; 422 } 423 424 static ULong MASK64( UInt begin, UInt end ) 425 { 426 ULong m1, m2, mask; 427 vassert(begin < 64); 428 vassert(end < 64); 429 m1 = ((ULong)(-1)) << begin; 430 m2 = ((ULong)(-1)) << end << 1; 431 mask = m1 ^ m2; 432 if (begin > end) mask = ~mask; // wrap mask 433 return mask; 434 } 435 436 static Addr64 nextInsnAddr( void ) 437 { 438 return guest_CIA_curr_instr + 4; 439 } 440 441 442 /*------------------------------------------------------------*/ 443 /*--- Helper bits and pieces for deconstructing the ---*/ 444 /*--- ppc32/64 insn stream. ---*/ 445 /*------------------------------------------------------------*/ 446 447 /* Add a statement to the list held by "irsb". */ 448 static void stmt ( IRStmt* st ) 449 { 450 addStmtToIRSB( irsb, st ); 451 } 452 453 /* Generate a new temporary of the given type. */ 454 static IRTemp newTemp ( IRType ty ) 455 { 456 vassert(isPlausibleIRType(ty)); 457 return newIRTemp( irsb->tyenv, ty ); 458 } 459 460 /* Various simple conversions */ 461 462 static UChar extend_s_5to8 ( UChar x ) 463 { 464 return toUChar((((Int)x) << 27) >> 27); 465 } 466 467 static UInt extend_s_8to32( UChar x ) 468 { 469 return (UInt)((((Int)x) << 24) >> 24); 470 } 471 472 static UInt extend_s_16to32 ( UInt x ) 473 { 474 return (UInt)((((Int)x) << 16) >> 16); 475 } 476 477 static ULong extend_s_16to64 ( UInt x ) 478 { 479 return (ULong)((((Long)x) << 48) >> 48); 480 } 481 482 static ULong extend_s_26to64 ( UInt x ) 483 { 484 return (ULong)((((Long)x) << 38) >> 38); 485 } 486 487 static ULong extend_s_32to64 ( UInt x ) 488 { 489 return (ULong)((((Long)x) << 32) >> 32); 490 } 491 492 /* Do a big-endian load of a 32-bit word, regardless of the endianness 493 of the underlying host. */ 494 static UInt getUIntBigendianly ( UChar* p ) 495 { 496 UInt w = 0; 497 w = (w << 8) | p[0]; 498 w = (w << 8) | p[1]; 499 w = (w << 8) | p[2]; 500 w = (w << 8) | p[3]; 501 return w; 502 } 503 504 505 /*------------------------------------------------------------*/ 506 /*--- Helpers for constructing IR. ---*/ 507 /*------------------------------------------------------------*/ 508 509 static void assign ( IRTemp dst, IRExpr* e ) 510 { 511 stmt( IRStmt_WrTmp(dst, e) ); 512 } 513 514 /* This generates a normal (non store-conditional) store. */ 515 static void storeBE ( IRExpr* addr, IRExpr* data ) 516 { 517 IRType tyA = typeOfIRExpr(irsb->tyenv, addr); 518 vassert(tyA == Ity_I32 || tyA == Ity_I64); 519 stmt( IRStmt_Store(Iend_BE, addr, data) ); 520 } 521 522 static IRExpr* unop ( IROp op, IRExpr* a ) 523 { 524 return IRExpr_Unop(op, a); 525 } 526 527 static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ) 528 { 529 return IRExpr_Binop(op, a1, a2); 530 } 531 532 static IRExpr* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 ) 533 { 534 return IRExpr_Triop(op, a1, a2, a3); 535 } 536 537 static IRExpr* qop ( IROp op, IRExpr* a1, IRExpr* a2, 538 IRExpr* a3, IRExpr* a4 ) 539 { 540 return IRExpr_Qop(op, a1, a2, a3, a4); 541 } 542 543 static IRExpr* mkexpr ( IRTemp tmp ) 544 { 545 return IRExpr_RdTmp(tmp); 546 } 547 548 static IRExpr* mkU8 ( UChar i ) 549 { 550 return IRExpr_Const(IRConst_U8(i)); 551 } 552 553 static IRExpr* mkU16 ( UInt i ) 554 { 555 return IRExpr_Const(IRConst_U16(i)); 556 } 557 558 static IRExpr* mkU32 ( UInt i ) 559 { 560 return IRExpr_Const(IRConst_U32(i)); 561 } 562 563 static IRExpr* mkU64 ( ULong i ) 564 { 565 return IRExpr_Const(IRConst_U64(i)); 566 } 567 568 static IRExpr* mkV128 ( UShort i ) 569 { 570 vassert(i == 0 || i == 0xffff); 571 return IRExpr_Const(IRConst_V128(i)); 572 } 573 574 /* This generates a normal (non load-linked) load. */ 575 static IRExpr* loadBE ( IRType ty, IRExpr* addr ) 576 { 577 return IRExpr_Load(Iend_BE, ty, addr); 578 } 579 580 static IRExpr* mkOR1 ( IRExpr* arg1, IRExpr* arg2 ) 581 { 582 vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1); 583 vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1); 584 return unop(Iop_32to1, binop(Iop_Or32, unop(Iop_1Uto32, arg1), 585 unop(Iop_1Uto32, arg2))); 586 } 587 588 static IRExpr* mkAND1 ( IRExpr* arg1, IRExpr* arg2 ) 589 { 590 vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1); 591 vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1); 592 return unop(Iop_32to1, binop(Iop_And32, unop(Iop_1Uto32, arg1), 593 unop(Iop_1Uto32, arg2))); 594 } 595 596 /* expand V128_8Ux16 to 2x V128_16Ux8's */ 597 static void expand8Ux16( IRExpr* vIn, 598 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 599 { 600 IRTemp ones8x16 = newTemp(Ity_V128); 601 602 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 603 vassert(vEvn && *vEvn == IRTemp_INVALID); 604 vassert(vOdd && *vOdd == IRTemp_INVALID); 605 *vEvn = newTemp(Ity_V128); 606 *vOdd = newTemp(Ity_V128); 607 608 assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); 609 assign( *vOdd, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), vIn) ); 610 assign( *vEvn, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), 611 binop(Iop_ShrV128, vIn, mkU8(8))) ); 612 } 613 614 /* expand V128_8Sx16 to 2x V128_16Sx8's */ 615 static void expand8Sx16( IRExpr* vIn, 616 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 617 { 618 IRTemp ones8x16 = newTemp(Ity_V128); 619 620 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 621 vassert(vEvn && *vEvn == IRTemp_INVALID); 622 vassert(vOdd && *vOdd == IRTemp_INVALID); 623 *vEvn = newTemp(Ity_V128); 624 *vOdd = newTemp(Ity_V128); 625 626 assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); 627 assign( *vOdd, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), vIn) ); 628 assign( *vEvn, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), 629 binop(Iop_ShrV128, vIn, mkU8(8))) ); 630 } 631 632 /* expand V128_16Uto8 to 2x V128_32Ux4's */ 633 static void expand16Ux8( IRExpr* vIn, 634 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 635 { 636 IRTemp ones16x8 = newTemp(Ity_V128); 637 638 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 639 vassert(vEvn && *vEvn == IRTemp_INVALID); 640 vassert(vOdd && *vOdd == IRTemp_INVALID); 641 *vEvn = newTemp(Ity_V128); 642 *vOdd = newTemp(Ity_V128); 643 644 assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); 645 assign( *vOdd, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), vIn) ); 646 assign( *vEvn, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), 647 binop(Iop_ShrV128, vIn, mkU8(16))) ); 648 } 649 650 /* expand V128_16Sto8 to 2x V128_32Sx4's */ 651 static void expand16Sx8( IRExpr* vIn, 652 /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ) 653 { 654 IRTemp ones16x8 = newTemp(Ity_V128); 655 656 vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128); 657 vassert(vEvn && *vEvn == IRTemp_INVALID); 658 vassert(vOdd && *vOdd == IRTemp_INVALID); 659 *vEvn = newTemp(Ity_V128); 660 *vOdd = newTemp(Ity_V128); 661 662 assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); 663 assign( *vOdd, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), vIn) ); 664 assign( *vEvn, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), 665 binop(Iop_ShrV128, vIn, mkU8(16))) ); 666 } 667 668 /* break V128 to 4xF64's*/ 669 static void breakV128to4xF64( IRExpr* t128, 670 /*OUTs*/ 671 IRTemp* t3, IRTemp* t2, 672 IRTemp* t1, IRTemp* t0 ) 673 { 674 IRTemp hi64 = newTemp(Ity_I64); 675 IRTemp lo64 = newTemp(Ity_I64); 676 677 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 678 vassert(t0 && *t0 == IRTemp_INVALID); 679 vassert(t1 && *t1 == IRTemp_INVALID); 680 vassert(t2 && *t2 == IRTemp_INVALID); 681 vassert(t3 && *t3 == IRTemp_INVALID); 682 *t0 = newTemp(Ity_F64); 683 *t1 = newTemp(Ity_F64); 684 *t2 = newTemp(Ity_F64); 685 *t3 = newTemp(Ity_F64); 686 687 assign( hi64, unop(Iop_V128HIto64, t128) ); 688 assign( lo64, unop(Iop_V128to64, t128) ); 689 assign( *t3, 690 unop( Iop_F32toF64, 691 unop( Iop_ReinterpI32asF32, 692 unop( Iop_64HIto32, mkexpr( hi64 ) ) ) ) ); 693 assign( *t2, 694 unop( Iop_F32toF64, 695 unop( Iop_ReinterpI32asF32, unop( Iop_64to32, mkexpr( hi64 ) ) ) ) ); 696 assign( *t1, 697 unop( Iop_F32toF64, 698 unop( Iop_ReinterpI32asF32, 699 unop( Iop_64HIto32, mkexpr( lo64 ) ) ) ) ); 700 assign( *t0, 701 unop( Iop_F32toF64, 702 unop( Iop_ReinterpI32asF32, unop( Iop_64to32, mkexpr( lo64 ) ) ) ) ); 703 } 704 705 706 /* break V128 to 4xI32's, then sign-extend to I64's */ 707 static void breakV128to4x64S( IRExpr* t128, 708 /*OUTs*/ 709 IRTemp* t3, IRTemp* t2, 710 IRTemp* t1, IRTemp* t0 ) 711 { 712 IRTemp hi64 = newTemp(Ity_I64); 713 IRTemp lo64 = newTemp(Ity_I64); 714 715 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 716 vassert(t0 && *t0 == IRTemp_INVALID); 717 vassert(t1 && *t1 == IRTemp_INVALID); 718 vassert(t2 && *t2 == IRTemp_INVALID); 719 vassert(t3 && *t3 == IRTemp_INVALID); 720 *t0 = newTemp(Ity_I64); 721 *t1 = newTemp(Ity_I64); 722 *t2 = newTemp(Ity_I64); 723 *t3 = newTemp(Ity_I64); 724 725 assign( hi64, unop(Iop_V128HIto64, t128) ); 726 assign( lo64, unop(Iop_V128to64, t128) ); 727 assign( *t3, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(hi64))) ); 728 assign( *t2, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(hi64))) ); 729 assign( *t1, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(lo64))) ); 730 assign( *t0, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(lo64))) ); 731 } 732 733 /* break V128 to 4xI32's, then zero-extend to I64's */ 734 static void breakV128to4x64U ( IRExpr* t128, 735 /*OUTs*/ 736 IRTemp* t3, IRTemp* t2, 737 IRTemp* t1, IRTemp* t0 ) 738 { 739 IRTemp hi64 = newTemp(Ity_I64); 740 IRTemp lo64 = newTemp(Ity_I64); 741 742 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 743 vassert(t0 && *t0 == IRTemp_INVALID); 744 vassert(t1 && *t1 == IRTemp_INVALID); 745 vassert(t2 && *t2 == IRTemp_INVALID); 746 vassert(t3 && *t3 == IRTemp_INVALID); 747 *t0 = newTemp(Ity_I64); 748 *t1 = newTemp(Ity_I64); 749 *t2 = newTemp(Ity_I64); 750 *t3 = newTemp(Ity_I64); 751 752 assign( hi64, unop(Iop_V128HIto64, t128) ); 753 assign( lo64, unop(Iop_V128to64, t128) ); 754 assign( *t3, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(hi64))) ); 755 assign( *t2, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(hi64))) ); 756 assign( *t1, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(lo64))) ); 757 assign( *t0, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(lo64))) ); 758 } 759 760 static void breakV128to4x32( IRExpr* t128, 761 /*OUTs*/ 762 IRTemp* t3, IRTemp* t2, 763 IRTemp* t1, IRTemp* t0 ) 764 { 765 IRTemp hi64 = newTemp(Ity_I64); 766 IRTemp lo64 = newTemp(Ity_I64); 767 768 vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128); 769 vassert(t0 && *t0 == IRTemp_INVALID); 770 vassert(t1 && *t1 == IRTemp_INVALID); 771 vassert(t2 && *t2 == IRTemp_INVALID); 772 vassert(t3 && *t3 == IRTemp_INVALID); 773 *t0 = newTemp(Ity_I32); 774 *t1 = newTemp(Ity_I32); 775 *t2 = newTemp(Ity_I32); 776 *t3 = newTemp(Ity_I32); 777 778 assign( hi64, unop(Iop_V128HIto64, t128) ); 779 assign( lo64, unop(Iop_V128to64, t128) ); 780 assign( *t3, unop(Iop_64HIto32, mkexpr(hi64)) ); 781 assign( *t2, unop(Iop_64to32, mkexpr(hi64)) ); 782 assign( *t1, unop(Iop_64HIto32, mkexpr(lo64)) ); 783 assign( *t0, unop(Iop_64to32, mkexpr(lo64)) ); 784 } 785 786 787 /* Signed saturating narrow 64S to 32 */ 788 static IRExpr* mkQNarrow64Sto32 ( IRExpr* t64 ) 789 { 790 IRTemp hi32 = newTemp(Ity_I32); 791 IRTemp lo32 = newTemp(Ity_I32); 792 793 vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64); 794 795 assign( hi32, unop(Iop_64HIto32, t64)); 796 assign( lo32, unop(Iop_64to32, t64)); 797 798 return IRExpr_Mux0X( 799 /* if (hi32 == (lo32 >>s 31)) */ 800 unop(Iop_1Uto8, 801 binop(Iop_CmpEQ32, mkexpr(hi32), 802 binop( Iop_Sar32, mkexpr(lo32), mkU8(31)))), 803 /* else: sign dep saturate: 1->0x80000000, 0->0x7FFFFFFF */ 804 binop(Iop_Add32, mkU32(0x7FFFFFFF), 805 binop(Iop_Shr32, mkexpr(hi32), mkU8(31))), 806 /* then: within signed-32 range: lo half good enough */ 807 mkexpr(lo32) ); 808 } 809 810 /* Unsigned saturating narrow 64S to 32 */ 811 static IRExpr* mkQNarrow64Uto32 ( IRExpr* t64 ) 812 { 813 IRTemp hi32 = newTemp(Ity_I32); 814 IRTemp lo32 = newTemp(Ity_I32); 815 816 vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64); 817 818 assign( hi32, unop(Iop_64HIto32, t64)); 819 assign( lo32, unop(Iop_64to32, t64)); 820 821 return IRExpr_Mux0X( 822 /* if (top 32 bits of t64 are 0) */ 823 unop(Iop_1Uto8, binop(Iop_CmpEQ32, mkexpr(hi32), mkU32(0))), 824 /* else: positive saturate -> 0xFFFFFFFF */ 825 mkU32(0xFFFFFFFF), 826 /* then: within unsigned-32 range: lo half good enough */ 827 mkexpr(lo32) ); 828 } 829 830 /* Signed saturate narrow 64->32, combining to V128 */ 831 static IRExpr* mkV128from4x64S ( IRExpr* t3, IRExpr* t2, 832 IRExpr* t1, IRExpr* t0 ) 833 { 834 vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64); 835 vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64); 836 vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64); 837 vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64); 838 return binop(Iop_64HLtoV128, 839 binop(Iop_32HLto64, 840 mkQNarrow64Sto32( t3 ), 841 mkQNarrow64Sto32( t2 )), 842 binop(Iop_32HLto64, 843 mkQNarrow64Sto32( t1 ), 844 mkQNarrow64Sto32( t0 ))); 845 } 846 847 /* Unsigned saturate narrow 64->32, combining to V128 */ 848 static IRExpr* mkV128from4x64U ( IRExpr* t3, IRExpr* t2, 849 IRExpr* t1, IRExpr* t0 ) 850 { 851 vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64); 852 vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64); 853 vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64); 854 vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64); 855 return binop(Iop_64HLtoV128, 856 binop(Iop_32HLto64, 857 mkQNarrow64Uto32( t3 ), 858 mkQNarrow64Uto32( t2 )), 859 binop(Iop_32HLto64, 860 mkQNarrow64Uto32( t1 ), 861 mkQNarrow64Uto32( t0 ))); 862 } 863 864 /* Simulate irops Iop_MullOdd*, since we don't have them */ 865 #define MK_Iop_MullOdd8Ux16( expr_vA, expr_vB ) \ 866 binop(Iop_MullEven8Ux16, \ 867 binop(Iop_ShrV128, expr_vA, mkU8(8)), \ 868 binop(Iop_ShrV128, expr_vB, mkU8(8))) 869 870 #define MK_Iop_MullOdd8Sx16( expr_vA, expr_vB ) \ 871 binop(Iop_MullEven8Sx16, \ 872 binop(Iop_ShrV128, expr_vA, mkU8(8)), \ 873 binop(Iop_ShrV128, expr_vB, mkU8(8))) 874 875 #define MK_Iop_MullOdd16Ux8( expr_vA, expr_vB ) \ 876 binop(Iop_MullEven16Ux8, \ 877 binop(Iop_ShrV128, expr_vA, mkU8(16)), \ 878 binop(Iop_ShrV128, expr_vB, mkU8(16))) 879 880 #define MK_Iop_MullOdd16Sx8( expr_vA, expr_vB ) \ 881 binop(Iop_MullEven16Sx8, \ 882 binop(Iop_ShrV128, expr_vA, mkU8(16)), \ 883 binop(Iop_ShrV128, expr_vB, mkU8(16))) 884 885 static IRExpr* /* :: Ity_I64 */ mk64lo32Sto64 ( IRExpr* src ) 886 { 887 vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64); 888 return unop(Iop_32Sto64, unop(Iop_64to32, src)); 889 } 890 891 static IRExpr* /* :: Ity_I64 */ mk64lo32Uto64 ( IRExpr* src ) 892 { 893 vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64); 894 return unop(Iop_32Uto64, unop(Iop_64to32, src)); 895 } 896 897 static IROp mkSzOp ( IRType ty, IROp op8 ) 898 { 899 Int adj; 900 vassert(ty == Ity_I8 || ty == Ity_I16 || 901 ty == Ity_I32 || ty == Ity_I64); 902 vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 || 903 op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 || 904 op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 || 905 op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || 906 op8 == Iop_Not8 ); 907 adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : (ty==Ity_I32 ? 2 : 3)); 908 return adj + op8; 909 } 910 911 /* Make sure we get valid 32 and 64bit addresses */ 912 static Addr64 mkSzAddr ( IRType ty, Addr64 addr ) 913 { 914 vassert(ty == Ity_I32 || ty == Ity_I64); 915 return ( ty == Ity_I64 ? 916 (Addr64)addr : 917 (Addr64)extend_s_32to64( toUInt(addr) ) ); 918 } 919 920 /* sz, ULong -> IRExpr */ 921 static IRExpr* mkSzImm ( IRType ty, ULong imm64 ) 922 { 923 vassert(ty == Ity_I32 || ty == Ity_I64); 924 return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt)imm64); 925 } 926 927 /* sz, ULong -> IRConst */ 928 static IRConst* mkSzConst ( IRType ty, ULong imm64 ) 929 { 930 vassert(ty == Ity_I32 || ty == Ity_I64); 931 return ( ty == Ity_I64 ? 932 IRConst_U64(imm64) : 933 IRConst_U32((UInt)imm64) ); 934 } 935 936 /* Sign extend imm16 -> IRExpr* */ 937 static IRExpr* mkSzExtendS16 ( IRType ty, UInt imm16 ) 938 { 939 vassert(ty == Ity_I32 || ty == Ity_I64); 940 return ( ty == Ity_I64 ? 941 mkU64(extend_s_16to64(imm16)) : 942 mkU32(extend_s_16to32(imm16)) ); 943 } 944 945 /* Sign extend imm32 -> IRExpr* */ 946 static IRExpr* mkSzExtendS32 ( IRType ty, UInt imm32 ) 947 { 948 vassert(ty == Ity_I32 || ty == Ity_I64); 949 return ( ty == Ity_I64 ? 950 mkU64(extend_s_32to64(imm32)) : 951 mkU32(imm32) ); 952 } 953 954 /* IR narrows I32/I64 -> I8/I16/I32 */ 955 static IRExpr* mkNarrowTo8 ( IRType ty, IRExpr* src ) 956 { 957 vassert(ty == Ity_I32 || ty == Ity_I64); 958 return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src); 959 } 960 961 static IRExpr* mkNarrowTo16 ( IRType ty, IRExpr* src ) 962 { 963 vassert(ty == Ity_I32 || ty == Ity_I64); 964 return ty == Ity_I64 ? unop(Iop_64to16, src) : unop(Iop_32to16, src); 965 } 966 967 static IRExpr* mkNarrowTo32 ( IRType ty, IRExpr* src ) 968 { 969 vassert(ty == Ity_I32 || ty == Ity_I64); 970 return ty == Ity_I64 ? unop(Iop_64to32, src) : src; 971 } 972 973 /* Signed/Unsigned IR widens I8/I16/I32 -> I32/I64 */ 974 static IRExpr* mkWidenFrom8 ( IRType ty, IRExpr* src, Bool sined ) 975 { 976 IROp op; 977 vassert(ty == Ity_I32 || ty == Ity_I64); 978 if (sined) op = (ty==Ity_I32) ? Iop_8Sto32 : Iop_8Sto64; 979 else op = (ty==Ity_I32) ? Iop_8Uto32 : Iop_8Uto64; 980 return unop(op, src); 981 } 982 983 static IRExpr* mkWidenFrom16 ( IRType ty, IRExpr* src, Bool sined ) 984 { 985 IROp op; 986 vassert(ty == Ity_I32 || ty == Ity_I64); 987 if (sined) op = (ty==Ity_I32) ? Iop_16Sto32 : Iop_16Sto64; 988 else op = (ty==Ity_I32) ? Iop_16Uto32 : Iop_16Uto64; 989 return unop(op, src); 990 } 991 992 static IRExpr* mkWidenFrom32 ( IRType ty, IRExpr* src, Bool sined ) 993 { 994 vassert(ty == Ity_I32 || ty == Ity_I64); 995 if (ty == Ity_I32) 996 return src; 997 return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src); 998 } 999 1000 1001 static Int integerGuestRegOffset ( UInt archreg ) 1002 { 1003 vassert(archreg < 32); 1004 1005 // jrs: probably not necessary; only matters if we reference sub-parts 1006 // of the ppc registers, but that isn't the case 1007 // later: this might affect Altivec though? 1008 vassert(host_is_bigendian); 1009 1010 switch (archreg) { 1011 case 0: return offsetofPPCGuestState(guest_GPR0); 1012 case 1: return offsetofPPCGuestState(guest_GPR1); 1013 case 2: return offsetofPPCGuestState(guest_GPR2); 1014 case 3: return offsetofPPCGuestState(guest_GPR3); 1015 case 4: return offsetofPPCGuestState(guest_GPR4); 1016 case 5: return offsetofPPCGuestState(guest_GPR5); 1017 case 6: return offsetofPPCGuestState(guest_GPR6); 1018 case 7: return offsetofPPCGuestState(guest_GPR7); 1019 case 8: return offsetofPPCGuestState(guest_GPR8); 1020 case 9: return offsetofPPCGuestState(guest_GPR9); 1021 case 10: return offsetofPPCGuestState(guest_GPR10); 1022 case 11: return offsetofPPCGuestState(guest_GPR11); 1023 case 12: return offsetofPPCGuestState(guest_GPR12); 1024 case 13: return offsetofPPCGuestState(guest_GPR13); 1025 case 14: return offsetofPPCGuestState(guest_GPR14); 1026 case 15: return offsetofPPCGuestState(guest_GPR15); 1027 case 16: return offsetofPPCGuestState(guest_GPR16); 1028 case 17: return offsetofPPCGuestState(guest_GPR17); 1029 case 18: return offsetofPPCGuestState(guest_GPR18); 1030 case 19: return offsetofPPCGuestState(guest_GPR19); 1031 case 20: return offsetofPPCGuestState(guest_GPR20); 1032 case 21: return offsetofPPCGuestState(guest_GPR21); 1033 case 22: return offsetofPPCGuestState(guest_GPR22); 1034 case 23: return offsetofPPCGuestState(guest_GPR23); 1035 case 24: return offsetofPPCGuestState(guest_GPR24); 1036 case 25: return offsetofPPCGuestState(guest_GPR25); 1037 case 26: return offsetofPPCGuestState(guest_GPR26); 1038 case 27: return offsetofPPCGuestState(guest_GPR27); 1039 case 28: return offsetofPPCGuestState(guest_GPR28); 1040 case 29: return offsetofPPCGuestState(guest_GPR29); 1041 case 30: return offsetofPPCGuestState(guest_GPR30); 1042 case 31: return offsetofPPCGuestState(guest_GPR31); 1043 default: break; 1044 } 1045 vpanic("integerGuestRegOffset(ppc,be)"); /*notreached*/ 1046 } 1047 1048 static IRExpr* getIReg ( UInt archreg ) 1049 { 1050 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1051 vassert(archreg < 32); 1052 return IRExpr_Get( integerGuestRegOffset(archreg), ty ); 1053 } 1054 1055 /* Ditto, but write to a reg instead. */ 1056 static void putIReg ( UInt archreg, IRExpr* e ) 1057 { 1058 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1059 vassert(archreg < 32); 1060 vassert(typeOfIRExpr(irsb->tyenv, e) == ty ); 1061 stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) ); 1062 } 1063 1064 1065 /* Floating point egisters are mapped to VSX registers[0..31]. */ 1066 static Int floatGuestRegOffset ( UInt archreg ) 1067 { 1068 vassert(archreg < 32); 1069 1070 switch (archreg) { 1071 case 0: return offsetofPPCGuestState(guest_VSR0); 1072 case 1: return offsetofPPCGuestState(guest_VSR1); 1073 case 2: return offsetofPPCGuestState(guest_VSR2); 1074 case 3: return offsetofPPCGuestState(guest_VSR3); 1075 case 4: return offsetofPPCGuestState(guest_VSR4); 1076 case 5: return offsetofPPCGuestState(guest_VSR5); 1077 case 6: return offsetofPPCGuestState(guest_VSR6); 1078 case 7: return offsetofPPCGuestState(guest_VSR7); 1079 case 8: return offsetofPPCGuestState(guest_VSR8); 1080 case 9: return offsetofPPCGuestState(guest_VSR9); 1081 case 10: return offsetofPPCGuestState(guest_VSR10); 1082 case 11: return offsetofPPCGuestState(guest_VSR11); 1083 case 12: return offsetofPPCGuestState(guest_VSR12); 1084 case 13: return offsetofPPCGuestState(guest_VSR13); 1085 case 14: return offsetofPPCGuestState(guest_VSR14); 1086 case 15: return offsetofPPCGuestState(guest_VSR15); 1087 case 16: return offsetofPPCGuestState(guest_VSR16); 1088 case 17: return offsetofPPCGuestState(guest_VSR17); 1089 case 18: return offsetofPPCGuestState(guest_VSR18); 1090 case 19: return offsetofPPCGuestState(guest_VSR19); 1091 case 20: return offsetofPPCGuestState(guest_VSR20); 1092 case 21: return offsetofPPCGuestState(guest_VSR21); 1093 case 22: return offsetofPPCGuestState(guest_VSR22); 1094 case 23: return offsetofPPCGuestState(guest_VSR23); 1095 case 24: return offsetofPPCGuestState(guest_VSR24); 1096 case 25: return offsetofPPCGuestState(guest_VSR25); 1097 case 26: return offsetofPPCGuestState(guest_VSR26); 1098 case 27: return offsetofPPCGuestState(guest_VSR27); 1099 case 28: return offsetofPPCGuestState(guest_VSR28); 1100 case 29: return offsetofPPCGuestState(guest_VSR29); 1101 case 30: return offsetofPPCGuestState(guest_VSR30); 1102 case 31: return offsetofPPCGuestState(guest_VSR31); 1103 default: break; 1104 } 1105 vpanic("floatGuestRegOffset(ppc)"); /*notreached*/ 1106 } 1107 1108 static IRExpr* getFReg ( UInt archreg ) 1109 { 1110 vassert(archreg < 32); 1111 return IRExpr_Get( floatGuestRegOffset(archreg), Ity_F64 ); 1112 } 1113 1114 /* Ditto, but write to a reg instead. */ 1115 static void putFReg ( UInt archreg, IRExpr* e ) 1116 { 1117 vassert(archreg < 32); 1118 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64); 1119 stmt( IRStmt_Put(floatGuestRegOffset(archreg), e) ); 1120 } 1121 1122 /* get Decimal float value. Note, they share floating point register file. */ 1123 static IRExpr* getDReg(UInt archreg) { 1124 IRExpr *e; 1125 vassert( archreg < 32 ); 1126 e = IRExpr_Get( floatGuestRegOffset( archreg ), Ity_D64 ); 1127 return e; 1128 } 1129 1130 /* Read a floating point register pair and combine their contents into a 1131 128-bit value */ 1132 static IRExpr *getDReg_pair(UInt archreg) { 1133 IRExpr *high = getDReg( archreg ); 1134 IRExpr *low = getDReg( archreg + 1 ); 1135 1136 return binop( Iop_D64HLtoD128, high, low ); 1137 } 1138 1139 /* Ditto, but write to a reg instead. */ 1140 static void putDReg(UInt archreg, IRExpr* e) { 1141 vassert( archreg < 32 ); 1142 vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_D64 ); 1143 stmt( IRStmt_Put( floatGuestRegOffset( archreg ), e ) ); 1144 } 1145 1146 /* Write a 128-bit floating point value into a register pair. */ 1147 static void putDReg_pair(UInt archreg, IRExpr *e) { 1148 IRTemp low = newTemp( Ity_D64 ); 1149 IRTemp high = newTemp( Ity_D64 ); 1150 1151 vassert( archreg < 32 ); 1152 vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_D128 ); 1153 1154 assign( low, unop( Iop_D128LOtoD64, e ) ); 1155 assign( high, unop( Iop_D128HItoD64, e ) ); 1156 1157 stmt( IRStmt_Put( floatGuestRegOffset( archreg ), mkexpr( high ) ) ); 1158 stmt( IRStmt_Put( floatGuestRegOffset( archreg + 1 ), mkexpr( low ) ) ); 1159 } 1160 1161 static Int vsxGuestRegOffset ( UInt archreg ) 1162 { 1163 vassert(archreg < 64); 1164 switch (archreg) { 1165 case 0: return offsetofPPCGuestState(guest_VSR0); 1166 case 1: return offsetofPPCGuestState(guest_VSR1); 1167 case 2: return offsetofPPCGuestState(guest_VSR2); 1168 case 3: return offsetofPPCGuestState(guest_VSR3); 1169 case 4: return offsetofPPCGuestState(guest_VSR4); 1170 case 5: return offsetofPPCGuestState(guest_VSR5); 1171 case 6: return offsetofPPCGuestState(guest_VSR6); 1172 case 7: return offsetofPPCGuestState(guest_VSR7); 1173 case 8: return offsetofPPCGuestState(guest_VSR8); 1174 case 9: return offsetofPPCGuestState(guest_VSR9); 1175 case 10: return offsetofPPCGuestState(guest_VSR10); 1176 case 11: return offsetofPPCGuestState(guest_VSR11); 1177 case 12: return offsetofPPCGuestState(guest_VSR12); 1178 case 13: return offsetofPPCGuestState(guest_VSR13); 1179 case 14: return offsetofPPCGuestState(guest_VSR14); 1180 case 15: return offsetofPPCGuestState(guest_VSR15); 1181 case 16: return offsetofPPCGuestState(guest_VSR16); 1182 case 17: return offsetofPPCGuestState(guest_VSR17); 1183 case 18: return offsetofPPCGuestState(guest_VSR18); 1184 case 19: return offsetofPPCGuestState(guest_VSR19); 1185 case 20: return offsetofPPCGuestState(guest_VSR20); 1186 case 21: return offsetofPPCGuestState(guest_VSR21); 1187 case 22: return offsetofPPCGuestState(guest_VSR22); 1188 case 23: return offsetofPPCGuestState(guest_VSR23); 1189 case 24: return offsetofPPCGuestState(guest_VSR24); 1190 case 25: return offsetofPPCGuestState(guest_VSR25); 1191 case 26: return offsetofPPCGuestState(guest_VSR26); 1192 case 27: return offsetofPPCGuestState(guest_VSR27); 1193 case 28: return offsetofPPCGuestState(guest_VSR28); 1194 case 29: return offsetofPPCGuestState(guest_VSR29); 1195 case 30: return offsetofPPCGuestState(guest_VSR30); 1196 case 31: return offsetofPPCGuestState(guest_VSR31); 1197 case 32: return offsetofPPCGuestState(guest_VSR32); 1198 case 33: return offsetofPPCGuestState(guest_VSR33); 1199 case 34: return offsetofPPCGuestState(guest_VSR34); 1200 case 35: return offsetofPPCGuestState(guest_VSR35); 1201 case 36: return offsetofPPCGuestState(guest_VSR36); 1202 case 37: return offsetofPPCGuestState(guest_VSR37); 1203 case 38: return offsetofPPCGuestState(guest_VSR38); 1204 case 39: return offsetofPPCGuestState(guest_VSR39); 1205 case 40: return offsetofPPCGuestState(guest_VSR40); 1206 case 41: return offsetofPPCGuestState(guest_VSR41); 1207 case 42: return offsetofPPCGuestState(guest_VSR42); 1208 case 43: return offsetofPPCGuestState(guest_VSR43); 1209 case 44: return offsetofPPCGuestState(guest_VSR44); 1210 case 45: return offsetofPPCGuestState(guest_VSR45); 1211 case 46: return offsetofPPCGuestState(guest_VSR46); 1212 case 47: return offsetofPPCGuestState(guest_VSR47); 1213 case 48: return offsetofPPCGuestState(guest_VSR48); 1214 case 49: return offsetofPPCGuestState(guest_VSR49); 1215 case 50: return offsetofPPCGuestState(guest_VSR50); 1216 case 51: return offsetofPPCGuestState(guest_VSR51); 1217 case 52: return offsetofPPCGuestState(guest_VSR52); 1218 case 53: return offsetofPPCGuestState(guest_VSR53); 1219 case 54: return offsetofPPCGuestState(guest_VSR54); 1220 case 55: return offsetofPPCGuestState(guest_VSR55); 1221 case 56: return offsetofPPCGuestState(guest_VSR56); 1222 case 57: return offsetofPPCGuestState(guest_VSR57); 1223 case 58: return offsetofPPCGuestState(guest_VSR58); 1224 case 59: return offsetofPPCGuestState(guest_VSR59); 1225 case 60: return offsetofPPCGuestState(guest_VSR60); 1226 case 61: return offsetofPPCGuestState(guest_VSR61); 1227 case 62: return offsetofPPCGuestState(guest_VSR62); 1228 case 63: return offsetofPPCGuestState(guest_VSR63); 1229 default: break; 1230 } 1231 vpanic("vsxGuestRegOffset(ppc)"); /*notreached*/ 1232 } 1233 1234 /* Vector registers are mapped to VSX registers[32..63]. */ 1235 static Int vectorGuestRegOffset ( UInt archreg ) 1236 { 1237 vassert(archreg < 32); 1238 1239 switch (archreg) { 1240 case 0: return offsetofPPCGuestState(guest_VSR32); 1241 case 1: return offsetofPPCGuestState(guest_VSR33); 1242 case 2: return offsetofPPCGuestState(guest_VSR34); 1243 case 3: return offsetofPPCGuestState(guest_VSR35); 1244 case 4: return offsetofPPCGuestState(guest_VSR36); 1245 case 5: return offsetofPPCGuestState(guest_VSR37); 1246 case 6: return offsetofPPCGuestState(guest_VSR38); 1247 case 7: return offsetofPPCGuestState(guest_VSR39); 1248 case 8: return offsetofPPCGuestState(guest_VSR40); 1249 case 9: return offsetofPPCGuestState(guest_VSR41); 1250 case 10: return offsetofPPCGuestState(guest_VSR42); 1251 case 11: return offsetofPPCGuestState(guest_VSR43); 1252 case 12: return offsetofPPCGuestState(guest_VSR44); 1253 case 13: return offsetofPPCGuestState(guest_VSR45); 1254 case 14: return offsetofPPCGuestState(guest_VSR46); 1255 case 15: return offsetofPPCGuestState(guest_VSR47); 1256 case 16: return offsetofPPCGuestState(guest_VSR48); 1257 case 17: return offsetofPPCGuestState(guest_VSR49); 1258 case 18: return offsetofPPCGuestState(guest_VSR50); 1259 case 19: return offsetofPPCGuestState(guest_VSR51); 1260 case 20: return offsetofPPCGuestState(guest_VSR52); 1261 case 21: return offsetofPPCGuestState(guest_VSR53); 1262 case 22: return offsetofPPCGuestState(guest_VSR54); 1263 case 23: return offsetofPPCGuestState(guest_VSR55); 1264 case 24: return offsetofPPCGuestState(guest_VSR56); 1265 case 25: return offsetofPPCGuestState(guest_VSR57); 1266 case 26: return offsetofPPCGuestState(guest_VSR58); 1267 case 27: return offsetofPPCGuestState(guest_VSR59); 1268 case 28: return offsetofPPCGuestState(guest_VSR60); 1269 case 29: return offsetofPPCGuestState(guest_VSR61); 1270 case 30: return offsetofPPCGuestState(guest_VSR62); 1271 case 31: return offsetofPPCGuestState(guest_VSR63); 1272 default: break; 1273 } 1274 vpanic("vextorGuestRegOffset(ppc)"); /*notreached*/ 1275 } 1276 1277 static IRExpr* getVReg ( UInt archreg ) 1278 { 1279 vassert(archreg < 32); 1280 return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_V128 ); 1281 } 1282 1283 /* Ditto, but write to a reg instead. */ 1284 static void putVReg ( UInt archreg, IRExpr* e ) 1285 { 1286 vassert(archreg < 32); 1287 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128); 1288 stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) ); 1289 } 1290 1291 /* Get contents of VSX guest register */ 1292 static IRExpr* getVSReg ( UInt archreg ) 1293 { 1294 vassert(archreg < 64); 1295 return IRExpr_Get( vsxGuestRegOffset(archreg), Ity_V128 ); 1296 } 1297 1298 /* Ditto, but write to a VSX reg instead. */ 1299 static void putVSReg ( UInt archreg, IRExpr* e ) 1300 { 1301 vassert(archreg < 64); 1302 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128); 1303 stmt( IRStmt_Put(vsxGuestRegOffset(archreg), e) ); 1304 } 1305 1306 1307 static Int guestCR321offset ( UInt cr ) 1308 { 1309 switch (cr) { 1310 case 0: return offsetofPPCGuestState(guest_CR0_321 ); 1311 case 1: return offsetofPPCGuestState(guest_CR1_321 ); 1312 case 2: return offsetofPPCGuestState(guest_CR2_321 ); 1313 case 3: return offsetofPPCGuestState(guest_CR3_321 ); 1314 case 4: return offsetofPPCGuestState(guest_CR4_321 ); 1315 case 5: return offsetofPPCGuestState(guest_CR5_321 ); 1316 case 6: return offsetofPPCGuestState(guest_CR6_321 ); 1317 case 7: return offsetofPPCGuestState(guest_CR7_321 ); 1318 default: vpanic("guestCR321offset(ppc)"); 1319 } 1320 } 1321 1322 static Int guestCR0offset ( UInt cr ) 1323 { 1324 switch (cr) { 1325 case 0: return offsetofPPCGuestState(guest_CR0_0 ); 1326 case 1: return offsetofPPCGuestState(guest_CR1_0 ); 1327 case 2: return offsetofPPCGuestState(guest_CR2_0 ); 1328 case 3: return offsetofPPCGuestState(guest_CR3_0 ); 1329 case 4: return offsetofPPCGuestState(guest_CR4_0 ); 1330 case 5: return offsetofPPCGuestState(guest_CR5_0 ); 1331 case 6: return offsetofPPCGuestState(guest_CR6_0 ); 1332 case 7: return offsetofPPCGuestState(guest_CR7_0 ); 1333 default: vpanic("guestCR3offset(ppc)"); 1334 } 1335 } 1336 1337 /* Generate an IR sequence to do a popcount operation on the supplied 1338 IRTemp, and return a new IRTemp holding the result. 'ty' may be 1339 Ity_I32 or Ity_I64 only. */ 1340 static IRTemp gen_POPCOUNT ( IRType ty, IRTemp src, Bool byte_count ) 1341 { 1342 Int i, shift[6], max; 1343 IRTemp mask[6]; 1344 IRTemp old = IRTemp_INVALID; 1345 IRTemp nyu = IRTemp_INVALID; 1346 1347 vassert(ty == Ity_I64 || ty == Ity_I32); 1348 1349 if (ty == Ity_I32) { 1350 if (byte_count) 1351 /* Return the population count across each byte not across the entire 1352 * 32-bit value. Stop after third iteration. 1353 */ 1354 max = 3; 1355 else 1356 max = 5; 1357 1358 for (i = 0; i < 5; i++) { 1359 mask[i] = newTemp(ty); 1360 shift[i] = 1 << i; 1361 } 1362 assign(mask[0], mkU32(0x55555555)); 1363 assign(mask[1], mkU32(0x33333333)); 1364 assign(mask[2], mkU32(0x0F0F0F0F)); 1365 assign(mask[3], mkU32(0x00FF00FF)); 1366 assign(mask[4], mkU32(0x0000FFFF)); 1367 old = src; 1368 for (i = 0; i < max; i++) { 1369 nyu = newTemp(ty); 1370 assign(nyu, 1371 binop(Iop_Add32, 1372 binop(Iop_And32, 1373 mkexpr(old), 1374 mkexpr(mask[i])), 1375 binop(Iop_And32, 1376 binop(Iop_Shr32, mkexpr(old), mkU8(shift[i])), 1377 mkexpr(mask[i])))); 1378 old = nyu; 1379 } 1380 return nyu; 1381 } 1382 // else, ty == Ity_I64 1383 if (byte_count) 1384 /* Return the population count across each byte not across the entire 1385 * 64-bit value. Stop after third iteration. 1386 */ 1387 max = 3; 1388 else 1389 max = 6; 1390 1391 for (i = 0; i < 6; i++) { 1392 mask[i] = newTemp( Ity_I64 ); 1393 shift[i] = 1 << i; 1394 } 1395 assign( mask[0], mkU64( 0x5555555555555555ULL ) ); 1396 assign( mask[1], mkU64( 0x3333333333333333ULL ) ); 1397 assign( mask[2], mkU64( 0x0F0F0F0F0F0F0F0FULL ) ); 1398 assign( mask[3], mkU64( 0x00FF00FF00FF00FFULL ) ); 1399 assign( mask[4], mkU64( 0x0000FFFF0000FFFFULL ) ); 1400 assign( mask[5], mkU64( 0x00000000FFFFFFFFULL ) ); 1401 old = src; 1402 for (i = 0; i < max; i++) { 1403 nyu = newTemp( Ity_I64 ); 1404 assign( nyu, 1405 binop( Iop_Add64, 1406 binop( Iop_And64, mkexpr( old ), mkexpr( mask[i] ) ), 1407 binop( Iop_And64, 1408 binop( Iop_Shr64, mkexpr( old ), mkU8( shift[i] ) ), 1409 mkexpr( mask[i] ) ) ) ); 1410 old = nyu; 1411 } 1412 return nyu; 1413 } 1414 1415 1416 // ROTL(src32/64, rot_amt5/6) 1417 static IRExpr* /* :: Ity_I32/64 */ ROTL ( IRExpr* src, 1418 IRExpr* rot_amt ) 1419 { 1420 IRExpr *mask, *rot; 1421 vassert(typeOfIRExpr(irsb->tyenv,rot_amt) == Ity_I8); 1422 1423 if (typeOfIRExpr(irsb->tyenv,src) == Ity_I64) { 1424 // rot = (src << rot_amt) | (src >> (64-rot_amt)) 1425 mask = binop(Iop_And8, rot_amt, mkU8(63)); 1426 rot = binop(Iop_Or64, 1427 binop(Iop_Shl64, src, mask), 1428 binop(Iop_Shr64, src, binop(Iop_Sub8, mkU8(64), mask))); 1429 } else { 1430 // rot = (src << rot_amt) | (src >> (32-rot_amt)) 1431 mask = binop(Iop_And8, rot_amt, mkU8(31)); 1432 rot = binop(Iop_Or32, 1433 binop(Iop_Shl32, src, mask), 1434 binop(Iop_Shr32, src, binop(Iop_Sub8, mkU8(32), mask))); 1435 } 1436 /* Note: the MuxOX is not merely an optimisation; it's needed 1437 because otherwise the Shr is a shift by the word size when 1438 mask denotes zero. For rotates by immediates, a lot of 1439 this junk gets folded out. */ 1440 return IRExpr_Mux0X( mask, /* zero rotate */ src, 1441 /* non-zero rotate */ rot ); 1442 } 1443 1444 /* Standard effective address calc: (rA + rB) */ 1445 static IRExpr* ea_rA_idxd ( UInt rA, UInt rB ) 1446 { 1447 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1448 vassert(rA < 32); 1449 vassert(rB < 32); 1450 return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), getIReg(rB)); 1451 } 1452 1453 /* Standard effective address calc: (rA + simm) */ 1454 static IRExpr* ea_rA_simm ( UInt rA, UInt simm16 ) 1455 { 1456 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1457 vassert(rA < 32); 1458 return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), 1459 mkSzExtendS16(ty, simm16)); 1460 } 1461 1462 /* Standard effective address calc: (rA|0) */ 1463 static IRExpr* ea_rAor0 ( UInt rA ) 1464 { 1465 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1466 vassert(rA < 32); 1467 if (rA == 0) { 1468 return mkSzImm(ty, 0); 1469 } else { 1470 return getIReg(rA); 1471 } 1472 } 1473 1474 /* Standard effective address calc: (rA|0) + rB */ 1475 static IRExpr* ea_rAor0_idxd ( UInt rA, UInt rB ) 1476 { 1477 vassert(rA < 32); 1478 vassert(rB < 32); 1479 return (rA == 0) ? getIReg(rB) : ea_rA_idxd( rA, rB ); 1480 } 1481 1482 /* Standard effective address calc: (rA|0) + simm16 */ 1483 static IRExpr* ea_rAor0_simm ( UInt rA, UInt simm16 ) 1484 { 1485 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1486 vassert(rA < 32); 1487 if (rA == 0) { 1488 return mkSzExtendS16(ty, simm16); 1489 } else { 1490 return ea_rA_simm( rA, simm16 ); 1491 } 1492 } 1493 1494 1495 /* Align effective address */ 1496 static IRExpr* addr_align( IRExpr* addr, UChar align ) 1497 { 1498 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1499 Long mask; 1500 switch (align) { 1501 case 1: return addr; // byte aligned 1502 case 2: mask = ((Long)-1) << 1; break; // half-word aligned 1503 case 4: mask = ((Long)-1) << 2; break; // word aligned 1504 case 16: mask = ((Long)-1) << 4; break; // quad-word aligned 1505 default: 1506 vex_printf("addr_align: align = %u\n", align); 1507 vpanic("addr_align(ppc)"); 1508 } 1509 1510 vassert(typeOfIRExpr(irsb->tyenv,addr) == ty); 1511 return binop( mkSzOp(ty, Iop_And8), addr, mkSzImm(ty, mask) ); 1512 } 1513 1514 1515 /* Exit the trace if ADDR (intended to be a guest memory address) is 1516 not ALIGN-aligned, generating a request for a SIGBUS followed by a 1517 restart of the current insn. */ 1518 static void gen_SIGBUS_if_misaligned ( IRTemp addr, UChar align ) 1519 { 1520 vassert(align == 4 || align == 8); 1521 if (mode64) { 1522 vassert(typeOfIRTemp(irsb->tyenv, addr) == Ity_I64); 1523 stmt( 1524 IRStmt_Exit( 1525 binop(Iop_CmpNE64, 1526 binop(Iop_And64, mkexpr(addr), mkU64(align-1)), 1527 mkU64(0)), 1528 Ijk_SigBUS, 1529 IRConst_U64( guest_CIA_curr_instr ), OFFB_CIA 1530 ) 1531 ); 1532 } else { 1533 vassert(typeOfIRTemp(irsb->tyenv, addr) == Ity_I32); 1534 stmt( 1535 IRStmt_Exit( 1536 binop(Iop_CmpNE32, 1537 binop(Iop_And32, mkexpr(addr), mkU32(align-1)), 1538 mkU32(0)), 1539 Ijk_SigBUS, 1540 IRConst_U32( guest_CIA_curr_instr ), OFFB_CIA 1541 ) 1542 ); 1543 } 1544 } 1545 1546 1547 /* Generate AbiHints which mark points at which the ELF or PowerOpen 1548 ABIs say that the stack red zone (viz, -N(r1) .. -1(r1), for some 1549 N) becomes undefined. That is at function calls and returns. ELF 1550 ppc32 doesn't have this "feature" (how fortunate for it). nia is 1551 the address of the next instruction to be executed. 1552 */ 1553 static void make_redzone_AbiHint ( VexAbiInfo* vbi, 1554 IRTemp nia, HChar* who ) 1555 { 1556 Int szB = vbi->guest_stack_redzone_size; 1557 if (0) vex_printf("AbiHint: %s\n", who); 1558 vassert(szB >= 0); 1559 if (szB > 0) { 1560 if (mode64) { 1561 vassert(typeOfIRTemp(irsb->tyenv, nia) == Ity_I64); 1562 stmt( IRStmt_AbiHint( 1563 binop(Iop_Sub64, getIReg(1), mkU64(szB)), 1564 szB, 1565 mkexpr(nia) 1566 )); 1567 } else { 1568 vassert(typeOfIRTemp(irsb->tyenv, nia) == Ity_I32); 1569 stmt( IRStmt_AbiHint( 1570 binop(Iop_Sub32, getIReg(1), mkU32(szB)), 1571 szB, 1572 mkexpr(nia) 1573 )); 1574 } 1575 } 1576 } 1577 1578 1579 /*------------------------------------------------------------*/ 1580 /*--- Helpers for condition codes. ---*/ 1581 /*------------------------------------------------------------*/ 1582 1583 /* Condition register layout. 1584 1585 In the hardware, CR is laid out like this. The leftmost end is the 1586 most significant bit in the register; however the IBM documentation 1587 numbers the bits backwards for some reason. 1588 1589 CR0 CR1 .......... CR6 CR7 1590 0 .. 3 ....................... 28 .. 31 (IBM bit numbering) 1591 31 28 3 0 (normal bit numbering) 1592 1593 Each CR field is 4 bits: [<,>,==,SO] 1594 1595 Hence in IBM's notation, BI=0 is CR7[SO], BI=1 is CR7[==], etc. 1596 1597 Indexing from BI to guest state: 1598 1599 let n = BI / 4 1600 off = BI % 4 1601 this references CR n: 1602 1603 off==0 -> guest_CRn_321 >> 3 1604 off==1 -> guest_CRn_321 >> 2 1605 off==2 -> guest_CRn_321 >> 1 1606 off==3 -> guest_CRn_SO 1607 1608 Bear in mind the only significant bit in guest_CRn_SO is bit 0 1609 (normal notation) and in guest_CRn_321 the significant bits are 1610 3, 2 and 1 (normal notation). 1611 */ 1612 1613 static void putCR321 ( UInt cr, IRExpr* e ) 1614 { 1615 vassert(cr < 8); 1616 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1617 stmt( IRStmt_Put(guestCR321offset(cr), e) ); 1618 } 1619 1620 static void putCR0 ( UInt cr, IRExpr* e ) 1621 { 1622 vassert(cr < 8); 1623 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1624 stmt( IRStmt_Put(guestCR0offset(cr), e) ); 1625 } 1626 1627 static IRExpr* /* :: Ity_I8 */ getCR0 ( UInt cr ) 1628 { 1629 vassert(cr < 8); 1630 return IRExpr_Get(guestCR0offset(cr), Ity_I8); 1631 } 1632 1633 static IRExpr* /* :: Ity_I8 */ getCR321 ( UInt cr ) 1634 { 1635 vassert(cr < 8); 1636 return IRExpr_Get(guestCR321offset(cr), Ity_I8); 1637 } 1638 1639 /* Fetch the specified CR bit (as per IBM/hardware notation) and 1640 return it at the bottom of an I32; the top 31 bits are guaranteed 1641 to be zero. */ 1642 static IRExpr* /* :: Ity_I32 */ getCRbit ( UInt bi ) 1643 { 1644 UInt n = bi / 4; 1645 UInt off = bi % 4; 1646 vassert(bi < 32); 1647 if (off == 3) { 1648 /* Fetch the SO bit for this CR field */ 1649 /* Note: And32 is redundant paranoia iff guest state only has 0 1650 or 1 in that slot. */ 1651 return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1)); 1652 } else { 1653 /* Fetch the <, > or == bit for this CR field */ 1654 return binop( Iop_And32, 1655 binop( Iop_Shr32, 1656 unop(Iop_8Uto32, getCR321(n)), 1657 mkU8(toUChar(3-off)) ), 1658 mkU32(1) ); 1659 } 1660 } 1661 1662 /* Dually, write the least significant bit of BIT to the specified CR 1663 bit. Indexing as per getCRbit. */ 1664 static void putCRbit ( UInt bi, IRExpr* bit ) 1665 { 1666 UInt n, off; 1667 IRExpr* safe; 1668 vassert(typeOfIRExpr(irsb->tyenv,bit) == Ity_I32); 1669 safe = binop(Iop_And32, bit, mkU32(1)); 1670 n = bi / 4; 1671 off = bi % 4; 1672 vassert(bi < 32); 1673 if (off == 3) { 1674 /* This is the SO bit for this CR field */ 1675 putCR0(n, unop(Iop_32to8, safe)); 1676 } else { 1677 off = 3 - off; 1678 vassert(off == 1 || off == 2 || off == 3); 1679 putCR321( 1680 n, 1681 unop( Iop_32to8, 1682 binop( Iop_Or32, 1683 /* old value with field masked out */ 1684 binop(Iop_And32, unop(Iop_8Uto32, getCR321(n)), 1685 mkU32(~(1 << off))), 1686 /* new value in the right place */ 1687 binop(Iop_Shl32, safe, mkU8(toUChar(off))) 1688 ) 1689 ) 1690 ); 1691 } 1692 } 1693 1694 /* Fetch the specified CR bit (as per IBM/hardware notation) and 1695 return it somewhere in an I32; it does not matter where, but 1696 whichever bit it is, all other bits are guaranteed to be zero. In 1697 other words, the I32-typed expression will be zero if the bit is 1698 zero and nonzero if the bit is 1. Write into *where the index 1699 of where the bit will be. */ 1700 1701 static 1702 IRExpr* /* :: Ity_I32 */ getCRbit_anywhere ( UInt bi, Int* where ) 1703 { 1704 UInt n = bi / 4; 1705 UInt off = bi % 4; 1706 vassert(bi < 32); 1707 if (off == 3) { 1708 /* Fetch the SO bit for this CR field */ 1709 /* Note: And32 is redundant paranoia iff guest state only has 0 1710 or 1 in that slot. */ 1711 *where = 0; 1712 return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1)); 1713 } else { 1714 /* Fetch the <, > or == bit for this CR field */ 1715 *where = 3-off; 1716 return binop( Iop_And32, 1717 unop(Iop_8Uto32, getCR321(n)), 1718 mkU32(1 << (3-off)) ); 1719 } 1720 } 1721 1722 /* Set the CR0 flags following an arithmetic operation. 1723 (Condition Register CR0 Field Definition, PPC32 p60) 1724 */ 1725 static IRExpr* getXER_SO ( void ); 1726 static void set_CR0 ( IRExpr* result ) 1727 { 1728 vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_I32 || 1729 typeOfIRExpr(irsb->tyenv,result) == Ity_I64); 1730 if (mode64) { 1731 putCR321( 0, unop(Iop_64to8, 1732 binop(Iop_CmpORD64S, result, mkU64(0))) ); 1733 } else { 1734 putCR321( 0, unop(Iop_32to8, 1735 binop(Iop_CmpORD32S, result, mkU32(0))) ); 1736 } 1737 putCR0( 0, getXER_SO() ); 1738 } 1739 1740 1741 /* Set the CR6 flags following an AltiVec compare operation. 1742 * NOTE: This also works for VSX single-precision compares. 1743 * */ 1744 static void set_AV_CR6 ( IRExpr* result, Bool test_all_ones ) 1745 { 1746 /* CR6[0:3] = {all_ones, 0, all_zeros, 0} 1747 all_ones = (v[0] && v[1] && v[2] && v[3]) 1748 all_zeros = ~(v[0] || v[1] || v[2] || v[3]) 1749 */ 1750 IRTemp v0 = newTemp(Ity_V128); 1751 IRTemp v1 = newTemp(Ity_V128); 1752 IRTemp v2 = newTemp(Ity_V128); 1753 IRTemp v3 = newTemp(Ity_V128); 1754 IRTemp rOnes = newTemp(Ity_I8); 1755 IRTemp rZeros = newTemp(Ity_I8); 1756 1757 vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_V128); 1758 1759 assign( v0, result ); 1760 assign( v1, binop(Iop_ShrV128, result, mkU8(32)) ); 1761 assign( v2, binop(Iop_ShrV128, result, mkU8(64)) ); 1762 assign( v3, binop(Iop_ShrV128, result, mkU8(96)) ); 1763 1764 assign( rZeros, unop(Iop_1Uto8, 1765 binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF), 1766 unop(Iop_Not32, 1767 unop(Iop_V128to32, 1768 binop(Iop_OrV128, 1769 binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)), 1770 binop(Iop_OrV128, mkexpr(v2), mkexpr(v3)))) 1771 ))) ); 1772 1773 if (test_all_ones) { 1774 assign( rOnes, unop(Iop_1Uto8, 1775 binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF), 1776 unop(Iop_V128to32, 1777 binop(Iop_AndV128, 1778 binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)), 1779 binop(Iop_AndV128, mkexpr(v2), mkexpr(v3))) 1780 ))) ); 1781 putCR321( 6, binop(Iop_Or8, 1782 binop(Iop_Shl8, mkexpr(rOnes), mkU8(3)), 1783 binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) ); 1784 } else { 1785 putCR321( 6, binop(Iop_Shl8, mkexpr(rZeros), mkU8(1)) ); 1786 } 1787 putCR0( 6, mkU8(0) ); 1788 } 1789 1790 1791 1792 /*------------------------------------------------------------*/ 1793 /*--- Helpers for XER flags. ---*/ 1794 /*------------------------------------------------------------*/ 1795 1796 static void putXER_SO ( IRExpr* e ) 1797 { 1798 IRExpr* so; 1799 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1800 so = binop(Iop_And8, e, mkU8(1)); 1801 stmt( IRStmt_Put( OFFB_XER_SO, so ) ); 1802 } 1803 1804 static void putXER_OV ( IRExpr* e ) 1805 { 1806 IRExpr* ov; 1807 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1808 ov = binop(Iop_And8, e, mkU8(1)); 1809 stmt( IRStmt_Put( OFFB_XER_OV, ov ) ); 1810 } 1811 1812 static void putXER_CA ( IRExpr* e ) 1813 { 1814 IRExpr* ca; 1815 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1816 ca = binop(Iop_And8, e, mkU8(1)); 1817 stmt( IRStmt_Put( OFFB_XER_CA, ca ) ); 1818 } 1819 1820 static void putXER_BC ( IRExpr* e ) 1821 { 1822 IRExpr* bc; 1823 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8); 1824 bc = binop(Iop_And8, e, mkU8(0x7F)); 1825 stmt( IRStmt_Put( OFFB_XER_BC, bc ) ); 1826 } 1827 1828 static IRExpr* /* :: Ity_I8 */ getXER_SO ( void ) 1829 { 1830 return IRExpr_Get( OFFB_XER_SO, Ity_I8 ); 1831 } 1832 1833 static IRExpr* /* :: Ity_I32 */ getXER_SO32 ( void ) 1834 { 1835 return binop( Iop_And32, unop(Iop_8Uto32, getXER_SO()), mkU32(1) ); 1836 } 1837 1838 static IRExpr* /* :: Ity_I8 */ getXER_OV ( void ) 1839 { 1840 return IRExpr_Get( OFFB_XER_OV, Ity_I8 ); 1841 } 1842 1843 static IRExpr* /* :: Ity_I32 */ getXER_OV32 ( void ) 1844 { 1845 return binop( Iop_And32, unop(Iop_8Uto32, getXER_OV()), mkU32(1) ); 1846 } 1847 1848 static IRExpr* /* :: Ity_I32 */ getXER_CA32 ( void ) 1849 { 1850 IRExpr* ca = IRExpr_Get( OFFB_XER_CA, Ity_I8 ); 1851 return binop( Iop_And32, unop(Iop_8Uto32, ca ), mkU32(1) ); 1852 } 1853 1854 static IRExpr* /* :: Ity_I8 */ getXER_BC ( void ) 1855 { 1856 return IRExpr_Get( OFFB_XER_BC, Ity_I8 ); 1857 } 1858 1859 static IRExpr* /* :: Ity_I32 */ getXER_BC32 ( void ) 1860 { 1861 IRExpr* bc = IRExpr_Get( OFFB_XER_BC, Ity_I8 ); 1862 return binop( Iop_And32, unop(Iop_8Uto32, bc), mkU32(0x7F) ); 1863 } 1864 1865 1866 /* RES is the result of doing OP on ARGL and ARGR. Set %XER.OV and 1867 %XER.SO accordingly. */ 1868 1869 static void set_XER_OV_32( UInt op, IRExpr* res, 1870 IRExpr* argL, IRExpr* argR ) 1871 { 1872 IRTemp t64; 1873 IRExpr* xer_ov; 1874 vassert(op < PPCG_FLAG_OP_NUMBER); 1875 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I32); 1876 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I32); 1877 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I32); 1878 1879 # define INT32_MIN 0x80000000 1880 1881 # define XOR2(_aa,_bb) \ 1882 binop(Iop_Xor32,(_aa),(_bb)) 1883 1884 # define XOR3(_cc,_dd,_ee) \ 1885 binop(Iop_Xor32,binop(Iop_Xor32,(_cc),(_dd)),(_ee)) 1886 1887 # define AND3(_ff,_gg,_hh) \ 1888 binop(Iop_And32,binop(Iop_And32,(_ff),(_gg)),(_hh)) 1889 1890 #define NOT(_jj) \ 1891 unop(Iop_Not32, (_jj)) 1892 1893 switch (op) { 1894 case /* 0 */ PPCG_FLAG_OP_ADD: 1895 case /* 1 */ PPCG_FLAG_OP_ADDE: 1896 /* (argL^argR^-1) & (argL^res) & (1<<31) ?1:0 */ 1897 // i.e. ((both_same_sign) & (sign_changed) & (sign_mask)) 1898 xer_ov 1899 = AND3( XOR3(argL,argR,mkU32(-1)), 1900 XOR2(argL,res), 1901 mkU32(INT32_MIN) ); 1902 /* xer_ov can only be 0 or 1<<31 */ 1903 xer_ov 1904 = binop(Iop_Shr32, xer_ov, mkU8(31) ); 1905 break; 1906 1907 case /* 2 */ PPCG_FLAG_OP_DIVW: 1908 /* (argL == INT32_MIN && argR == -1) || argR == 0 */ 1909 xer_ov 1910 = mkOR1( 1911 mkAND1( 1912 binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)), 1913 binop(Iop_CmpEQ32, argR, mkU32(-1)) 1914 ), 1915 binop(Iop_CmpEQ32, argR, mkU32(0) ) 1916 ); 1917 xer_ov 1918 = unop(Iop_1Uto32, xer_ov); 1919 break; 1920 1921 case /* 3 */ PPCG_FLAG_OP_DIVWU: 1922 /* argR == 0 */ 1923 xer_ov 1924 = unop(Iop_1Uto32, binop(Iop_CmpEQ32, argR, mkU32(0))); 1925 break; 1926 1927 case /* 4 */ PPCG_FLAG_OP_MULLW: 1928 /* OV true if result can't be represented in 32 bits 1929 i.e sHi != sign extension of sLo */ 1930 t64 = newTemp(Ity_I64); 1931 assign( t64, binop(Iop_MullS32, argL, argR) ); 1932 xer_ov 1933 = binop( Iop_CmpNE32, 1934 unop(Iop_64HIto32, mkexpr(t64)), 1935 binop( Iop_Sar32, 1936 unop(Iop_64to32, mkexpr(t64)), 1937 mkU8(31)) 1938 ); 1939 xer_ov 1940 = unop(Iop_1Uto32, xer_ov); 1941 break; 1942 1943 case /* 5 */ PPCG_FLAG_OP_NEG: 1944 /* argL == INT32_MIN */ 1945 xer_ov 1946 = unop( Iop_1Uto32, 1947 binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)) ); 1948 break; 1949 1950 case /* 6 */ PPCG_FLAG_OP_SUBF: 1951 case /* 7 */ PPCG_FLAG_OP_SUBFC: 1952 case /* 8 */ PPCG_FLAG_OP_SUBFE: 1953 /* ((~argL)^argR^-1) & ((~argL)^res) & (1<<31) ?1:0; */ 1954 xer_ov 1955 = AND3( XOR3(NOT(argL),argR,mkU32(-1)), 1956 XOR2(NOT(argL),res), 1957 mkU32(INT32_MIN) ); 1958 /* xer_ov can only be 0 or 1<<31 */ 1959 xer_ov 1960 = binop(Iop_Shr32, xer_ov, mkU8(31) ); 1961 break; 1962 1963 case PPCG_FLAG_OP_DIVWEU: 1964 xer_ov 1965 = binop( Iop_Or32, 1966 unop( Iop_1Uto32, binop( Iop_CmpEQ32, argR, mkU32( 0 ) ) ), 1967 unop( Iop_1Uto32, binop( Iop_CmpLT32U, argR, argL ) ) ); 1968 break; 1969 1970 case PPCG_FLAG_OP_DIVWE: 1971 1972 /* If argR == 0 of if the result cannot fit in the 32-bit destination register, 1973 * then OV <- 1. If dest reg is 0 AND both dividend and divisor are non-zero, 1974 * an overflow is implied. 1975 */ 1976 xer_ov = binop( Iop_Or32, 1977 unop( Iop_1Uto32, binop( Iop_CmpEQ32, argR, mkU32( 0 ) ) ), 1978 unop( Iop_1Uto32, mkAND1( binop( Iop_CmpEQ32, res, mkU32( 0 ) ), 1979 mkAND1( binop( Iop_CmpNE32, argL, mkU32( 0 ) ), 1980 binop( Iop_CmpNE32, argR, mkU32( 0 ) ) ) ) ) ); 1981 break; 1982 1983 1984 1985 default: 1986 vex_printf("set_XER_OV: op = %u\n", op); 1987 vpanic("set_XER_OV(ppc)"); 1988 } 1989 1990 /* xer_ov MUST denote either 0 or 1, no other value allowed */ 1991 putXER_OV( unop(Iop_32to8, xer_ov) ); 1992 1993 /* Update the summary overflow */ 1994 putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) ); 1995 1996 # undef INT32_MIN 1997 # undef AND3 1998 # undef XOR3 1999 # undef XOR2 2000 # undef NOT 2001 } 2002 2003 static void set_XER_OV_64( UInt op, IRExpr* res, 2004 IRExpr* argL, IRExpr* argR ) 2005 { 2006 IRExpr* xer_ov; 2007 vassert(op < PPCG_FLAG_OP_NUMBER); 2008 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I64); 2009 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I64); 2010 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I64); 2011 2012 # define INT64_MIN 0x8000000000000000ULL 2013 2014 # define XOR2(_aa,_bb) \ 2015 binop(Iop_Xor64,(_aa),(_bb)) 2016 2017 # define XOR3(_cc,_dd,_ee) \ 2018 binop(Iop_Xor64,binop(Iop_Xor64,(_cc),(_dd)),(_ee)) 2019 2020 # define AND3(_ff,_gg,_hh) \ 2021 binop(Iop_And64,binop(Iop_And64,(_ff),(_gg)),(_hh)) 2022 2023 #define NOT(_jj) \ 2024 unop(Iop_Not64, (_jj)) 2025 2026 switch (op) { 2027 case /* 0 */ PPCG_FLAG_OP_ADD: 2028 case /* 1 */ PPCG_FLAG_OP_ADDE: 2029 /* (argL^argR^-1) & (argL^res) & (1<<63) ? 1:0 */ 2030 // i.e. ((both_same_sign) & (sign_changed) & (sign_mask)) 2031 xer_ov 2032 = AND3( XOR3(argL,argR,mkU64(-1)), 2033 XOR2(argL,res), 2034 mkU64(INT64_MIN) ); 2035 /* xer_ov can only be 0 or 1<<63 */ 2036 xer_ov 2037 = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63))); 2038 break; 2039 2040 case /* 2 */ PPCG_FLAG_OP_DIVW: 2041 /* (argL == INT64_MIN && argR == -1) || argR == 0 */ 2042 xer_ov 2043 = mkOR1( 2044 mkAND1( 2045 binop(Iop_CmpEQ64, argL, mkU64(INT64_MIN)), 2046 binop(Iop_CmpEQ64, argR, mkU64(-1)) 2047 ), 2048 binop(Iop_CmpEQ64, argR, mkU64(0) ) 2049 ); 2050 break; 2051 2052 case /* 3 */ PPCG_FLAG_OP_DIVWU: 2053 /* argR == 0 */ 2054 xer_ov 2055 = binop(Iop_CmpEQ64, argR, mkU64(0)); 2056 break; 2057 2058 case /* 4 */ PPCG_FLAG_OP_MULLW: { 2059 /* OV true if result can't be represented in 64 bits 2060 i.e sHi != sign extension of sLo */ 2061 xer_ov 2062 = binop( Iop_CmpNE32, 2063 unop(Iop_64HIto32, res), 2064 binop( Iop_Sar32, 2065 unop(Iop_64to32, res), 2066 mkU8(31)) 2067 ); 2068 break; 2069 } 2070 2071 case /* 5 */ PPCG_FLAG_OP_NEG: 2072 /* argL == INT64_MIN */ 2073 xer_ov 2074 = binop(Iop_CmpEQ64, argL, mkU64(INT64_MIN)); 2075 break; 2076 2077 case /* 6 */ PPCG_FLAG_OP_SUBF: 2078 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2079 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2080 /* ((~argL)^argR^-1) & ((~argL)^res) & (1<<63) ?1:0; */ 2081 xer_ov 2082 = AND3( XOR3(NOT(argL),argR,mkU64(-1)), 2083 XOR2(NOT(argL),res), 2084 mkU64(INT64_MIN) ); 2085 /* xer_ov can only be 0 or 1<<63 */ 2086 xer_ov 2087 = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63))); 2088 break; 2089 2090 case PPCG_FLAG_OP_DIVDE: 2091 2092 /* If argR == 0, we must set the OV bit. But there's another condition 2093 * where we can get overflow set for divde . . . when the 2094 * result cannot fit in the 64-bit destination register. If dest reg is 0 AND 2095 * both dividend and divisor are non-zero, it implies an overflow. 2096 */ 2097 xer_ov 2098 = mkOR1( binop( Iop_CmpEQ64, argR, mkU64( 0 ) ), 2099 mkAND1( binop( Iop_CmpEQ64, res, mkU64( 0 ) ), 2100 mkAND1( binop( Iop_CmpNE64, argL, mkU64( 0 ) ), 2101 binop( Iop_CmpNE64, argR, mkU64( 0 ) ) ) ) ); 2102 break; 2103 2104 case PPCG_FLAG_OP_DIVDEU: 2105 /* If argR == 0 or if argL >= argR, set OV. */ 2106 xer_ov = mkOR1( binop( Iop_CmpEQ64, argR, mkU64( 0 ) ), 2107 binop( Iop_CmpLE64U, argR, argL ) ); 2108 break; 2109 2110 default: 2111 vex_printf("set_XER_OV: op = %u\n", op); 2112 vpanic("set_XER_OV(ppc64)"); 2113 } 2114 2115 /* xer_ov MUST denote either 0 or 1, no other value allowed */ 2116 putXER_OV( unop(Iop_1Uto8, xer_ov) ); 2117 2118 /* Update the summary overflow */ 2119 putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) ); 2120 2121 # undef INT64_MIN 2122 # undef AND3 2123 # undef XOR3 2124 # undef XOR2 2125 # undef NOT 2126 } 2127 2128 static void set_XER_OV ( IRType ty, UInt op, IRExpr* res, 2129 IRExpr* argL, IRExpr* argR ) 2130 { 2131 if (ty == Ity_I32) 2132 set_XER_OV_32( op, res, argL, argR ); 2133 else 2134 set_XER_OV_64( op, res, argL, argR ); 2135 } 2136 2137 2138 2139 /* RES is the result of doing OP on ARGL and ARGR with the old %XER.CA 2140 value being OLDCA. Set %XER.CA accordingly. */ 2141 2142 static void set_XER_CA_32 ( UInt op, IRExpr* res, 2143 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2144 { 2145 IRExpr* xer_ca; 2146 vassert(op < PPCG_FLAG_OP_NUMBER); 2147 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I32); 2148 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I32); 2149 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I32); 2150 vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I32); 2151 2152 /* Incoming oldca is assumed to hold the values 0 or 1 only. This 2153 seems reasonable given that it's always generated by 2154 getXER_CA32(), which masks it accordingly. In any case it being 2155 0 or 1 is an invariant of the ppc guest state representation; 2156 if it has any other value, that invariant has been violated. */ 2157 2158 switch (op) { 2159 case /* 0 */ PPCG_FLAG_OP_ADD: 2160 /* res <u argL */ 2161 xer_ca 2162 = unop(Iop_1Uto32, binop(Iop_CmpLT32U, res, argL)); 2163 break; 2164 2165 case /* 1 */ PPCG_FLAG_OP_ADDE: 2166 /* res <u argL || (old_ca==1 && res==argL) */ 2167 xer_ca 2168 = mkOR1( 2169 binop(Iop_CmpLT32U, res, argL), 2170 mkAND1( 2171 binop(Iop_CmpEQ32, oldca, mkU32(1)), 2172 binop(Iop_CmpEQ32, res, argL) 2173 ) 2174 ); 2175 xer_ca 2176 = unop(Iop_1Uto32, xer_ca); 2177 break; 2178 2179 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2180 /* res <u argR || (old_ca==1 && res==argR) */ 2181 xer_ca 2182 = mkOR1( 2183 binop(Iop_CmpLT32U, res, argR), 2184 mkAND1( 2185 binop(Iop_CmpEQ32, oldca, mkU32(1)), 2186 binop(Iop_CmpEQ32, res, argR) 2187 ) 2188 ); 2189 xer_ca 2190 = unop(Iop_1Uto32, xer_ca); 2191 break; 2192 2193 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2194 case /* 9 */ PPCG_FLAG_OP_SUBFI: 2195 /* res <=u argR */ 2196 xer_ca 2197 = unop(Iop_1Uto32, binop(Iop_CmpLE32U, res, argR)); 2198 break; 2199 2200 case /* 10 */ PPCG_FLAG_OP_SRAW: 2201 /* The shift amount is guaranteed to be in 0 .. 63 inclusive. 2202 If it is <= 31, behave like SRAWI; else XER.CA is the sign 2203 bit of argL. */ 2204 /* This term valid for shift amount < 32 only */ 2205 xer_ca 2206 = binop( 2207 Iop_And32, 2208 binop(Iop_Sar32, argL, mkU8(31)), 2209 binop( Iop_And32, 2210 argL, 2211 binop( Iop_Sub32, 2212 binop(Iop_Shl32, mkU32(1), 2213 unop(Iop_32to8,argR)), 2214 mkU32(1) ) 2215 ) 2216 ); 2217 xer_ca 2218 = IRExpr_Mux0X( 2219 /* shift amt > 31 ? */ 2220 unop(Iop_1Uto8, binop(Iop_CmpLT32U, mkU32(31), argR)), 2221 /* no -- be like srawi */ 2222 unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))), 2223 /* yes -- get sign bit of argL */ 2224 binop(Iop_Shr32, argL, mkU8(31)) 2225 ); 2226 break; 2227 2228 case /* 11 */ PPCG_FLAG_OP_SRAWI: 2229 /* xer_ca is 1 iff src was negative and bits_shifted_out != 2230 0. Since the shift amount is known to be in the range 2231 0 .. 31 inclusive the following seems viable: 2232 xer.ca == 1 iff the following is nonzero: 2233 (argL >>s 31) -- either all 0s or all 1s 2234 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2235 xer_ca 2236 = binop( 2237 Iop_And32, 2238 binop(Iop_Sar32, argL, mkU8(31)), 2239 binop( Iop_And32, 2240 argL, 2241 binop( Iop_Sub32, 2242 binop(Iop_Shl32, mkU32(1), 2243 unop(Iop_32to8,argR)), 2244 mkU32(1) ) 2245 ) 2246 ); 2247 xer_ca 2248 = unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))); 2249 break; 2250 2251 default: 2252 vex_printf("set_XER_CA: op = %u\n", op); 2253 vpanic("set_XER_CA(ppc)"); 2254 } 2255 2256 /* xer_ca MUST denote either 0 or 1, no other value allowed */ 2257 putXER_CA( unop(Iop_32to8, xer_ca) ); 2258 } 2259 2260 static void set_XER_CA_64 ( UInt op, IRExpr* res, 2261 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2262 { 2263 IRExpr* xer_ca; 2264 vassert(op < PPCG_FLAG_OP_NUMBER); 2265 vassert(typeOfIRExpr(irsb->tyenv,res) == Ity_I64); 2266 vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I64); 2267 vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I64); 2268 vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I64); 2269 2270 /* Incoming oldca is assumed to hold the values 0 or 1 only. This 2271 seems reasonable given that it's always generated by 2272 getXER_CA32(), which masks it accordingly. In any case it being 2273 0 or 1 is an invariant of the ppc guest state representation; 2274 if it has any other value, that invariant has been violated. */ 2275 2276 switch (op) { 2277 case /* 0 */ PPCG_FLAG_OP_ADD: 2278 /* res <u argL */ 2279 xer_ca 2280 = unop(Iop_1Uto32, binop(Iop_CmpLT64U, res, argL)); 2281 break; 2282 2283 case /* 1 */ PPCG_FLAG_OP_ADDE: 2284 /* res <u argL || (old_ca==1 && res==argL) */ 2285 xer_ca 2286 = mkOR1( 2287 binop(Iop_CmpLT64U, res, argL), 2288 mkAND1( 2289 binop(Iop_CmpEQ64, oldca, mkU64(1)), 2290 binop(Iop_CmpEQ64, res, argL) 2291 ) 2292 ); 2293 xer_ca 2294 = unop(Iop_1Uto32, xer_ca); 2295 break; 2296 2297 case /* 8 */ PPCG_FLAG_OP_SUBFE: 2298 /* res <u argR || (old_ca==1 && res==argR) */ 2299 xer_ca 2300 = mkOR1( 2301 binop(Iop_CmpLT64U, res, argR), 2302 mkAND1( 2303 binop(Iop_CmpEQ64, oldca, mkU64(1)), 2304 binop(Iop_CmpEQ64, res, argR) 2305 ) 2306 ); 2307 xer_ca 2308 = unop(Iop_1Uto32, xer_ca); 2309 break; 2310 2311 case /* 7 */ PPCG_FLAG_OP_SUBFC: 2312 case /* 9 */ PPCG_FLAG_OP_SUBFI: 2313 /* res <=u argR */ 2314 xer_ca 2315 = unop(Iop_1Uto32, binop(Iop_CmpLE64U, res, argR)); 2316 break; 2317 2318 2319 case /* 10 */ PPCG_FLAG_OP_SRAW: 2320 /* The shift amount is guaranteed to be in 0 .. 31 inclusive. 2321 If it is <= 31, behave like SRAWI; else XER.CA is the sign 2322 bit of argL. */ 2323 /* This term valid for shift amount < 31 only */ 2324 2325 xer_ca 2326 = binop( 2327 Iop_And64, 2328 binop(Iop_Sar64, argL, mkU8(31)), 2329 binop( Iop_And64, 2330 argL, 2331 binop( Iop_Sub64, 2332 binop(Iop_Shl64, mkU64(1), 2333 unop(Iop_64to8,argR)), 2334 mkU64(1) ) 2335 ) 2336 ); 2337 xer_ca 2338 = IRExpr_Mux0X( 2339 /* shift amt > 31 ? */ 2340 unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(31), argR)), 2341 /* no -- be like srawi */ 2342 unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))), 2343 /* yes -- get sign bit of argL */ 2344 unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63))) 2345 ); 2346 break; 2347 2348 case /* 11 */ PPCG_FLAG_OP_SRAWI: 2349 /* xer_ca is 1 iff src was negative and bits_shifted_out != 0. 2350 Since the shift amount is known to be in the range 0 .. 31 2351 inclusive the following seems viable: 2352 xer.ca == 1 iff the following is nonzero: 2353 (argL >>s 31) -- either all 0s or all 1s 2354 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2355 2356 xer_ca 2357 = binop( 2358 Iop_And64, 2359 binop(Iop_Sar64, argL, mkU8(31)), 2360 binop( Iop_And64, 2361 argL, 2362 binop( Iop_Sub64, 2363 binop(Iop_Shl64, mkU64(1), 2364 unop(Iop_64to8,argR)), 2365 mkU64(1) ) 2366 ) 2367 ); 2368 xer_ca 2369 = unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))); 2370 break; 2371 2372 2373 case /* 12 */ PPCG_FLAG_OP_SRAD: 2374 /* The shift amount is guaranteed to be in 0 .. 63 inclusive. 2375 If it is <= 63, behave like SRADI; else XER.CA is the sign 2376 bit of argL. */ 2377 /* This term valid for shift amount < 63 only */ 2378 2379 xer_ca 2380 = binop( 2381 Iop_And64, 2382 binop(Iop_Sar64, argL, mkU8(63)), 2383 binop( Iop_And64, 2384 argL, 2385 binop( Iop_Sub64, 2386 binop(Iop_Shl64, mkU64(1), 2387 unop(Iop_64to8,argR)), 2388 mkU64(1) ) 2389 ) 2390 ); 2391 xer_ca 2392 = IRExpr_Mux0X( 2393 /* shift amt > 63 ? */ 2394 unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(63), argR)), 2395 /* no -- be like sradi */ 2396 unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))), 2397 /* yes -- get sign bit of argL */ 2398 unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63))) 2399 ); 2400 break; 2401 2402 2403 case /* 13 */ PPCG_FLAG_OP_SRADI: 2404 /* xer_ca is 1 iff src was negative and bits_shifted_out != 0. 2405 Since the shift amount is known to be in the range 0 .. 63 2406 inclusive, the following seems viable: 2407 xer.ca == 1 iff the following is nonzero: 2408 (argL >>s 63) -- either all 0s or all 1s 2409 & (argL & (1<<argR)-1) -- the stuff shifted out */ 2410 2411 xer_ca 2412 = binop( 2413 Iop_And64, 2414 binop(Iop_Sar64, argL, mkU8(63)), 2415 binop( Iop_And64, 2416 argL, 2417 binop( Iop_Sub64, 2418 binop(Iop_Shl64, mkU64(1), 2419 unop(Iop_64to8,argR)), 2420 mkU64(1) ) 2421 ) 2422 ); 2423 xer_ca 2424 = unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))); 2425 break; 2426 2427 default: 2428 vex_printf("set_XER_CA: op = %u\n", op); 2429 vpanic("set_XER_CA(ppc64)"); 2430 } 2431 2432 /* xer_ca MUST denote either 0 or 1, no other value allowed */ 2433 putXER_CA( unop(Iop_32to8, xer_ca) ); 2434 } 2435 2436 static void set_XER_CA ( IRType ty, UInt op, IRExpr* res, 2437 IRExpr* argL, IRExpr* argR, IRExpr* oldca ) 2438 { 2439 if (ty == Ity_I32) 2440 set_XER_CA_32( op, res, argL, argR, oldca ); 2441 else 2442 set_XER_CA_64( op, res, argL, argR, oldca ); 2443 } 2444 2445 2446 2447 /*------------------------------------------------------------*/ 2448 /*--- Read/write to guest-state --- */ 2449 /*------------------------------------------------------------*/ 2450 2451 static IRExpr* /* :: Ity_I32/64 */ getGST ( PPC_GST reg ) 2452 { 2453 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2454 switch (reg) { 2455 case PPC_GST_SPRG3_RO: 2456 return IRExpr_Get( OFFB_SPRG3_RO, ty ); 2457 2458 case PPC_GST_CIA: 2459 return IRExpr_Get( OFFB_CIA, ty ); 2460 2461 case PPC_GST_LR: 2462 return IRExpr_Get( OFFB_LR, ty ); 2463 2464 case PPC_GST_CTR: 2465 return IRExpr_Get( OFFB_CTR, ty ); 2466 2467 case PPC_GST_VRSAVE: 2468 return IRExpr_Get( OFFB_VRSAVE, Ity_I32 ); 2469 2470 case PPC_GST_VSCR: 2471 return binop(Iop_And32, IRExpr_Get( OFFB_VSCR,Ity_I32 ), 2472 mkU32(MASK_VSCR_VALID)); 2473 2474 case PPC_GST_CR: { 2475 /* Synthesise the entire CR into a single word. Expensive. */ 2476 # define FIELD(_n) \ 2477 binop(Iop_Shl32, \ 2478 unop(Iop_8Uto32, \ 2479 binop(Iop_Or8, \ 2480 binop(Iop_And8, getCR321(_n), mkU8(7<<1)), \ 2481 binop(Iop_And8, getCR0(_n), mkU8(1)) \ 2482 ) \ 2483 ), \ 2484 mkU8(4 * (7-(_n))) \ 2485 ) 2486 return binop(Iop_Or32, 2487 binop(Iop_Or32, 2488 binop(Iop_Or32, FIELD(0), FIELD(1)), 2489 binop(Iop_Or32, FIELD(2), FIELD(3)) 2490 ), 2491 binop(Iop_Or32, 2492 binop(Iop_Or32, FIELD(4), FIELD(5)), 2493 binop(Iop_Or32, FIELD(6), FIELD(7)) 2494 ) 2495 ); 2496 # undef FIELD 2497 } 2498 2499 case PPC_GST_XER: 2500 return binop(Iop_Or32, 2501 binop(Iop_Or32, 2502 binop( Iop_Shl32, getXER_SO32(), mkU8(31)), 2503 binop( Iop_Shl32, getXER_OV32(), mkU8(30))), 2504 binop(Iop_Or32, 2505 binop( Iop_Shl32, getXER_CA32(), mkU8(29)), 2506 getXER_BC32())); 2507 2508 default: 2509 vex_printf("getGST(ppc): reg = %u", reg); 2510 vpanic("getGST(ppc)"); 2511 } 2512 } 2513 2514 /* Get a masked word from the given reg */ 2515 static IRExpr* /* ::Ity_I32 */ getGST_masked ( PPC_GST reg, UInt mask ) 2516 { 2517 IRTemp val = newTemp(Ity_I32); 2518 vassert( reg < PPC_GST_MAX ); 2519 2520 switch (reg) { 2521 2522 case PPC_GST_FPSCR: { 2523 /* Vex-generated code expects the FPSCR to be set as follows: 2524 all exceptions masked, round-to-nearest. 2525 This corresponds to a FPSCR value of 0x0. */ 2526 2527 /* In the lower 32 bits of FPSCR, we're only keeping track of 2528 * the binary floating point rounding mode, so if the mask isn't 2529 * asking for this, just return 0x0. 2530 */ 2531 if (mask & MASK_FPSCR_RN) { 2532 assign( val, unop( Iop_8Uto32, IRExpr_Get( OFFB_FPROUND, Ity_I8 ) ) ); 2533 } else { 2534 assign( val, mkU32(0x0) ); 2535 } 2536 break; 2537 } 2538 2539 default: 2540 vex_printf("getGST_masked(ppc): reg = %u", reg); 2541 vpanic("getGST_masked(ppc)"); 2542 } 2543 2544 if (mask != 0xFFFFFFFF) { 2545 return binop(Iop_And32, mkexpr(val), mkU32(mask)); 2546 } else { 2547 return mkexpr(val); 2548 } 2549 } 2550 2551 /* Get a masked word from the given reg */ 2552 static IRExpr* /* ::Ity_I32 */getGST_masked_upper(PPC_GST reg, ULong mask) { 2553 IRExpr * val; 2554 vassert( reg < PPC_GST_MAX ); 2555 2556 switch (reg) { 2557 2558 case PPC_GST_FPSCR: { 2559 /* In the upper 32 bits of FPSCR, we're only keeping track 2560 * of the decimal floating point rounding mode, so if the mask 2561 * isn't asking for this, just return 0x0. 2562 */ 2563 if (mask & MASK_FPSCR_DRN) { 2564 val = binop( Iop_And32, 2565 unop( Iop_8Uto32, IRExpr_Get( OFFB_DFPROUND, Ity_I8 ) ), 2566 unop( Iop_64HIto32, mkU64( mask ) ) ); 2567 } else { 2568 val = mkU32( 0x0ULL ); 2569 } 2570 break; 2571 } 2572 2573 default: 2574 vex_printf( "getGST_masked_upper(ppc): reg = %u", reg ); 2575 vpanic( "getGST_masked_upper(ppc)" ); 2576 } 2577 return val; 2578 } 2579 2580 2581 /* Fetch the specified REG[FLD] nibble (as per IBM/hardware notation) 2582 and return it at the bottom of an I32; the top 27 bits are 2583 guaranteed to be zero. */ 2584 static IRExpr* /* ::Ity_I32 */ getGST_field ( PPC_GST reg, UInt fld ) 2585 { 2586 UInt shft, mask; 2587 2588 vassert( fld < 8 ); 2589 vassert( reg < PPC_GST_MAX ); 2590 2591 shft = 4*(7-fld); 2592 mask = 0xF<<shft; 2593 2594 switch (reg) { 2595 case PPC_GST_XER: 2596 vassert(fld ==7); 2597 return binop(Iop_Or32, 2598 binop(Iop_Or32, 2599 binop(Iop_Shl32, getXER_SO32(), mkU8(3)), 2600 binop(Iop_Shl32, getXER_OV32(), mkU8(2))), 2601 binop( Iop_Shl32, getXER_CA32(), mkU8(1))); 2602 break; 2603 2604 default: 2605 if (shft == 0) 2606 return getGST_masked( reg, mask ); 2607 else 2608 return binop(Iop_Shr32, 2609 getGST_masked( reg, mask ), 2610 mkU8(toUChar( shft ))); 2611 } 2612 } 2613 2614 static void putGST ( PPC_GST reg, IRExpr* src ) 2615 { 2616 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2617 IRType ty_src = typeOfIRExpr(irsb->tyenv,src ); 2618 vassert( reg < PPC_GST_MAX ); 2619 switch (reg) { 2620 case PPC_GST_IP_AT_SYSCALL: 2621 vassert( ty_src == ty ); 2622 stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, src ) ); 2623 break; 2624 case PPC_GST_CIA: 2625 vassert( ty_src == ty ); 2626 stmt( IRStmt_Put( OFFB_CIA, src ) ); 2627 break; 2628 case PPC_GST_LR: 2629 vassert( ty_src == ty ); 2630 stmt( IRStmt_Put( OFFB_LR, src ) ); 2631 break; 2632 case PPC_GST_CTR: 2633 vassert( ty_src == ty ); 2634 stmt( IRStmt_Put( OFFB_CTR, src ) ); 2635 break; 2636 case PPC_GST_VRSAVE: 2637 vassert( ty_src == Ity_I32 ); 2638 stmt( IRStmt_Put( OFFB_VRSAVE,src)); 2639 break; 2640 case PPC_GST_VSCR: 2641 vassert( ty_src == Ity_I32 ); 2642 stmt( IRStmt_Put( OFFB_VSCR, 2643 binop(Iop_And32, src, 2644 mkU32(MASK_VSCR_VALID)) ) ); 2645 break; 2646 case PPC_GST_XER: 2647 vassert( ty_src == Ity_I32 ); 2648 putXER_SO( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(31))) ); 2649 putXER_OV( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(30))) ); 2650 putXER_CA( unop(Iop_32to8, binop(Iop_Shr32, src, mkU8(29))) ); 2651 putXER_BC( unop(Iop_32to8, src) ); 2652 break; 2653 2654 case PPC_GST_EMWARN: 2655 vassert( ty_src == Ity_I32 ); 2656 stmt( IRStmt_Put( OFFB_EMWARN,src) ); 2657 break; 2658 2659 case PPC_GST_TISTART: 2660 vassert( ty_src == ty ); 2661 stmt( IRStmt_Put( OFFB_TISTART, src) ); 2662 break; 2663 2664 case PPC_GST_TILEN: 2665 vassert( ty_src == ty ); 2666 stmt( IRStmt_Put( OFFB_TILEN, src) ); 2667 break; 2668 2669 default: 2670 vex_printf("putGST(ppc): reg = %u", reg); 2671 vpanic("putGST(ppc)"); 2672 } 2673 } 2674 2675 /* Write masked src to the given reg */ 2676 static void putGST_masked ( PPC_GST reg, IRExpr* src, ULong mask ) 2677 { 2678 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2679 vassert( reg < PPC_GST_MAX ); 2680 vassert( typeOfIRExpr( irsb->tyenv,src ) == Ity_I64 ); 2681 2682 switch (reg) { 2683 case PPC_GST_FPSCR: { 2684 /* Allow writes to either binary or decimal floating point 2685 * Rounding Mode 2686 */ 2687 if (mask & MASK_FPSCR_RN) { 2688 stmt( IRStmt_Put( OFFB_FPROUND, 2689 unop( Iop_32to8, 2690 binop( Iop_And32, 2691 unop( Iop_64to32, src ), 2692 mkU32( MASK_FPSCR_RN & mask ) ) ) ) ); 2693 } else if (mask & MASK_FPSCR_DRN) { 2694 stmt( IRStmt_Put( OFFB_DFPROUND, 2695 unop( Iop_32to8, 2696 binop( Iop_And32, 2697 unop( Iop_64HIto32, src ), 2698 mkU32( ( MASK_FPSCR_DRN & mask ) 2699 >> 32 ) ) ) ) ); 2700 } 2701 2702 /* Give EmWarn for attempted writes to: 2703 - Exception Controls 2704 - Non-IEEE Mode 2705 */ 2706 if (mask & 0xFC) { // Exception Control, Non-IEE mode 2707 VexEmWarn ew = EmWarn_PPCexns; 2708 2709 /* If any of the src::exception_control bits are actually set, 2710 side-exit to the next insn, reporting the warning, 2711 so that Valgrind's dispatcher sees the warning. */ 2712 putGST( PPC_GST_EMWARN, mkU32(ew) ); 2713 stmt( 2714 IRStmt_Exit( 2715 binop(Iop_CmpNE32, mkU32(ew), mkU32(EmWarn_NONE)), 2716 Ijk_EmWarn, 2717 mkSzConst( ty, nextInsnAddr()), OFFB_CIA )); 2718 } 2719 2720 /* Ignore all other writes */ 2721 break; 2722 } 2723 2724 default: 2725 vex_printf("putGST_masked(ppc): reg = %u", reg); 2726 vpanic("putGST_masked(ppc)"); 2727 } 2728 } 2729 2730 /* Write the least significant nibble of src to the specified 2731 REG[FLD] (as per IBM/hardware notation). */ 2732 static void putGST_field ( PPC_GST reg, IRExpr* src, UInt fld ) 2733 { 2734 UInt shft; 2735 ULong mask; 2736 2737 vassert( typeOfIRExpr(irsb->tyenv,src ) == Ity_I32 ); 2738 vassert( fld < 16 ); 2739 vassert( reg < PPC_GST_MAX ); 2740 2741 if (fld < 8) 2742 shft = 4*(7-fld); 2743 else 2744 shft = 4*(15-fld); 2745 mask = 0xF<<shft; 2746 2747 switch (reg) { 2748 case PPC_GST_CR: 2749 putCR0 (fld, binop(Iop_And8, mkU8(1 ), unop(Iop_32to8, src))); 2750 putCR321(fld, binop(Iop_And8, mkU8(7<<1), unop(Iop_32to8, src))); 2751 break; 2752 2753 default: 2754 { 2755 IRExpr * src64 = unop( Iop_32Uto64, src ); 2756 2757 if (shft == 0) { 2758 putGST_masked( reg, src64, mask ); 2759 } else { 2760 putGST_masked( reg, 2761 binop( Iop_Shl64, src64, mkU8( toUChar( shft ) ) ), 2762 mask ); 2763 } 2764 } 2765 } 2766 } 2767 2768 /*------------------------------------------------------------*/ 2769 /* Helpers for VSX instructions that do floating point 2770 * operations and need to determine if a src contains a 2771 * special FP value. 2772 * 2773 *------------------------------------------------------------*/ 2774 2775 #define NONZERO_FRAC_MASK 0x000fffffffffffffULL 2776 #define FP_FRAC_PART(x) binop( Iop_And64, \ 2777 mkexpr( x ), \ 2778 mkU64( NONZERO_FRAC_MASK ) ) 2779 2780 // Returns exponent part of a single precision floating point as I32 2781 static IRExpr * fp_exp_part_sp(IRTemp src) 2782 { 2783 return binop( Iop_And32, 2784 binop( Iop_Shr32, mkexpr( src ), mkU8( 23 ) ), 2785 mkU32( 0xff ) ); 2786 } 2787 2788 // Returns exponent part of floating point as I32 2789 static IRExpr * fp_exp_part(IRTemp src, Bool sp) 2790 { 2791 IRExpr * exp; 2792 if (sp) 2793 return fp_exp_part_sp(src); 2794 2795 if (!mode64) 2796 exp = binop( Iop_And32, binop( Iop_Shr32, unop( Iop_64HIto32, 2797 mkexpr( src ) ), 2798 mkU8( 20 ) ), mkU32( 0x7ff ) ); 2799 else 2800 exp = unop( Iop_64to32, 2801 binop( Iop_And64, 2802 binop( Iop_Shr64, mkexpr( src ), mkU8( 52 ) ), 2803 mkU64( 0x7ff ) ) ); 2804 return exp; 2805 } 2806 2807 static IRExpr * is_Inf_sp(IRTemp src) 2808 { 2809 IRTemp frac_part = newTemp(Ity_I32); 2810 IRExpr * Inf_exp; 2811 2812 assign( frac_part, binop( Iop_And32, mkexpr(src), mkU32(0x007fffff)) ); 2813 Inf_exp = binop( Iop_CmpEQ32, fp_exp_part( src, True /*single precision*/ ), mkU32( 0xff ) ); 2814 return mkAND1( Inf_exp, binop( Iop_CmpEQ32, mkexpr( frac_part ), mkU32( 0 ) ) ); 2815 } 2816 2817 2818 // Infinity: exp = 7ff and fraction is zero; s = 0/1 2819 static IRExpr * is_Inf(IRTemp src, Bool sp) 2820 { 2821 IRExpr * Inf_exp, * hi32, * low32; 2822 IRTemp frac_part; 2823 2824 if (sp) 2825 return is_Inf_sp(src); 2826 2827 frac_part = newTemp(Ity_I64); 2828 assign( frac_part, FP_FRAC_PART(src) ); 2829 Inf_exp = binop( Iop_CmpEQ32, fp_exp_part( src, False /*not single precision*/ ), mkU32( 0x7ff ) ); 2830 hi32 = unop( Iop_64HIto32, mkexpr( frac_part ) ); 2831 low32 = unop( Iop_64to32, mkexpr( frac_part ) ); 2832 return mkAND1( Inf_exp, binop( Iop_CmpEQ32, binop( Iop_Or32, low32, hi32 ), 2833 mkU32( 0 ) ) ); 2834 } 2835 2836 static IRExpr * is_Zero_sp(IRTemp src) 2837 { 2838 IRTemp sign_less_part = newTemp(Ity_I32); 2839 assign( sign_less_part, binop( Iop_And32, mkexpr( src ), mkU32( SIGN_MASK32 ) ) ); 2840 return binop( Iop_CmpEQ32, mkexpr( sign_less_part ), mkU32( 0 ) ); 2841 } 2842 2843 // Zero: exp is zero and fraction is zero; s = 0/1 2844 static IRExpr * is_Zero(IRTemp src, Bool sp) 2845 { 2846 IRExpr * hi32, * low32; 2847 IRTemp sign_less_part; 2848 if (sp) 2849 return is_Zero_sp(src); 2850 2851 sign_less_part = newTemp(Ity_I64); 2852 2853 assign( sign_less_part, binop( Iop_And64, mkexpr( src ), mkU64( SIGN_MASK ) ) ); 2854 hi32 = unop( Iop_64HIto32, mkexpr( sign_less_part ) ); 2855 low32 = unop( Iop_64to32, mkexpr( sign_less_part ) ); 2856 return binop( Iop_CmpEQ32, binop( Iop_Or32, low32, hi32 ), 2857 mkU32( 0 ) ); 2858 } 2859 2860 /* SNAN: s = 1/0; exp = 0x7ff; fraction is nonzero, with highest bit '1' 2861 * QNAN: s = 1/0; exp = 0x7ff; fraction is nonzero, with highest bit '0' 2862 * This function returns an IRExpr value of '1' for any type of NaN. 2863 */ 2864 static IRExpr * is_NaN(IRTemp src) 2865 { 2866 IRExpr * NaN_exp, * hi32, * low32; 2867 IRTemp frac_part = newTemp(Ity_I64); 2868 2869 assign( frac_part, FP_FRAC_PART(src) ); 2870 hi32 = unop( Iop_64HIto32, mkexpr( frac_part ) ); 2871 low32 = unop( Iop_64to32, mkexpr( frac_part ) ); 2872 NaN_exp = binop( Iop_CmpEQ32, fp_exp_part( src, False /*not single precision*/ ), 2873 mkU32( 0x7ff ) ); 2874 2875 return mkAND1( NaN_exp, binop( Iop_CmpNE32, binop( Iop_Or32, low32, hi32 ), 2876 mkU32( 0 ) ) ); 2877 } 2878 2879 /* This function returns an IRExpr value of '1' for any type of NaN. 2880 * The passed 'src' argument is assumed to be Ity_I32. 2881 */ 2882 static IRExpr * is_NaN_32(IRTemp src) 2883 { 2884 #define NONZERO_FRAC_MASK32 0x007fffffULL 2885 #define FP_FRAC_PART32(x) binop( Iop_And32, \ 2886 mkexpr( x ), \ 2887 mkU32( NONZERO_FRAC_MASK32 ) ) 2888 2889 IRExpr * frac_part = FP_FRAC_PART32(src); 2890 IRExpr * exp_part = binop( Iop_And32, 2891 binop( Iop_Shr32, mkexpr( src ), mkU8( 23 ) ), 2892 mkU32( 0x0ff ) ); 2893 IRExpr * NaN_exp = binop( Iop_CmpEQ32, exp_part, mkU32( 0xff ) ); 2894 2895 return mkAND1( NaN_exp, binop( Iop_CmpNE32, frac_part, mkU32( 0 ) ) ); 2896 } 2897 2898 /* This helper function performs the negation part of operations of the form: 2899 * "Negate Multiply-<op>" 2900 * where "<op>" is either "Add" or "Sub". 2901 * 2902 * This function takes one argument -- the floating point intermediate result (converted to 2903 * Ity_I64 via Iop_ReinterpF64asI64) that was obtained from the "Multip-<op>" part of 2904 * the operation described above. 2905 */ 2906 static IRTemp getNegatedResult(IRTemp intermediateResult) 2907 { 2908 ULong signbit_mask = 0x8000000000000000ULL; 2909 IRTemp signbit_32 = newTemp(Ity_I32); 2910 IRTemp resultantSignbit = newTemp(Ity_I1); 2911 IRTemp negatedResult = newTemp(Ity_I64); 2912 assign( signbit_32, binop( Iop_Shr32, 2913 unop( Iop_64HIto32, 2914 binop( Iop_And64, mkexpr( intermediateResult ), 2915 mkU64( signbit_mask ) ) ), 2916 mkU8( 31 ) ) ); 2917 /* We negate the signbit if and only if the intermediate result from the 2918 * multiply-<op> was NOT a NaN. This is an XNOR predicate. 2919 */ 2920 assign( resultantSignbit, 2921 unop( Iop_Not1, 2922 binop( Iop_CmpEQ32, 2923 binop( Iop_Xor32, 2924 mkexpr( signbit_32 ), 2925 unop( Iop_1Uto32, is_NaN( intermediateResult ) ) ), 2926 mkU32( 1 ) ) ) ); 2927 2928 assign( negatedResult, 2929 binop( Iop_Or64, 2930 binop( Iop_And64, 2931 mkexpr( intermediateResult ), 2932 mkU64( ~signbit_mask ) ), 2933 binop( Iop_32HLto64, 2934 binop( Iop_Shl32, 2935 unop( Iop_1Uto32, mkexpr( resultantSignbit ) ), 2936 mkU8( 31 ) ), 2937 mkU32( 0 ) ) ) ); 2938 2939 return negatedResult; 2940 } 2941 2942 /* This helper function performs the negation part of operations of the form: 2943 * "Negate Multiply-<op>" 2944 * where "<op>" is either "Add" or "Sub". 2945 * 2946 * This function takes one argument -- the floating point intermediate result (converted to 2947 * Ity_I32 via Iop_ReinterpF32asI32) that was obtained from the "Multip-<op>" part of 2948 * the operation described above. 2949 */ 2950 static IRTemp getNegatedResult_32(IRTemp intermediateResult) 2951 { 2952 UInt signbit_mask = 0x80000000; 2953 IRTemp signbit_32 = newTemp(Ity_I32); 2954 IRTemp resultantSignbit = newTemp(Ity_I1); 2955 IRTemp negatedResult = newTemp(Ity_I32); 2956 assign( signbit_32, binop( Iop_Shr32, 2957 binop( Iop_And32, mkexpr( intermediateResult ), 2958 mkU32( signbit_mask ) ), 2959 mkU8( 31 ) ) ); 2960 /* We negate the signbit if and only if the intermediate result from the 2961 * multiply-<op> was NOT a NaN. This is an XNOR predicate. 2962 */ 2963 assign( resultantSignbit, 2964 unop( Iop_Not1, 2965 binop( Iop_CmpEQ32, 2966 binop( Iop_Xor32, 2967 mkexpr( signbit_32 ), 2968 unop( Iop_1Uto32, is_NaN_32( intermediateResult ) ) ), 2969 mkU32( 1 ) ) ) ); 2970 2971 assign( negatedResult, 2972 binop( Iop_Or32, 2973 binop( Iop_And32, 2974 mkexpr( intermediateResult ), 2975 mkU32( ~signbit_mask ) ), 2976 binop( Iop_Shl32, 2977 unop( Iop_1Uto32, mkexpr( resultantSignbit ) ), 2978 mkU8( 31 ) ) ) ); 2979 2980 return negatedResult; 2981 } 2982 2983 /*------------------------------------------------------------*/ 2984 /*--- Integer Instruction Translation --- */ 2985 /*------------------------------------------------------------*/ 2986 2987 /* 2988 Integer Arithmetic Instructions 2989 */ 2990 static Bool dis_int_arith ( UInt theInstr ) 2991 { 2992 /* D-Form, XO-Form */ 2993 UChar opc1 = ifieldOPC(theInstr); 2994 UChar rD_addr = ifieldRegDS(theInstr); 2995 UChar rA_addr = ifieldRegA(theInstr); 2996 UInt uimm16 = ifieldUIMM16(theInstr); 2997 UChar rB_addr = ifieldRegB(theInstr); 2998 UChar flag_OE = ifieldBIT10(theInstr); 2999 UInt opc2 = ifieldOPClo9(theInstr); 3000 UChar flag_rC = ifieldBIT0(theInstr); 3001 3002 Long simm16 = extend_s_16to64(uimm16); 3003 IRType ty = mode64 ? Ity_I64 : Ity_I32; 3004 IRTemp rA = newTemp(ty); 3005 IRTemp rB = newTemp(ty); 3006 IRTemp rD = newTemp(ty); 3007 3008 Bool do_rc = False; 3009 3010 assign( rA, getIReg(rA_addr) ); 3011 assign( rB, getIReg(rB_addr) ); // XO-Form: rD, rA, rB 3012 3013 switch (opc1) { 3014 /* D-Form */ 3015 case 0x0C: // addic (Add Immediate Carrying, PPC32 p351 3016 DIP("addic r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 3017 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3018 mkSzExtendS16(ty, uimm16) ) ); 3019 set_XER_CA( ty, PPCG_FLAG_OP_ADD, 3020 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 3021 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 3022 break; 3023 3024 case 0x0D: // addic. (Add Immediate Carrying and Record, PPC32 p352) 3025 DIP("addic. r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 3026 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3027 mkSzExtendS16(ty, uimm16) ) ); 3028 set_XER_CA( ty, PPCG_FLAG_OP_ADD, 3029 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 3030 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 3031 do_rc = True; // Always record to CR 3032 flag_rC = 1; 3033 break; 3034 3035 case 0x0E: // addi (Add Immediate, PPC32 p350) 3036 // li rD,val == addi rD,0,val 3037 // la disp(rA) == addi rD,rA,disp 3038 if ( rA_addr == 0 ) { 3039 DIP("li r%u,%d\n", rD_addr, (Int)simm16); 3040 assign( rD, mkSzExtendS16(ty, uimm16) ); 3041 } else { 3042 DIP("addi r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 3043 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3044 mkSzExtendS16(ty, uimm16) ) ); 3045 } 3046 break; 3047 3048 case 0x0F: // addis (Add Immediate Shifted, PPC32 p353) 3049 // lis rD,val == addis rD,0,val 3050 if ( rA_addr == 0 ) { 3051 DIP("lis r%u,%d\n", rD_addr, (Int)simm16); 3052 assign( rD, mkSzExtendS32(ty, uimm16 << 16) ); 3053 } else { 3054 DIP("addis r%u,r%u,0x%x\n", rD_addr, rA_addr, (Int)simm16); 3055 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3056 mkSzExtendS32(ty, uimm16 << 16) ) ); 3057 } 3058 break; 3059 3060 case 0x07: // mulli (Multiply Low Immediate, PPC32 p490) 3061 DIP("mulli r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 3062 if (mode64) 3063 assign( rD, unop(Iop_128to64, 3064 binop(Iop_MullS64, mkexpr(rA), 3065 mkSzExtendS16(ty, uimm16))) ); 3066 else 3067 assign( rD, unop(Iop_64to32, 3068 binop(Iop_MullS32, mkexpr(rA), 3069 mkSzExtendS16(ty, uimm16))) ); 3070 break; 3071 3072 case 0x08: // subfic (Subtract from Immediate Carrying, PPC32 p540) 3073 DIP("subfic r%u,r%u,%d\n", rD_addr, rA_addr, (Int)simm16); 3074 // rD = simm16 - rA 3075 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 3076 mkSzExtendS16(ty, uimm16), 3077 mkexpr(rA)) ); 3078 set_XER_CA( ty, PPCG_FLAG_OP_SUBFI, 3079 mkexpr(rD), mkexpr(rA), mkSzExtendS16(ty, uimm16), 3080 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 3081 break; 3082 3083 /* XO-Form */ 3084 case 0x1F: 3085 do_rc = True; // All below record to CR 3086 3087 switch (opc2) { 3088 case 0x10A: // add (Add, PPC32 p347) 3089 DIP("add%s%s r%u,r%u,r%u\n", 3090 flag_OE ? "o" : "", flag_rC ? ".":"", 3091 rD_addr, rA_addr, rB_addr); 3092 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3093 mkexpr(rA), mkexpr(rB) ) ); 3094 if (flag_OE) { 3095 set_XER_OV( ty, PPCG_FLAG_OP_ADD, 3096 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3097 } 3098 break; 3099 3100 case 0x00A: // addc (Add Carrying, PPC32 p348) 3101 DIP("addc%s%s r%u,r%u,r%u\n", 3102 flag_OE ? "o" : "", flag_rC ? ".":"", 3103 rD_addr, rA_addr, rB_addr); 3104 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3105 mkexpr(rA), mkexpr(rB)) ); 3106 set_XER_CA( ty, PPCG_FLAG_OP_ADD, 3107 mkexpr(rD), mkexpr(rA), mkexpr(rB), 3108 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 3109 if (flag_OE) { 3110 set_XER_OV( ty, PPCG_FLAG_OP_ADD, 3111 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3112 } 3113 break; 3114 3115 case 0x08A: { // adde (Add Extended, PPC32 p349) 3116 IRTemp old_xer_ca = newTemp(ty); 3117 DIP("adde%s%s r%u,r%u,r%u\n", 3118 flag_OE ? "o" : "", flag_rC ? ".":"", 3119 rD_addr, rA_addr, rB_addr); 3120 // rD = rA + rB + XER[CA] 3121 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3122 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3123 binop( mkSzOp(ty, Iop_Add8), 3124 mkexpr(rB), mkexpr(old_xer_ca))) ); 3125 set_XER_CA( ty, PPCG_FLAG_OP_ADDE, 3126 mkexpr(rD), mkexpr(rA), mkexpr(rB), 3127 mkexpr(old_xer_ca) ); 3128 if (flag_OE) { 3129 set_XER_OV( ty, PPCG_FLAG_OP_ADDE, 3130 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3131 } 3132 break; 3133 } 3134 3135 case 0x0EA: { // addme (Add to Minus One Extended, PPC32 p354) 3136 IRTemp old_xer_ca = newTemp(ty); 3137 IRExpr *min_one; 3138 if (rB_addr != 0) { 3139 vex_printf("dis_int_arith(ppc)(addme,rB_addr)\n"); 3140 return False; 3141 } 3142 DIP("addme%s%s r%u,r%u,r%u\n", 3143 flag_OE ? "o" : "", flag_rC ? ".":"", 3144 rD_addr, rA_addr, rB_addr); 3145 // rD = rA + (-1) + XER[CA] 3146 // => Just another form of adde 3147 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3148 min_one = mkSzImm(ty, (Long)-1); 3149 assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), 3150 binop( mkSzOp(ty, Iop_Add8), 3151 min_one, mkexpr(old_xer_ca)) )); 3152 set_XER_CA( ty, PPCG_FLAG_OP_ADDE, 3153 mkexpr(rD), mkexpr(rA), min_one, 3154 mkexpr(old_xer_ca) ); 3155 if (flag_OE) { 3156 set_XER_OV( ty, PPCG_FLAG_OP_ADDE, 3157 mkexpr(rD), mkexpr(rA), min_one ); 3158 } 3159 break; 3160 } 3161 3162 case 0x0CA: { // addze (Add to Zero Extended, PPC32 p355) 3163 IRTemp old_xer_ca = newTemp(ty); 3164 if (rB_addr != 0) { 3165 vex_printf("dis_int_arith(ppc)(addze,rB_addr)\n"); 3166 return False; 3167 } 3168 DIP("addze%s%s r%u,r%u,r%u\n", 3169 flag_OE ? "o" : "", flag_rC ? ".":"", 3170 rD_addr, rA_addr, rB_addr); 3171 // rD = rA + (0) + XER[CA] 3172 // => Just another form of adde 3173 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3174 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3175 mkexpr(rA), mkexpr(old_xer_ca)) ); 3176 set_XER_CA( ty, PPCG_FLAG_OP_ADDE, 3177 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0), 3178 mkexpr(old_xer_ca) ); 3179 if (flag_OE) { 3180 set_XER_OV( ty, PPCG_FLAG_OP_ADDE, 3181 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0) ); 3182 } 3183 break; 3184 } 3185 3186 case 0x1EB: // divw (Divide Word, PPC32 p388) 3187 DIP("divw%s%s r%u,r%u,r%u\n", 3188 flag_OE ? "o" : "", flag_rC ? ".":"", 3189 rD_addr, rA_addr, rB_addr); 3190 if (mode64) { 3191 /* Note: 3192 XER settings are mode independent, and reflect the 3193 overflow of the low-order 32bit result 3194 CR0[LT|GT|EQ] are undefined if flag_rC && mode64 3195 */ 3196 /* rD[hi32] are undefined: setting them to sign of lo32 3197 - makes set_CR0 happy */ 3198 IRExpr* dividend = mk64lo32Sto64( mkexpr(rA) ); 3199 IRExpr* divisor = mk64lo32Sto64( mkexpr(rB) ); 3200 assign( rD, mk64lo32Uto64( binop(Iop_DivS64, dividend, 3201 divisor) ) ); 3202 if (flag_OE) { 3203 set_XER_OV( ty, PPCG_FLAG_OP_DIVW, 3204 mkexpr(rD), dividend, divisor ); 3205 } 3206 } else { 3207 assign( rD, binop(Iop_DivS32, mkexpr(rA), mkexpr(rB)) ); 3208 if (flag_OE) { 3209 set_XER_OV( ty, PPCG_FLAG_OP_DIVW, 3210 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3211 } 3212 } 3213 /* Note: 3214 if (0x8000_0000 / -1) or (x / 0) 3215 => rD=undef, if(flag_rC) CR7=undef, if(flag_OE) XER_OV=1 3216 => But _no_ exception raised. */ 3217 break; 3218 3219 case 0x1CB: // divwu (Divide Word Unsigned, PPC32 p389) 3220 DIP("divwu%s%s r%u,r%u,r%u\n", 3221 flag_OE ? "o" : "", flag_rC ? ".":"", 3222 rD_addr, rA_addr, rB_addr); 3223 if (mode64) { 3224 /* Note: 3225 XER settings are mode independent, and reflect the 3226 overflow of the low-order 32bit result 3227 CR0[LT|GT|EQ] are undefined if flag_rC && mode64 3228 */ 3229 IRExpr* dividend = mk64lo32Uto64( mkexpr(rA) ); 3230 IRExpr* divisor = mk64lo32Uto64( mkexpr(rB) ); 3231 assign( rD, mk64lo32Uto64( binop(Iop_DivU64, dividend, 3232 divisor) ) ); 3233 if (flag_OE) { 3234 set_XER_OV( ty, PPCG_FLAG_OP_DIVWU, 3235 mkexpr(rD), dividend, divisor ); 3236 } 3237 } else { 3238 assign( rD, binop(Iop_DivU32, mkexpr(rA), mkexpr(rB)) ); 3239 if (flag_OE) { 3240 set_XER_OV( ty, PPCG_FLAG_OP_DIVWU, 3241 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3242 } 3243 } 3244 /* Note: ditto comment divw, for (x / 0) */ 3245 break; 3246 3247 case 0x04B: // mulhw (Multiply High Word, PPC32 p488) 3248 if (flag_OE != 0) { 3249 vex_printf("dis_int_arith(ppc)(mulhw,flag_OE)\n"); 3250 return False; 3251 } 3252 DIP("mulhw%s r%u,r%u,r%u\n", flag_rC ? ".":"", 3253 rD_addr, rA_addr, rB_addr); 3254 if (mode64) { 3255 /* rD[hi32] are undefined: setting them to sign of lo32 3256 - makes set_CR0 happy */ 3257 assign( rD, binop(Iop_Sar64, 3258 binop(Iop_Mul64, 3259 mk64lo32Sto64( mkexpr(rA) ), 3260 mk64lo32Sto64( mkexpr(rB) )), 3261 mkU8(32)) ); 3262 } else { 3263 assign( rD, unop(Iop_64HIto32, 3264 binop(Iop_MullS32, 3265 mkexpr(rA), mkexpr(rB))) ); 3266 } 3267 break; 3268 3269 case 0x00B: // mulhwu (Multiply High Word Unsigned, PPC32 p489) 3270 if (flag_OE != 0) { 3271 vex_printf("dis_int_arith(ppc)(mulhwu,flag_OE)\n"); 3272 return False; 3273 } 3274 DIP("mulhwu%s r%u,r%u,r%u\n", flag_rC ? ".":"", 3275 rD_addr, rA_addr, rB_addr); 3276 if (mode64) { 3277 /* rD[hi32] are undefined: setting them to sign of lo32 3278 - makes set_CR0 happy */ 3279 assign( rD, binop(Iop_Sar64, 3280 binop(Iop_Mul64, 3281 mk64lo32Uto64( mkexpr(rA) ), 3282 mk64lo32Uto64( mkexpr(rB) ) ), 3283 mkU8(32)) ); 3284 } else { 3285 assign( rD, unop(Iop_64HIto32, 3286 binop(Iop_MullU32, 3287 mkexpr(rA), mkexpr(rB))) ); 3288 } 3289 break; 3290 3291 case 0x0EB: // mullw (Multiply Low Word, PPC32 p491) 3292 DIP("mullw%s%s r%u,r%u,r%u\n", 3293 flag_OE ? "o" : "", flag_rC ? ".":"", 3294 rD_addr, rA_addr, rB_addr); 3295 if (mode64) { 3296 /* rD[hi32] are undefined: setting them to sign of lo32 3297 - set_XER_OV() and set_CR0() depend on this */ 3298 IRExpr *a = unop(Iop_64to32, mkexpr(rA) ); 3299 IRExpr *b = unop(Iop_64to32, mkexpr(rB) ); 3300 assign( rD, binop(Iop_MullS32, a, b) ); 3301 if (flag_OE) { 3302 set_XER_OV( ty, PPCG_FLAG_OP_MULLW, 3303 mkexpr(rD), 3304 unop(Iop_32Uto64, a), unop(Iop_32Uto64, b) ); 3305 } 3306 } else { 3307 assign( rD, unop(Iop_64to32, 3308 binop(Iop_MullU32, 3309 mkexpr(rA), mkexpr(rB))) ); 3310 if (flag_OE) { 3311 set_XER_OV( ty, PPCG_FLAG_OP_MULLW, 3312 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3313 } 3314 } 3315 break; 3316 3317 case 0x068: // neg (Negate, PPC32 p493) 3318 if (rB_addr != 0) { 3319 vex_printf("dis_int_arith(ppc)(neg,rB_addr)\n"); 3320 return False; 3321 } 3322 DIP("neg%s%s r%u,r%u\n", 3323 flag_OE ? "o" : "", flag_rC ? ".":"", 3324 rD_addr, rA_addr); 3325 // rD = (~rA) + 1 3326 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3327 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA) ), 3328 mkSzImm(ty, 1)) ); 3329 if (flag_OE) { 3330 set_XER_OV( ty, PPCG_FLAG_OP_NEG, 3331 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3332 } 3333 break; 3334 3335 case 0x028: // subf (Subtract From, PPC32 p537) 3336 DIP("subf%s%s r%u,r%u,r%u\n", 3337 flag_OE ? "o" : "", flag_rC ? ".":"", 3338 rD_addr, rA_addr, rB_addr); 3339 // rD = rB - rA 3340 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 3341 mkexpr(rB), mkexpr(rA)) ); 3342 if (flag_OE) { 3343 set_XER_OV( ty, PPCG_FLAG_OP_SUBF, 3344 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3345 } 3346 break; 3347 3348 case 0x008: // subfc (Subtract from Carrying, PPC32 p538) 3349 DIP("subfc%s%s r%u,r%u,r%u\n", 3350 flag_OE ? "o" : "", flag_rC ? ".":"", 3351 rD_addr, rA_addr, rB_addr); 3352 // rD = rB - rA 3353 assign( rD, binop( mkSzOp(ty, Iop_Sub8), 3354 mkexpr(rB), mkexpr(rA)) ); 3355 set_XER_CA( ty, PPCG_FLAG_OP_SUBFC, 3356 mkexpr(rD), mkexpr(rA), mkexpr(rB), 3357 mkSzImm(ty, 0)/*old xer.ca, which is ignored*/ ); 3358 if (flag_OE) { 3359 set_XER_OV( ty, PPCG_FLAG_OP_SUBFC, 3360 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3361 } 3362 break; 3363 3364 case 0x088: {// subfe (Subtract from Extended, PPC32 p539) 3365 IRTemp old_xer_ca = newTemp(ty); 3366 DIP("subfe%s%s r%u,r%u,r%u\n", 3367 flag_OE ? "o" : "", flag_rC ? ".":"", 3368 rD_addr, rA_addr, rB_addr); 3369 // rD = (log not)rA + rB + XER[CA] 3370 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3371 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3372 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA)), 3373 binop( mkSzOp(ty, Iop_Add8), 3374 mkexpr(rB), mkexpr(old_xer_ca))) ); 3375 set_XER_CA( ty, PPCG_FLAG_OP_SUBFE, 3376 mkexpr(rD), mkexpr(rA), mkexpr(rB), 3377 mkexpr(old_xer_ca) ); 3378 if (flag_OE) { 3379 set_XER_OV( ty, PPCG_FLAG_OP_SUBFE, 3380 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3381 } 3382 break; 3383 } 3384 3385 case 0x0E8: { // subfme (Subtract from -1 Extended, PPC32 p541) 3386 IRTemp old_xer_ca = newTemp(ty); 3387 IRExpr *min_one; 3388 if (rB_addr != 0) { 3389 vex_printf("dis_int_arith(ppc)(subfme,rB_addr)\n"); 3390 return False; 3391 } 3392 DIP("subfme%s%s r%u,r%u\n", 3393 flag_OE ? "o" : "", flag_rC ? ".":"", 3394 rD_addr, rA_addr); 3395 // rD = (log not)rA + (-1) + XER[CA] 3396 // => Just another form of subfe 3397 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3398 min_one = mkSzImm(ty, (Long)-1); 3399 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3400 unop( mkSzOp(ty, Iop_Not8), mkexpr(rA)), 3401 binop( mkSzOp(ty, Iop_Add8), 3402 min_one, mkexpr(old_xer_ca))) ); 3403 set_XER_CA( ty, PPCG_FLAG_OP_SUBFE, 3404 mkexpr(rD), mkexpr(rA), min_one, 3405 mkexpr(old_xer_ca) ); 3406 if (flag_OE) { 3407 set_XER_OV( ty, PPCG_FLAG_OP_SUBFE, 3408 mkexpr(rD), mkexpr(rA), min_one ); 3409 } 3410 break; 3411 } 3412 3413 case 0x0C8: { // subfze (Subtract from Zero Extended, PPC32 p542) 3414 IRTemp old_xer_ca = newTemp(ty); 3415 if (rB_addr != 0) { 3416 vex_printf("dis_int_arith(ppc)(subfze,rB_addr)\n"); 3417 return False; 3418 } 3419 DIP("subfze%s%s r%u,r%u\n", 3420 flag_OE ? "o" : "", flag_rC ? ".":"", 3421 rD_addr, rA_addr); 3422 // rD = (log not)rA + (0) + XER[CA] 3423 // => Just another form of subfe 3424 assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA32(), False) ); 3425 assign( rD, binop( mkSzOp(ty, Iop_Add8), 3426 unop( mkSzOp(ty, Iop_Not8), 3427 mkexpr(rA)), mkexpr(old_xer_ca)) ); 3428 set_XER_CA( ty, PPCG_FLAG_OP_SUBFE, 3429 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0), 3430 mkexpr(old_xer_ca) ); 3431 if (flag_OE) { 3432 set_XER_OV( ty, PPCG_FLAG_OP_SUBFE, 3433 mkexpr(rD), mkexpr(rA), mkSzImm(ty, 0) ); 3434 } 3435 break; 3436 } 3437 3438 3439 /* 64bit Arithmetic */ 3440 case 0x49: // mulhd (Multiply High DWord, PPC64 p539) 3441 if (flag_OE != 0) { 3442 vex_printf("dis_int_arith(ppc)(mulhd,flagOE)\n"); 3443 return False; 3444 } 3445 DIP("mulhd%s r%u,r%u,r%u\n", flag_rC ? ".":"", 3446 rD_addr, rA_addr, rB_addr); 3447 assign( rD, unop(Iop_128HIto64, 3448 binop(Iop_MullS64, 3449 mkexpr(rA), mkexpr(rB))) ); 3450 3451 break; 3452 3453 case 0x9: // mulhdu (Multiply High DWord Unsigned, PPC64 p540) 3454 if (flag_OE != 0) { 3455 vex_printf("dis_int_arith(ppc)(mulhdu,flagOE)\n"); 3456 return False; 3457 } 3458 DIP("mulhdu%s r%u,r%u,r%u\n", flag_rC ? ".":"", 3459 rD_addr, rA_addr, rB_addr); 3460 assign( rD, unop(Iop_128HIto64, 3461 binop(Iop_MullU64, 3462 mkexpr(rA), mkexpr(rB))) ); 3463 break; 3464 3465 case 0xE9: // mulld (Multiply Low DWord, PPC64 p543) 3466 DIP("mulld%s%s r%u,r%u,r%u\n", 3467 flag_OE ? "o" : "", flag_rC ? ".":"", 3468 rD_addr, rA_addr, rB_addr); 3469 assign( rD, binop(Iop_Mul64, mkexpr(rA), mkexpr(rB)) ); 3470 if (flag_OE) { 3471 set_XER_OV( ty, PPCG_FLAG_OP_MULLW, 3472 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3473 } 3474 break; 3475 3476 case 0x1E9: // divd (Divide DWord, PPC64 p419) 3477 DIP("divd%s%s r%u,r%u,r%u\n", 3478 flag_OE ? "o" : "", flag_rC ? ".":"", 3479 rD_addr, rA_addr, rB_addr); 3480 assign( rD, binop(Iop_DivS64, mkexpr(rA), mkexpr(rB)) ); 3481 if (flag_OE) { 3482 set_XER_OV( ty, PPCG_FLAG_OP_DIVW, 3483 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3484 } 3485 break; 3486 /* Note: 3487 if (0x8000_0000_0000_0000 / -1) or (x / 0) 3488 => rD=undef, if(flag_rC) CR7=undef, if(flag_OE) XER_OV=1 3489 => But _no_ exception raised. */ 3490 3491 case 0x1C9: // divdu (Divide DWord Unsigned, PPC64 p420) 3492 DIP("divdu%s%s r%u,r%u,r%u\n", 3493 flag_OE ? "o" : "", flag_rC ? ".":"", 3494 rD_addr, rA_addr, rB_addr); 3495 assign( rD, binop(Iop_DivU64, mkexpr(rA), mkexpr(rB)) ); 3496 if (flag_OE) { 3497 set_XER_OV( ty, PPCG_FLAG_OP_DIVWU, 3498 mkexpr(rD), mkexpr(rA), mkexpr(rB) ); 3499 } 3500 break; 3501 /* Note: ditto comment divd, for (x / 0) */ 3502 3503 case 0x18B: // divweu (Divide Word Extended Unsigned) 3504 { 3505 /* 3506 * If (RA) >= (RB), or if an attempt is made to perform the division 3507 * <anything> / 0 3508 * then the contents of register RD are undefined as are (if Rc=1) the contents of 3509 * the LT, GT, and EQ bits of CR Field 0. In these cases, if OE=1 then OV is set 3510 * to 1. 3511 */ 3512 IRTemp res = newTemp(Ity_I32); 3513 IRExpr * dividend, * divisor; 3514 DIP("divweu%s%s r%u,r%u,r%u\n", 3515 flag_OE ? "o" : "", flag_rC ? ".":"", 3516 rD_addr, rA_addr, rB_addr); 3517 if (mode64) { 3518 dividend = unop( Iop_64to32, mkexpr( rA ) ); 3519 divisor = unop( Iop_64to32, mkexpr( rB ) ); 3520 assign( res, binop( Iop_DivU32E, dividend, divisor ) ); 3521 assign( rD, binop( Iop_32HLto64, mkU32( 0 ), mkexpr( res ) ) ); 3522 } else { 3523 dividend = mkexpr( rA ); 3524 divisor = mkexpr( rB ); 3525 assign( res, binop( Iop_DivU32E, dividend, divisor ) ); 3526 assign( rD, mkexpr( res) ); 3527 } 3528 3529 if (flag_OE) { 3530 set_XER_OV_32( PPCG_FLAG_OP_DIVWEU, 3531 mkexpr(res), dividend, divisor ); 3532 } 3533 break; 3534 } 3535 3536 case 0x1AB: // divwe (Divide Word Extended) 3537 { 3538 /* 3539 * If the quotient cannot be represented in 32 bits, or if an 3540 * attempt is made to perform the division 3541 * <anything> / 0 3542 * then the contents of register RD are undefined as are (if 3543 * Rc=1) the contents of the LT, GT, and EQ bits of CR 3544 * Field 0. In these cases, if OE=1 then OV is set to 1. 3545 */ 3546 3547 IRTemp res = newTemp(Ity_I32); 3548 IRExpr * dividend, * divisor; 3549 DIP("divwe%s%s r%u,r%u,r%u\n", 3550 flag_OE ? "o" : "", flag_rC ? ".":"", 3551 rD_addr, rA_addr, rB_addr); 3552 if (mode64) { 3553 dividend = unop( Iop_64to32, mkexpr( rA ) ); 3554 divisor = unop( Iop_64to32, mkexpr( rB ) ); 3555 assign( res, binop( Iop_DivS32E, dividend, divisor ) ); 3556 assign( rD, binop( Iop_32HLto64, mkU32( 0 ), mkexpr( res ) ) ); 3557 } else { 3558 dividend = mkexpr( rA ); 3559 divisor = mkexpr( rB ); 3560 assign( res, binop( Iop_DivS32E, dividend, divisor ) ); 3561 assign( rD, mkexpr( res) ); 3562 } 3563 3564 if (flag_OE) { 3565 set_XER_OV_32( PPCG_FLAG_OP_DIVWE, 3566 mkexpr(res), dividend, divisor ); 3567 } 3568 break; 3569 } 3570 3571 3572 case 0x1A9: // divde (Divide Doubleword Extended) 3573 /* 3574 * If the quotient cannot be represented in 64 bits, or if an 3575 * attempt is made to perform the division 3576 * <anything> / 0 3577 * then the contents of register RD are undefined as are (if 3578 * Rc=1) the contents of the LT, GT, and EQ bits of CR 3579 * Field 0. In these cases, if OE=1 then OV is set to 1. 3580 */ 3581 DIP("divde%s%s r%u,r%u,r%u\n", 3582 flag_OE ? "o" : "", flag_rC ? ".":"", 3583 rD_addr, rA_addr, rB_addr); 3584 assign( rD, binop(Iop_DivS64E, mkexpr(rA), mkexpr(rB)) ); 3585 if (flag_OE) { 3586 set_XER_OV_64( PPCG_FLAG_OP_DIVDE, mkexpr( rD ), 3587 mkexpr( rA ), mkexpr( rB ) ); 3588 } 3589 break; 3590 3591 case 0x189: // divdeuo (Divide Doubleword Extended Unsigned) 3592 // Same CR and OV rules as given for divweu above 3593 DIP("divdeu%s%s r%u,r%u,r%u\n", 3594 flag_OE ? "o" : "", flag_rC ? ".":"", 3595 rD_addr, rA_addr, rB_addr); 3596 assign( rD, binop(Iop_DivU64E, mkexpr(rA), mkexpr(rB)) ); 3597 if (flag_OE) { 3598 set_XER_OV_64( PPCG_FLAG_OP_DIVDEU, mkexpr( rD ), 3599 mkexpr( rA ), mkexpr( rB ) ); 3600 } 3601 break; 3602 3603 default: 3604 vex_printf("dis_int_arith(ppc)(opc2)\n"); 3605 return False; 3606 } 3607 break; 3608 3609 default: 3610 vex_printf("dis_int_arith(ppc)(opc1)\n"); 3611 return False; 3612 } 3613 3614 putIReg( rD_addr, mkexpr(rD) ); 3615 3616 if (do_rc && flag_rC) { 3617 set_CR0( mkexpr(rD) ); 3618 } 3619 return True; 3620 } 3621 3622 3623 3624 /* 3625 Integer Compare Instructions 3626 */ 3627 static Bool dis_int_cmp ( UInt theInstr ) 3628 { 3629 /* D-Form, X-Form */ 3630 UChar opc1 = ifieldOPC(theInstr); 3631 UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); 3632 UChar b22 = toUChar( IFIELD( theInstr, 22, 1 ) ); 3633 UChar flag_L = toUChar( IFIELD( theInstr, 21, 1 ) ); 3634 UChar rA_addr = ifieldRegA(theInstr); 3635 UInt uimm16 = ifieldUIMM16(theInstr); 3636 UChar rB_addr = ifieldRegB(theInstr); 3637 UInt opc2 = ifieldOPClo10(theInstr); 3638 UChar b0 = ifieldBIT0(theInstr); 3639 3640 IRType ty = mode64 ? Ity_I64 : Ity_I32; 3641 IRExpr *a = getIReg(rA_addr); 3642 IRExpr *b; 3643 3644 if (!mode64 && flag_L==1) { // L==1 invalid for 32 bit. 3645 vex_printf("dis_int_cmp(ppc)(flag_L)\n"); 3646 return False; 3647 } 3648 3649 if (b22 != 0) { 3650 vex_printf("dis_int_cmp(ppc)(b22)\n"); 3651 return False; 3652 } 3653 3654 switch (opc1) { 3655 case 0x0B: // cmpi (Compare Immediate, PPC32 p368) 3656 DIP("cmpi cr%u,%u,r%u,%d\n", crfD, flag_L, rA_addr, 3657 (Int)extend_s_16to32(uimm16)); 3658 b = mkSzExtendS16( ty, uimm16 ); 3659 if (flag_L == 1) { 3660 putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64S, a, b))); 3661 } else { 3662 a = mkNarrowTo32( ty, a ); 3663 b = mkNarrowTo32( ty, b ); 3664 putCR321(crfD, unop(Iop_32to8, binop(Iop_CmpORD32S, a, b))); 3665 } 3666 putCR0( crfD, getXER_SO() ); 3667 break; 3668 3669 case 0x0A: // cmpli (Compare Logical Immediate, PPC32 p370) 3670 DIP("cmpli cr%u,%u,r%u,0x%x\n", crfD, flag_L, rA_addr, uimm16); 3671 b = mkSzImm( ty, uimm16 ); 3672 if (flag_L == 1) { 3673 putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64U, a, b))); 3674 } else { 3675 a = mkNarrowTo32( ty, a ); 3676 b = mkNarrowTo32( ty, b ); 3677 putCR321(crfD, unop(Iop_32to8, binop(Iop_CmpORD32U, a, b))); 3678 } 3679 putCR0( crfD, getXER_SO() ); 3680 break; 3681 3682 /* X Form */ 3683 case 0x1F: 3684 if (b0 != 0) { 3685 vex_printf("dis_int_cmp(ppc)(0x1F,b0)\n"); 3686 return False; 3687 } 3688 b = getIReg(rB_addr); 3689 3690 switch (opc2) { 3691 case 0x000: // cmp (Compare, PPC32 p367) 3692 DIP("cmp cr%u,%u,r%u,r%u\n", crfD, flag_L, rA_addr, rB_addr); 3693 /* Comparing a reg with itself produces a result which 3694 doesn't depend on the contents of the reg. Therefore 3695 remove the false dependency, which has been known to cause 3696 memcheck to produce false errors. */ 3697 if (rA_addr == rB_addr) 3698 a = b = typeOfIRExpr(irsb->tyenv,a) == Ity_I64 3699 ? mkU64(0) : mkU32(0); 3700 if (flag_L == 1) { 3701 putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64S, a, b))); 3702 } else { 3703 a = mkNarrowTo32( ty, a ); 3704 b = mkNarrowTo32( ty, b ); 3705 putCR321(crfD, unop(Iop_32to8,binop(Iop_CmpORD32S, a, b))); 3706 } 3707 putCR0( crfD, getXER_SO() ); 3708 break; 3709 3710 case 0x020: // cmpl (Compare Logical, PPC32 p369) 3711 DIP("cmpl cr%u,%u,r%u,r%u\n", crfD, flag_L, rA_addr, rB_addr); 3712 /* Comparing a reg with itself produces a result which 3713 doesn't depend on the contents of the reg. Therefore 3714 remove the false dependency, which has been known to cause 3715 memcheck to produce false errors. */ 3716 if (rA_addr == rB_addr) 3717 a = b = typeOfIRExpr(irsb->tyenv,a) == Ity_I64 3718 ? mkU64(0) : mkU32(0); 3719 if (flag_L == 1) { 3720 putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64U, a, b))); 3721 } else { 3722 a = mkNarrowTo32( ty, a ); 3723 b = mkNarrowTo32( ty, b ); 3724 putCR321(crfD, unop(Iop_32to8, binop(Iop_CmpORD32U, a, b))); 3725 } 3726 putCR0( crfD, getXER_SO() ); 3727 break; 3728 3729 default: 3730 vex_printf("dis_int_cmp(ppc)(opc2)\n"); 3731 return False; 3732 } 3733 break; 3734 3735 default: 3736 vex_printf("dis_int_cmp(ppc)(opc1)\n"); 3737 return False; 3738 } 3739 3740 return True; 3741 } 3742 3743 3744 /* 3745 Integer Logical Instructions 3746 */ 3747 static Bool dis_int_logic ( UInt theInstr ) 3748 { 3749 /* D-Form, X-Form */ 3750 UChar opc1 = ifieldOPC(theInstr); 3751 UChar rS_addr = ifieldRegDS(theInstr); 3752 UChar rA_addr = ifieldRegA(theInstr); 3753 UInt uimm16 = ifieldUIMM16(theInstr); 3754 UChar rB_addr = ifieldRegB(theInstr); 3755 UInt opc2 = ifieldOPClo10(theInstr); 3756 UChar flag_rC = ifieldBIT0(theInstr); 3757 3758 IRType ty = mode64 ? Ity_I64 : Ity_I32; 3759 IRTemp rS = newTemp(ty); 3760 IRTemp rA = newTemp(ty); 3761 IRTemp rB = newTemp(ty); 3762 IRExpr* irx; 3763 Bool do_rc = False; 3764 3765 assign( rS, getIReg(rS_addr) ); 3766 assign( rB, getIReg(rB_addr) ); 3767 3768 switch (opc1) { 3769 case 0x1C: // andi. (AND Immediate, PPC32 p358) 3770 DIP("andi. r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3771 assign( rA, binop( mkSzOp(ty, Iop_And8), mkexpr(rS), 3772 mkSzImm(ty, uimm16)) ); 3773 do_rc = True; // Always record to CR 3774 flag_rC = 1; 3775 break; 3776 3777 case 0x1D: // andis. (AND Immediate Shifted, PPC32 p359) 3778 DIP("andis r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3779 assign( rA, binop( mkSzOp(ty, Iop_And8), mkexpr(rS), 3780 mkSzImm(ty, uimm16 << 16)) ); 3781 do_rc = True; // Always record to CR 3782 flag_rC = 1; 3783 break; 3784 3785 case 0x18: // ori (OR Immediate, PPC32 p497) 3786 DIP("ori r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3787 assign( rA, binop( mkSzOp(ty, Iop_Or8), mkexpr(rS), 3788 mkSzImm(ty, uimm16)) ); 3789 break; 3790 3791 case 0x19: // oris (OR Immediate Shifted, PPC32 p498) 3792 DIP("oris r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3793 assign( rA, binop( mkSzOp(ty, Iop_Or8), mkexpr(rS), 3794 mkSzImm(ty, uimm16 << 16)) ); 3795 break; 3796 3797 case 0x1A: // xori (XOR Immediate, PPC32 p550) 3798 DIP("xori r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3799 assign( rA, binop( mkSzOp(ty, Iop_Xor8), mkexpr(rS), 3800 mkSzImm(ty, uimm16)) ); 3801 break; 3802 3803 case 0x1B: // xoris (XOR Immediate Shifted, PPC32 p551) 3804 DIP("xoris r%u,r%u,0x%x\n", rA_addr, rS_addr, uimm16); 3805 assign( rA, binop( mkSzOp(ty, Iop_Xor8), mkexpr(rS), 3806 mkSzImm(ty, uimm16 << 16)) ); 3807 break; 3808 3809 /* X Form */ 3810 case 0x1F: 3811 do_rc = True; // All below record to CR, except for where we return at case end. 3812 3813 switch (opc2) { 3814 case 0x01C: // and (AND, PPC32 p356) 3815 DIP("and%s r%u,r%u,r%u\n", 3816 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3817 assign(rA, binop( mkSzOp(ty, Iop_And8), 3818 mkexpr(rS), mkexpr(rB))); 3819 break; 3820 3821 case 0x03C: // andc (AND with Complement, PPC32 p357) 3822 DIP("andc%s r%u,r%u,r%u\n", 3823 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3824 assign(rA, binop( mkSzOp(ty, Iop_And8), mkexpr(rS), 3825 unop( mkSzOp(ty, Iop_Not8), 3826 mkexpr(rB)))); 3827 break; 3828 3829 case 0x01A: { // cntlzw (Count Leading Zeros Word, PPC32 p371) 3830 IRExpr* lo32; 3831 if (rB_addr!=0) { 3832 vex_printf("dis_int_logic(ppc)(cntlzw,rB_addr)\n"); 3833 return False; 3834 } 3835 DIP("cntlzw%s r%u,r%u\n", 3836 flag_rC ? ".":"", rA_addr, rS_addr); 3837 3838 // mode64: count in low word only 3839 lo32 = mode64 ? unop(Iop_64to32, mkexpr(rS)) : mkexpr(rS); 3840 3841 // Iop_Clz32 undefined for arg==0, so deal with that case: 3842 irx = binop(Iop_CmpNE32, lo32, mkU32(0)); 3843 assign(rA, mkWidenFrom32(ty, 3844 IRExpr_Mux0X( unop(Iop_1Uto8, irx), 3845 mkU32(32), 3846 unop(Iop_Clz32, lo32)), 3847 False)); 3848 3849 // TODO: alternatively: assign(rA, verbose_Clz32(rS)); 3850 break; 3851 } 3852 3853 case 0x11C: // eqv (Equivalent, PPC32 p396) 3854 DIP("eqv%s r%u,r%u,r%u\n", 3855 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3856 assign( rA, unop( mkSzOp(ty, Iop_Not8), 3857 binop( mkSzOp(ty, Iop_Xor8), 3858 mkexpr(rS), mkexpr(rB))) ); 3859 break; 3860 3861 case 0x3BA: // extsb (Extend Sign Byte, PPC32 p397 3862 if (rB_addr!=0) { 3863 vex_printf("dis_int_logic(ppc)(extsb,rB_addr)\n"); 3864 return False; 3865 } 3866 DIP("extsb%s r%u,r%u\n", 3867 flag_rC ? ".":"", rA_addr, rS_addr); 3868 if (mode64) 3869 assign( rA, unop(Iop_8Sto64, unop(Iop_64to8, mkexpr(rS))) ); 3870 else 3871 assign( rA, unop(Iop_8Sto32, unop(Iop_32to8, mkexpr(rS))) ); 3872 break; 3873 3874 case 0x39A: // extsh (Extend Sign Half Word, PPC32 p398) 3875 if (rB_addr!=0) { 3876 vex_printf("dis_int_logic(ppc)(extsh,rB_addr)\n"); 3877 return False; 3878 } 3879 DIP("extsh%s r%u,r%u\n", 3880 flag_rC ? ".":"", rA_addr, rS_addr); 3881 if (mode64) 3882 assign( rA, unop(Iop_16Sto64, 3883 unop(Iop_64to16, mkexpr(rS))) ); 3884 else 3885 assign( rA, unop(Iop_16Sto32, 3886 unop(Iop_32to16, mkexpr(rS))) ); 3887 break; 3888 3889 case 0x1DC: // nand (NAND, PPC32 p492) 3890 DIP("nand%s r%u,r%u,r%u\n", 3891 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3892 assign( rA, unop( mkSzOp(ty, Iop_Not8), 3893 binop( mkSzOp(ty, Iop_And8), 3894 mkexpr(rS), mkexpr(rB))) ); 3895 break; 3896 3897 case 0x07C: // nor (NOR, PPC32 p494) 3898 DIP("nor%s r%u,r%u,r%u\n", 3899 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3900 assign( rA, unop( mkSzOp(ty, Iop_Not8), 3901 binop( mkSzOp(ty, Iop_Or8), 3902 mkexpr(rS), mkexpr(rB))) ); 3903 break; 3904 3905 case 0x1BC: // or (OR, PPC32 p495) 3906 if ((!flag_rC) && rS_addr == rB_addr) { 3907 DIP("mr r%u,r%u\n", rA_addr, rS_addr); 3908 assign( rA, mkexpr(rS) ); 3909 } else { 3910 DIP("or%s r%u,r%u,r%u\n", 3911 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3912 assign( rA, binop( mkSzOp(ty, Iop_Or8), 3913 mkexpr(rS), mkexpr(rB)) ); 3914 } 3915 break; 3916 3917 case 0x19C: // orc (OR with Complement, PPC32 p496) 3918 DIP("orc%s r%u,r%u,r%u\n", 3919 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3920 assign( rA, binop( mkSzOp(ty, Iop_Or8), mkexpr(rS), 3921 unop(mkSzOp(ty, Iop_Not8), mkexpr(rB)))); 3922 break; 3923 3924 case 0x13C: // xor (XOR, PPC32 p549) 3925 DIP("xor%s r%u,r%u,r%u\n", 3926 flag_rC ? ".":"", rA_addr, rS_addr, rB_addr); 3927 assign( rA, binop( mkSzOp(ty, Iop_Xor8), 3928 mkexpr(rS), mkexpr(rB)) ); 3929 break; 3930 3931 3932 /* 64bit Integer Logical Instructions */ 3933 case 0x3DA: // extsw (Extend Sign Word, PPC64 p430) 3934 if (rB_addr!=0) { 3935 vex_printf("dis_int_logic(ppc)(extsw,rB_addr)\n"); 3936 return False; 3937 } 3938 DIP("extsw%s r%u,r%u\n", flag_rC ? ".":"", rA_addr, rS_addr); 3939 assign(rA, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(rS)))); 3940 break; 3941 3942 case 0x03A: // cntlzd (Count Leading Zeros DWord, PPC64 p401) 3943 if (rB_addr!=0) { 3944 vex_printf("dis_int_logic(ppc)(cntlzd,rB_addr)\n"); 3945 return False; 3946 } 3947 DIP("cntlzd%s r%u,r%u\n", 3948 flag_rC ? ".":"", rA_addr, rS_addr); 3949 // Iop_Clz64 undefined for arg==0, so deal with that case: 3950 irx = binop(Iop_CmpNE64, mkexpr(rS), mkU64(0)); 3951 assign(rA, IRExpr_Mux0X( unop(Iop_1Uto8, irx), 3952 mkU64(64), 3953 unop(Iop_Clz64, mkexpr(rS)) )); 3954 // TODO: alternatively: assign(rA, verbose_Clz64(rS)); 3955 break; 3956 3957 case 0x1FC: // cmpb (Power6: compare bytes) 3958 DIP("cmpb r%u,r%u,r%u\n", rA_addr, rS_addr, rB_addr); 3959 3960 if (mode64) 3961 assign( rA, unop( Iop_V128to64, 3962 binop( Iop_CmpEQ8x16, 3963 binop( Iop_64HLtoV128, mkU64(0), mkexpr(rS) ), 3964 binop( Iop_64HLtoV128, mkU64(0), mkexpr(rB) ) 3965 )) ); 3966 else 3967 assign( rA, unop( Iop_V128to32, 3968 binop( Iop_CmpEQ8x16, 3969 unop( Iop_32UtoV128, mkexpr(rS) ), 3970 unop( Iop_32UtoV128, mkexpr(rB) ) 3971 )) ); 3972 break; 3973 3974 case 0x2DF: { // mftgpr (move floating-point to general