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