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