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