Home | History | Annotate | Download | only in priv
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- begin                                      guest_mips_toIR.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2010-2015 RT-RK
     11       mips-valgrind (at) rt-rk.com
     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., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 /* Translates MIPS code to IR. */
     32 
     33 #include "libvex_basictypes.h"
     34 #include "libvex_ir.h"
     35 #include "libvex.h"
     36 #include "libvex_guest_mips32.h"
     37 #include "libvex_guest_mips64.h"
     38 
     39 #include "main_util.h"
     40 #include "main_globals.h"
     41 #include "guest_generic_bb_to_IR.h"
     42 #include "guest_mips_defs.h"
     43 
     44 /*------------------------------------------------------------*/
     45 /*---                      Globals                         ---*/
     46 /*------------------------------------------------------------*/
     47 
     48 /* These are set at the start of the translation of a instruction, so
     49    that we don't have to pass them around endlessly. CONST means does
     50    not change during translation of the instruction. */
     51 
     52 /* CONST: what is the host's endianness?  This has to do with float vs
     53    double register accesses on VFP, but it's complex and not properly
     54    thought out. */
     55 static VexEndness host_endness;
     56 
     57 /* Pointer to the guest code area. */
     58 static const UChar *guest_code;
     59 
     60 /* CONST: The guest address for the instruction currently being
     61    translated. */
     62 #if defined(VGP_mips32_linux)
     63 static Addr32 guest_PC_curr_instr;
     64 #else
     65 static Addr64 guest_PC_curr_instr;
     66 #endif
     67 
     68 /* MOD: The IRSB* into which we're generating code. */
     69 static IRSB *irsb;
     70 
     71 /* Is our guest binary 32 or 64bit? Set at each call to
     72    disInstr_MIPS below. */
     73 static Bool mode64 = False;
     74 
     75 /* CPU has FPU and 32 dbl. prec. FP registers. */
     76 static Bool fp_mode64 = False;
     77 
     78 /* Define 1.0 in single and double precision. */
     79 #define ONE_SINGLE 0x3F800000
     80 #define ONE_DOUBLE 0x3FF0000000000000ULL
     81 
     82 /*------------------------------------------------------------*/
     83 /*---                  Debugging output                    ---*/
     84 /*------------------------------------------------------------*/
     85 
     86 #define DIP(format, args...)           \
     87    if (vex_traceflags & VEX_TRACE_FE)  \
     88       vex_printf(format, ## args)
     89 
     90 /*------------------------------------------------------------*/
     91 /*--- Helper bits and pieces for deconstructing the        ---*/
     92 /*--- mips insn stream.                                    ---*/
     93 /*------------------------------------------------------------*/
     94 
     95 /* ---------------- Integer registers ---------------- */
     96 
     97 static UInt integerGuestRegOffset(UInt iregNo)
     98 {
     99    /* Do we care about endianness here?  We do if sub-parts of integer
    100       registers are accessed, but I don't think that ever happens on
    101       MIPS. */
    102    UInt ret;
    103    if (!mode64)
    104       switch (iregNo) {
    105          case 0:
    106             ret = offsetof(VexGuestMIPS32State, guest_r0); break;
    107          case 1:
    108             ret = offsetof(VexGuestMIPS32State, guest_r1); break;
    109          case 2:
    110             ret = offsetof(VexGuestMIPS32State, guest_r2); break;
    111          case 3:
    112             ret = offsetof(VexGuestMIPS32State, guest_r3); break;
    113          case 4:
    114             ret = offsetof(VexGuestMIPS32State, guest_r4); break;
    115          case 5:
    116             ret = offsetof(VexGuestMIPS32State, guest_r5); break;
    117          case 6:
    118             ret = offsetof(VexGuestMIPS32State, guest_r6); break;
    119          case 7:
    120             ret = offsetof(VexGuestMIPS32State, guest_r7); break;
    121          case 8:
    122             ret = offsetof(VexGuestMIPS32State, guest_r8); break;
    123          case 9:
    124             ret = offsetof(VexGuestMIPS32State, guest_r9); break;
    125          case 10:
    126             ret = offsetof(VexGuestMIPS32State, guest_r10); break;
    127          case 11:
    128             ret = offsetof(VexGuestMIPS32State, guest_r11); break;
    129          case 12:
    130             ret = offsetof(VexGuestMIPS32State, guest_r12); break;
    131          case 13:
    132             ret = offsetof(VexGuestMIPS32State, guest_r13); break;
    133          case 14:
    134             ret = offsetof(VexGuestMIPS32State, guest_r14); break;
    135          case 15:
    136             ret = offsetof(VexGuestMIPS32State, guest_r15); break;
    137          case 16:
    138             ret = offsetof(VexGuestMIPS32State, guest_r16); break;
    139          case 17:
    140             ret = offsetof(VexGuestMIPS32State, guest_r17); break;
    141          case 18:
    142             ret = offsetof(VexGuestMIPS32State, guest_r18); break;
    143          case 19:
    144             ret = offsetof(VexGuestMIPS32State, guest_r19); break;
    145          case 20:
    146             ret = offsetof(VexGuestMIPS32State, guest_r20); break;
    147          case 21:
    148             ret = offsetof(VexGuestMIPS32State, guest_r21); break;
    149          case 22:
    150             ret = offsetof(VexGuestMIPS32State, guest_r22); break;
    151          case 23:
    152             ret = offsetof(VexGuestMIPS32State, guest_r23); break;
    153          case 24:
    154             ret = offsetof(VexGuestMIPS32State, guest_r24); break;
    155          case 25:
    156             ret = offsetof(VexGuestMIPS32State, guest_r25); break;
    157          case 26:
    158             ret = offsetof(VexGuestMIPS32State, guest_r26); break;
    159          case 27:
    160             ret = offsetof(VexGuestMIPS32State, guest_r27); break;
    161          case 28:
    162             ret = offsetof(VexGuestMIPS32State, guest_r28); break;
    163          case 29:
    164             ret = offsetof(VexGuestMIPS32State, guest_r29); break;
    165          case 30:
    166             ret = offsetof(VexGuestMIPS32State, guest_r30); break;
    167          case 31:
    168             ret = offsetof(VexGuestMIPS32State, guest_r31); break;
    169          default:
    170             vassert(0);
    171             break;
    172       }
    173    else
    174       switch (iregNo) {
    175          case 0:
    176             ret = offsetof(VexGuestMIPS64State, guest_r0); break;
    177          case 1:
    178             ret = offsetof(VexGuestMIPS64State, guest_r1); break;
    179          case 2:
    180             ret = offsetof(VexGuestMIPS64State, guest_r2); break;
    181          case 3:
    182             ret = offsetof(VexGuestMIPS64State, guest_r3); break;
    183          case 4:
    184             ret = offsetof(VexGuestMIPS64State, guest_r4); break;
    185          case 5:
    186             ret = offsetof(VexGuestMIPS64State, guest_r5); break;
    187          case 6:
    188             ret = offsetof(VexGuestMIPS64State, guest_r6); break;
    189          case 7:
    190             ret = offsetof(VexGuestMIPS64State, guest_r7); break;
    191          case 8:
    192             ret = offsetof(VexGuestMIPS64State, guest_r8); break;
    193          case 9:
    194             ret = offsetof(VexGuestMIPS64State, guest_r9); break;
    195          case 10:
    196             ret = offsetof(VexGuestMIPS64State, guest_r10); break;
    197          case 11:
    198             ret = offsetof(VexGuestMIPS64State, guest_r11); break;
    199          case 12:
    200             ret = offsetof(VexGuestMIPS64State, guest_r12); break;
    201          case 13:
    202             ret = offsetof(VexGuestMIPS64State, guest_r13); break;
    203          case 14:
    204             ret = offsetof(VexGuestMIPS64State, guest_r14); break;
    205          case 15:
    206             ret = offsetof(VexGuestMIPS64State, guest_r15); break;
    207          case 16:
    208             ret = offsetof(VexGuestMIPS64State, guest_r16); break;
    209          case 17:
    210             ret = offsetof(VexGuestMIPS64State, guest_r17); break;
    211          case 18:
    212             ret = offsetof(VexGuestMIPS64State, guest_r18); break;
    213          case 19:
    214             ret = offsetof(VexGuestMIPS64State, guest_r19); break;
    215          case 20:
    216             ret = offsetof(VexGuestMIPS64State, guest_r20); break;
    217          case 21:
    218             ret = offsetof(VexGuestMIPS64State, guest_r21); break;
    219          case 22:
    220             ret = offsetof(VexGuestMIPS64State, guest_r22); break;
    221          case 23:
    222             ret = offsetof(VexGuestMIPS64State, guest_r23); break;
    223          case 24:
    224             ret = offsetof(VexGuestMIPS64State, guest_r24); break;
    225          case 25:
    226             ret = offsetof(VexGuestMIPS64State, guest_r25); break;
    227          case 26:
    228             ret = offsetof(VexGuestMIPS64State, guest_r26); break;
    229          case 27:
    230             ret = offsetof(VexGuestMIPS64State, guest_r27); break;
    231          case 28:
    232             ret = offsetof(VexGuestMIPS64State, guest_r28); break;
    233          case 29:
    234             ret = offsetof(VexGuestMIPS64State, guest_r29); break;
    235          case 30:
    236             ret = offsetof(VexGuestMIPS64State, guest_r30); break;
    237          case 31:
    238             ret = offsetof(VexGuestMIPS64State, guest_r31); break;
    239          default:
    240             vassert(0);
    241             break;
    242       }
    243    return ret;
    244 }
    245 
    246 #if defined(VGP_mips32_linux)
    247 #define OFFB_PC     offsetof(VexGuestMIPS32State, guest_PC)
    248 #else
    249 #define OFFB_PC     offsetof(VexGuestMIPS64State, guest_PC)
    250 #endif
    251 
    252 /* ---------------- Floating point registers ---------------- */
    253 
    254 static UInt floatGuestRegOffset(UInt fregNo)
    255 {
    256    vassert(fregNo < 32);
    257    UInt ret;
    258    if (!mode64)
    259       switch (fregNo) {
    260          case 0:
    261             ret = offsetof(VexGuestMIPS32State, guest_f0); break;
    262          case 1:
    263             ret = offsetof(VexGuestMIPS32State, guest_f1); break;
    264          case 2:
    265             ret = offsetof(VexGuestMIPS32State, guest_f2); break;
    266          case 3:
    267             ret = offsetof(VexGuestMIPS32State, guest_f3); break;
    268          case 4:
    269             ret = offsetof(VexGuestMIPS32State, guest_f4); break;
    270          case 5:
    271             ret = offsetof(VexGuestMIPS32State, guest_f5); break;
    272          case 6:
    273             ret = offsetof(VexGuestMIPS32State, guest_f6); break;
    274          case 7:
    275             ret = offsetof(VexGuestMIPS32State, guest_f7); break;
    276          case 8:
    277             ret = offsetof(VexGuestMIPS32State, guest_f8); break;
    278          case 9:
    279             ret = offsetof(VexGuestMIPS32State, guest_f9); break;
    280          case 10:
    281             ret = offsetof(VexGuestMIPS32State, guest_f10); break;
    282          case 11:
    283             ret = offsetof(VexGuestMIPS32State, guest_f11); break;
    284          case 12:
    285             ret = offsetof(VexGuestMIPS32State, guest_f12); break;
    286          case 13:
    287             ret = offsetof(VexGuestMIPS32State, guest_f13); break;
    288          case 14:
    289             ret = offsetof(VexGuestMIPS32State, guest_f14); break;
    290          case 15:
    291             ret = offsetof(VexGuestMIPS32State, guest_f15); break;
    292          case 16:
    293             ret = offsetof(VexGuestMIPS32State, guest_f16); break;
    294          case 17:
    295             ret = offsetof(VexGuestMIPS32State, guest_f17); break;
    296          case 18:
    297             ret = offsetof(VexGuestMIPS32State, guest_f18); break;
    298          case 19:
    299             ret = offsetof(VexGuestMIPS32State, guest_f19); break;
    300          case 20:
    301             ret = offsetof(VexGuestMIPS32State, guest_f20); break;
    302          case 21:
    303             ret = offsetof(VexGuestMIPS32State, guest_f21); break;
    304          case 22:
    305             ret = offsetof(VexGuestMIPS32State, guest_f22); break;
    306          case 23:
    307             ret = offsetof(VexGuestMIPS32State, guest_f23); break;
    308          case 24:
    309             ret = offsetof(VexGuestMIPS32State, guest_f24); break;
    310          case 25:
    311             ret = offsetof(VexGuestMIPS32State, guest_f25); break;
    312          case 26:
    313             ret = offsetof(VexGuestMIPS32State, guest_f26); break;
    314          case 27:
    315             ret = offsetof(VexGuestMIPS32State, guest_f27); break;
    316          case 28:
    317             ret = offsetof(VexGuestMIPS32State, guest_f28); break;
    318          case 29:
    319             ret = offsetof(VexGuestMIPS32State, guest_f29); break;
    320          case 30:
    321             ret = offsetof(VexGuestMIPS32State, guest_f30); break;
    322          case 31:
    323             ret = offsetof(VexGuestMIPS32State, guest_f31); break;
    324          default:
    325             vassert(0);
    326             break;
    327       }
    328    else
    329       switch (fregNo) {
    330          case 0:
    331             ret = offsetof(VexGuestMIPS64State, guest_f0); break;
    332          case 1:
    333             ret = offsetof(VexGuestMIPS64State, guest_f1); break;
    334          case 2:
    335             ret = offsetof(VexGuestMIPS64State, guest_f2); break;
    336          case 3:
    337             ret = offsetof(VexGuestMIPS64State, guest_f3); break;
    338          case 4:
    339             ret = offsetof(VexGuestMIPS64State, guest_f4); break;
    340          case 5:
    341             ret = offsetof(VexGuestMIPS64State, guest_f5); break;
    342          case 6:
    343             ret = offsetof(VexGuestMIPS64State, guest_f6); break;
    344          case 7:
    345             ret = offsetof(VexGuestMIPS64State, guest_f7); break;
    346          case 8:
    347             ret = offsetof(VexGuestMIPS64State, guest_f8); break;
    348          case 9:
    349             ret = offsetof(VexGuestMIPS64State, guest_f9); break;
    350          case 10:
    351             ret = offsetof(VexGuestMIPS64State, guest_f10); break;
    352          case 11:
    353             ret = offsetof(VexGuestMIPS64State, guest_f11); break;
    354          case 12:
    355             ret = offsetof(VexGuestMIPS64State, guest_f12); break;
    356          case 13:
    357             ret = offsetof(VexGuestMIPS64State, guest_f13); break;
    358          case 14:
    359             ret = offsetof(VexGuestMIPS64State, guest_f14); break;
    360          case 15:
    361             ret = offsetof(VexGuestMIPS64State, guest_f15); break;
    362          case 16:
    363             ret = offsetof(VexGuestMIPS64State, guest_f16); break;
    364          case 17:
    365             ret = offsetof(VexGuestMIPS64State, guest_f17); break;
    366          case 18:
    367             ret = offsetof(VexGuestMIPS64State, guest_f18); break;
    368          case 19:
    369             ret = offsetof(VexGuestMIPS64State, guest_f19); break;
    370          case 20:
    371             ret = offsetof(VexGuestMIPS64State, guest_f20); break;
    372          case 21:
    373             ret = offsetof(VexGuestMIPS64State, guest_f21); break;
    374          case 22:
    375             ret = offsetof(VexGuestMIPS64State, guest_f22); break;
    376          case 23:
    377             ret = offsetof(VexGuestMIPS64State, guest_f23); break;
    378          case 24:
    379             ret = offsetof(VexGuestMIPS64State, guest_f24); break;
    380          case 25:
    381             ret = offsetof(VexGuestMIPS64State, guest_f25); break;
    382          case 26:
    383             ret = offsetof(VexGuestMIPS64State, guest_f26); break;
    384          case 27:
    385             ret = offsetof(VexGuestMIPS64State, guest_f27); break;
    386          case 28:
    387             ret = offsetof(VexGuestMIPS64State, guest_f28); break;
    388          case 29:
    389             ret = offsetof(VexGuestMIPS64State, guest_f29); break;
    390          case 30:
    391             ret = offsetof(VexGuestMIPS64State, guest_f30); break;
    392          case 31:
    393             ret = offsetof(VexGuestMIPS64State, guest_f31); break;
    394          default:
    395             vassert(0);
    396             break;
    397       }
    398    return ret;
    399 }
    400 
    401 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
    402 
    403 static UInt accumulatorGuestRegOffset(UInt acNo)
    404 {
    405    vassert(!mode64);
    406    vassert(acNo <= 3);
    407    UInt ret;
    408    switch (acNo) {
    409       case 0:
    410          ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
    411       case 1:
    412          ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
    413       case 2:
    414          ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
    415       case 3:
    416          ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
    417       default:
    418          vassert(0);
    419     break;
    420    }
    421    return ret;
    422 }
    423 
    424 /* Do a endian load of a 32-bit word, regardless of the endianness of the
    425    underlying host. */
    426 static inline UInt getUInt(const UChar * p)
    427 {
    428    UInt w = 0;
    429 #if defined (_MIPSEL)
    430    w = (w << 8) | p[3];
    431    w = (w << 8) | p[2];
    432    w = (w << 8) | p[1];
    433    w = (w << 8) | p[0];
    434 #elif defined (_MIPSEB)
    435    w = (w << 8) | p[0];
    436    w = (w << 8) | p[1];
    437    w = (w << 8) | p[2];
    438    w = (w << 8) | p[3];
    439 #endif
    440    return w;
    441 }
    442 
    443 #define BITS2(_b1,_b0) \
    444    (((_b1) << 1) | (_b0))
    445 
    446 #define BITS3(_b2,_b1,_b0)                      \
    447   (((_b2) << 2) | ((_b1) << 1) | (_b0))
    448 
    449 #define BITS4(_b3,_b2,_b1,_b0) \
    450    (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
    451 
    452 #define BITS5(_b4,_b3,_b2,_b1,_b0)  \
    453    (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
    454 
    455 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0)  \
    456    ((BITS2((_b5),(_b4)) << 4) \
    457     | BITS4((_b3),(_b2),(_b1),(_b0)))
    458 
    459 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0)  \
    460    ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
    461     | BITS4((_b3),(_b2),(_b1),(_b0)))
    462 
    463 #define LOAD_STORE_PATTERN \
    464    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    465       if(!mode64) \
    466          assign(t1, binop(Iop_Add32, getIReg(rs), \
    467                                      mkU32(extend_s_16to32(imm)))); \
    468       else \
    469          assign(t1, binop(Iop_Add64, getIReg(rs), \
    470                                      mkU64(extend_s_16to64(imm)))); \
    471 
    472 #define LOADX_STORE_PATTERN \
    473    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    474       if(!mode64) \
    475          assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
    476       else \
    477          assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
    478 
    479 #define LWX_SWX_PATTERN64 \
    480    t2 = newTemp(Ity_I64); \
    481    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \
    482    t4 = newTemp(Ity_I32); \
    483    assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
    484                                       mkexpr(t1), mkU64(0x3))));
    485 
    486 #define LWX_SWX_PATTERN64_1 \
    487    t2 = newTemp(Ity_I64); \
    488    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
    489    t4 = newTemp(Ity_I64); \
    490    assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
    491 
    492 #define LWX_SWX_PATTERN \
    493    t2 = newTemp(Ity_I32); \
    494    assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
    495    t4 = newTemp(Ity_I32); \
    496    assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
    497 
    498 #define SXXV_PATTERN(op) \
    499    putIReg(rd, binop(op, \
    500          getIReg(rt), \
    501             unop(Iop_32to8, \
    502                binop(Iop_And32, \
    503                   getIReg(rs), \
    504                   mkU32(0x0000001F) \
    505                ) \
    506             ) \
    507          ) \
    508       )
    509 
    510 #define SXXV_PATTERN64(op) \
    511    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    512            mkNarrowTo32(ty, getIReg(rt)), \
    513              unop(Iop_32to8, \
    514                 binop(Iop_And32, \
    515                    mkNarrowTo32(ty, getIReg(rs)), \
    516                    mkU32(0x0000001F) \
    517                 ) \
    518              ) \
    519           ), True \
    520        ))
    521 
    522 #define SXX_PATTERN(op) \
    523    putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
    524 
    525 #define ALU_PATTERN(op) \
    526    putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
    527 
    528 #define ALUI_PATTERN(op) \
    529    putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
    530 
    531 #define ALUI_PATTERN64(op) \
    532    putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
    533 
    534 #define ALU_PATTERN64(op) \
    535    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    536                              mkNarrowTo32(ty, getIReg(rs)), \
    537                              mkNarrowTo32(ty, getIReg(rt))), True));
    538 
    539 #define FP_CONDITIONAL_CODE \
    540    t3 = newTemp(Ity_I32);   \
    541    assign(t3, binop(Iop_And32, \
    542                  IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \
    543                              binop(Iop_Shr32, getFCSR(), mkU8(23)), \
    544                              binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \
    545                  mkU32(0x1)));
    546 
    547 #define ILLEGAL_INSTRUCTON \
    548    putPC(mkU32(guest_PC_curr_instr + 4)); \
    549    dres.jk_StopHere = Ijk_SigILL; \
    550    dres.whatNext    = Dis_StopHere;
    551 
    552 /*------------------------------------------------------------*/
    553 /*---                  Field helpers                       ---*/
    554 /*------------------------------------------------------------*/
    555 
    556 static UInt get_opcode(UInt mipsins)
    557 {
    558    return (0xFC000000 & mipsins) >> 26;
    559 }
    560 
    561 static UInt get_rs(UInt mipsins)
    562 {
    563    return (0x03E00000 & mipsins) >> 21;
    564 }
    565 
    566 static UInt get_rt(UInt mipsins)
    567 {
    568    return (0x001F0000 & mipsins) >> 16;
    569 }
    570 
    571 static UInt get_imm(UInt mipsins)
    572 {
    573    return (0x0000FFFF & mipsins);
    574 }
    575 
    576 static UInt get_instr_index(UInt mipsins)
    577 {
    578    return (0x03FFFFFF & mipsins);
    579 }
    580 
    581 static UInt get_rd(UInt mipsins)
    582 {
    583    return (0x0000F800 & mipsins) >> 11;
    584 }
    585 
    586 static UInt get_sa(UInt mipsins)
    587 {
    588    return (0x000007C0 & mipsins) >> 6;
    589 }
    590 
    591 static UInt get_function(UInt mipsins)
    592 {
    593    return (0x0000003F & mipsins);
    594 }
    595 
    596 static UInt get_ft(UInt mipsins)
    597 {
    598    return (0x001F0000 & mipsins) >> 16;
    599 }
    600 
    601 static UInt get_fs(UInt mipsins)
    602 {
    603    return (0x0000F800 & mipsins) >> 11;
    604 }
    605 
    606 static UInt get_fd(UInt mipsins)
    607 {
    608    return (0x000007C0 & mipsins) >> 6;
    609 }
    610 
    611 static UInt get_mov_cc(UInt mipsins)
    612 {
    613    return (0x001C0000 & mipsins) >> 18;
    614 }
    615 
    616 static UInt get_bc1_cc(UInt mipsins)
    617 {
    618    return (0x001C0000 & mipsins) >> 18;
    619 }
    620 
    621 static UInt get_fpc_cc(UInt mipsins)
    622 {
    623    return (0x00000700 & mipsins) >> 8;
    624 }
    625 
    626 static UInt get_tf(UInt mipsins)
    627 {
    628    return (0x00010000 & mipsins) >> 16;
    629 }
    630 
    631 static UInt get_nd(UInt mipsins)
    632 {
    633    return (0x00020000 & mipsins) >> 17;
    634 }
    635 
    636 static UInt get_fmt(UInt mipsins)
    637 {
    638    return (0x03E00000 & mipsins) >> 21;
    639 }
    640 
    641 static UInt get_FC(UInt mipsins)
    642 {
    643    return (0x000000F0 & mipsins) >> 4;
    644 }
    645 
    646 static UInt get_cond(UInt mipsins)
    647 {
    648    return (0x0000000F & mipsins);
    649 }
    650 
    651 /* for break & syscall */
    652 static UInt get_code(UInt mipsins)
    653 {
    654    return (0xFFC0 & mipsins) >> 6;
    655 }
    656 
    657 static UInt get_lsb(UInt mipsins)
    658 {
    659    return (0x7C0 & mipsins) >> 6;
    660 }
    661 
    662 static UInt get_msb(UInt mipsins)
    663 {
    664    return (0x0000F800 & mipsins) >> 11;
    665 }
    666 
    667 static UInt get_rot(UInt mipsins)
    668 {
    669    return (0x00200000 & mipsins) >> 21;
    670 }
    671 
    672 static UInt get_rotv(UInt mipsins)
    673 {
    674    return (0x00000040 & mipsins) >> 6;
    675 }
    676 
    677 static UInt get_sel(UInt mipsins)
    678 {
    679    return (0x00000007 & mipsins);
    680 }
    681 
    682 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
    683    except for MFHI and MFLO. */
    684 static UInt get_acNo(UInt mipsins)
    685 {
    686    return (0x00001800 & mipsins) >> 11;
    687 }
    688 
    689 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
    690 static UInt get_acNo_mfhilo(UInt mipsins)
    691 {
    692    return (0x00600000 & mipsins) >> 21;
    693 }
    694 
    695 /* Get mask field (helper function for wrdsp instruction). */
    696 static UInt get_wrdspMask(UInt mipsins)
    697 {
    698    return (0x001ff800 & mipsins) >> 11;
    699 }
    700 
    701 /* Get mask field (helper function for rddsp instruction). */
    702 static UInt get_rddspMask(UInt mipsins)
    703 {
    704    return (0x03ff0000 & mipsins) >> 16;
    705 }
    706 
    707 /* Get shift field (helper function for DSP ASE instructions). */
    708 static UInt get_shift(UInt mipsins)
    709 {
    710    return (0x03f00000 & mipsins) >> 20;
    711 }
    712 
    713 /* Get immediate field for DSP ASE instructions. */
    714 static UInt get_dspImm(UInt mipsins)
    715 {
    716    return (0x03ff0000 & mipsins) >> 16;
    717 }
    718 
    719 static Bool branch_or_jump(const UChar * addr)
    720 {
    721    UInt fmt;
    722    UInt cins = getUInt(addr);
    723 
    724    UInt opcode = get_opcode(cins);
    725    UInt rt = get_rt(cins);
    726    UInt function = get_function(cins);
    727 
    728    /* bgtz, blez, bne, beq, jal */
    729    if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
    730        || opcode == 0x03 || opcode == 0x02) {
    731       return True;
    732    }
    733 
    734    /* bgez */
    735    if (opcode == 0x01 && rt == 0x01) {
    736       return True;
    737    }
    738 
    739    /* bgezal */
    740    if (opcode == 0x01 && rt == 0x11) {
    741       return True;
    742    }
    743 
    744    /* bltzal */
    745    if (opcode == 0x01 && rt == 0x10) {
    746       return True;
    747    }
    748 
    749    /* bltz */
    750    if (opcode == 0x01 && rt == 0x00) {
    751       return True;
    752    }
    753 
    754    /* jalr */
    755    if (opcode == 0x00 && function == 0x09) {
    756       return True;
    757    }
    758 
    759    /* jr */
    760    if (opcode == 0x00 && function == 0x08) {
    761       return True;
    762    }
    763 
    764    if (opcode == 0x11) {
    765       /*bc1f & bc1t */
    766       fmt = get_fmt(cins);
    767       if (fmt == 0x08) {
    768          return True;
    769       }
    770    }
    771 
    772    /* bposge32 */
    773    if (opcode == 0x01 && rt == 0x1c) {
    774       return True;
    775    }
    776 
    777    /* Cavium Specific instructions. */
    778    if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) {
    779        /* BBIT0, BBIT1, BBIT032, BBIT132 */
    780       return True;
    781    }
    782 
    783    return False;
    784 }
    785 
    786 static Bool is_Branch_or_Jump_and_Link(const UChar * addr)
    787 {
    788    UInt cins = getUInt(addr);
    789 
    790    UInt opcode = get_opcode(cins);
    791    UInt rt = get_rt(cins);
    792    UInt function = get_function(cins);
    793 
    794    /* jal */
    795    if (opcode == 0x02) {
    796       return True;
    797    }
    798 
    799    /* bgezal */
    800    if (opcode == 0x01 && rt == 0x11) {
    801       return True;
    802    }
    803 
    804    /* bltzal */
    805    if (opcode == 0x01 && rt == 0x10) {
    806       return True;
    807    }
    808 
    809    /* jalr */
    810    if (opcode == 0x00 && function == 0x09) {
    811       return True;
    812    }
    813 
    814    return False;
    815 }
    816 
    817 static Bool branch_or_link_likely(const UChar * addr)
    818 {
    819    UInt cins = getUInt(addr);
    820    UInt opcode = get_opcode(cins);
    821    UInt rt = get_rt(cins);
    822 
    823    /* bgtzl, blezl, bnel, beql */
    824    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
    825       return True;
    826 
    827    /* bgezl */
    828    if (opcode == 0x01 && rt == 0x03)
    829       return True;
    830 
    831    /* bgezall */
    832    if (opcode == 0x01 && rt == 0x13)
    833       return True;
    834 
    835    /* bltzall */
    836    if (opcode == 0x01 && rt == 0x12)
    837       return True;
    838 
    839    /* bltzl */
    840    if (opcode == 0x01 && rt == 0x02)
    841       return True;
    842 
    843    return False;
    844 }
    845 
    846 /*------------------------------------------------------------*/
    847 /*--- Helper bits and pieces for creating IR fragments.    ---*/
    848 /*------------------------------------------------------------*/
    849 
    850 static IRExpr *mkU8(UInt i)
    851 {
    852    vassert(i < 256);
    853    return IRExpr_Const(IRConst_U8((UChar) i));
    854 }
    855 
    856 /* Create an expression node for a 16-bit integer constant. */
    857 static IRExpr *mkU16(UInt i)
    858 {
    859    return IRExpr_Const(IRConst_U16(i));
    860 }
    861 
    862 /* Create an expression node for a 32-bit integer constant. */
    863 static IRExpr *mkU32(UInt i)
    864 {
    865    return IRExpr_Const(IRConst_U32(i));
    866 }
    867 
    868 /* Create an expression node for a 64-bit integer constant. */
    869 static IRExpr *mkU64(ULong i)
    870 {
    871    return IRExpr_Const(IRConst_U64(i));
    872 }
    873 
    874 static IRExpr *mkexpr(IRTemp tmp)
    875 {
    876    return IRExpr_RdTmp(tmp);
    877 }
    878 
    879 static IRExpr *unop(IROp op, IRExpr * a)
    880 {
    881    return IRExpr_Unop(op, a);
    882 }
    883 
    884 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
    885 {
    886    return IRExpr_Binop(op, a1, a2);
    887 }
    888 
    889 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
    890 {
    891    return IRExpr_Triop(op, a1, a2, a3);
    892 }
    893 
    894 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
    895                      IRExpr * a4 )
    896 {
    897    return IRExpr_Qop(op, a1, a2, a3, a4);
    898 }
    899 
    900 static IRExpr *load(IRType ty, IRExpr * addr)
    901 {
    902    IRExpr *load1 = NULL;
    903 #if defined (_MIPSEL)
    904    load1 = IRExpr_Load(Iend_LE, ty, addr);
    905 #elif defined (_MIPSEB)
    906    load1 = IRExpr_Load(Iend_BE, ty, addr);
    907 #endif
    908    return load1;
    909 }
    910 
    911 /* Add a statement to the list held by "irsb". */
    912 static void stmt(IRStmt * st)
    913 {
    914    addStmtToIRSB(irsb, st);
    915 }
    916 
    917 static void assign(IRTemp dst, IRExpr * e)
    918 {
    919    stmt(IRStmt_WrTmp(dst, e));
    920 }
    921 
    922 static void store(IRExpr * addr, IRExpr * data)
    923 {
    924 #if defined (_MIPSEL)
    925    stmt(IRStmt_Store(Iend_LE, addr, data));
    926 #elif defined (_MIPSEB)
    927    stmt(IRStmt_Store(Iend_BE, addr, data));
    928 #endif
    929 }
    930 
    931 /* Generate a new temporary of the given type. */
    932 static IRTemp newTemp(IRType ty)
    933 {
    934    vassert(isPlausibleIRType(ty));
    935    return newIRTemp(irsb->tyenv, ty);
    936 }
    937 
    938 /* Generate an expression for SRC rotated right by ROT. */
    939 static IRExpr *genROR32(IRExpr * src, Int rot)
    940 {
    941    vassert(rot >= 0 && rot < 32);
    942    if (rot == 0)
    943       return src;
    944    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
    945                           binop(Iop_Shr32, src, mkU8(rot)));
    946 }
    947 
    948 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
    949 {
    950    IRTemp t0 = newTemp(Ity_I8);
    951    IRTemp t1 = newTemp(Ity_I8);
    952 
    953    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
    954    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
    955    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
    956                           binop(Iop_Shr32, src, mkexpr(t0)));
    957 }
    958 
    959 static UShort extend_s_10to16(UInt x)
    960 {
    961    return (UShort) ((((Int) x) << 22) >> 22);
    962 }
    963 
    964 static ULong extend_s_10to32(UInt x)
    965 {
    966    return (ULong)((((Long) x) << 22) >> 22);
    967 }
    968 
    969 static ULong extend_s_10to64(UInt x)
    970 {
    971    return (ULong)((((Long) x) << 54) >> 54);
    972 }
    973 
    974 static UInt extend_s_16to32(UInt x)
    975 {
    976    return (UInt) ((((Int) x) << 16) >> 16);
    977 }
    978 
    979 static UInt extend_s_18to32(UInt x)
    980 {
    981    return (UInt) ((((Int) x) << 14) >> 14);
    982 }
    983 
    984 static ULong extend_s_16to64 ( UInt x )
    985 {
    986    return (ULong) ((((Long) x) << 48) >> 48);
    987 }
    988 
    989 static ULong extend_s_18to64 ( UInt x )
    990 {
    991    return (ULong) ((((Long) x) << 46) >> 46);
    992 }
    993 
    994 static ULong extend_s_32to64 ( UInt x )
    995 {
    996    return (ULong) ((((Long) x) << 32) >> 32);
    997 }
    998 
    999 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
   1000 {
   1001    vassert(dres->whatNext    == Dis_Continue);
   1002    vassert(dres->len         == 0);
   1003    vassert(dres->continueAt  == 0);
   1004    vassert(dres->jk_StopHere == Ijk_INVALID);
   1005    dres->whatNext    = Dis_StopHere;
   1006    dres->jk_StopHere = kind;
   1007    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
   1008 }
   1009 
   1010 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
   1011 {
   1012    vassert(dres->whatNext    == Dis_Continue);
   1013    vassert(dres->len         == 0);
   1014    vassert(dres->continueAt  == 0);
   1015    vassert(dres->jk_StopHere == Ijk_INVALID);
   1016    dres->whatNext    = Dis_StopHere;
   1017    dres->jk_StopHere = kind;
   1018    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
   1019 }
   1020 
   1021 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
   1022    This function should be called before any other operation if widening
   1023    multiplications are used. */
   1024 static IRExpr *getAcc(UInt acNo)
   1025 {
   1026    vassert(!mode64);
   1027    vassert(acNo <= 3);
   1028    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
   1029 }
   1030 
   1031 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
   1032    instructions). */
   1033 static IRExpr *getDSPControl(void)
   1034 {
   1035    vassert(!mode64);
   1036    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
   1037 }
   1038 
   1039 /* Put value to DSPControl register. Expression e is written to DSPControl as
   1040    is. If only certain bits of DSPControl need to be changed, it should be done
   1041    before calling putDSPControl(). It could be done by reading DSPControl and
   1042    ORing it with appropriate mask. */
   1043 static void putDSPControl(IRExpr * e)
   1044 {
   1045    vassert(!mode64);
   1046    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
   1047 }
   1048 
   1049 /* Fetch a byte from the guest insn stream. */
   1050 static UChar getIByte(Int delta)
   1051 {
   1052    return guest_code[delta];
   1053 }
   1054 
   1055 static IRExpr *getIReg(UInt iregNo)
   1056 {
   1057    if (0 == iregNo) {
   1058       return mode64 ? mkU64(0x0) : mkU32(0x0);
   1059    } else {
   1060       IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1061       vassert(iregNo < 32);
   1062       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
   1063    }
   1064 }
   1065 
   1066 static IRExpr *getHI(void)
   1067 {
   1068    if (mode64)
   1069       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
   1070    else
   1071       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
   1072 }
   1073 
   1074 static IRExpr *getLO(void)
   1075 {
   1076    if (mode64)
   1077       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
   1078    else
   1079       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
   1080 }
   1081 
   1082 static IRExpr *getFCSR(void)
   1083 {
   1084    if (mode64)
   1085       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
   1086    else
   1087       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
   1088 }
   1089 
   1090 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
   1091 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
   1092 {
   1093   UInt pos = byte_pos * 8;
   1094   if (mode64)
   1095       return unop(Iop_64to8, binop(Iop_And64,
   1096                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
   1097                                    mkU64(0xFF)));
   1098    else
   1099       return unop(Iop_32to8, binop(Iop_And32,
   1100                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
   1101                                    mkU32(0xFF)));
   1102 }
   1103 
   1104 static void putFCSR(IRExpr * e)
   1105 {
   1106    if (mode64)
   1107       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
   1108    else
   1109       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
   1110 }
   1111 
   1112 /* fs   - fpu source register number.
   1113    inst - fpu instruction that needs to be executed.
   1114    sz32 - size of source register.
   1115    opN  - number of operads:
   1116           1 - unary operation.
   1117           2 - binary operation. */
   1118 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
   1119 {
   1120    IRDirty *d;
   1121    IRTemp fcsr = newTemp(Ity_I32);
   1122    /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
   1123    if (fp_mode64)
   1124       d = unsafeIRDirty_1_N(fcsr, 0,
   1125                             "mips_dirtyhelper_calculate_FCSR_fp64",
   1126                             &mips_dirtyhelper_calculate_FCSR_fp64,
   1127                             mkIRExprVec_4(IRExpr_BBPTR(),
   1128                                           mkU32(fs),
   1129                                           mkU32(ft),
   1130                                           mkU32(inst)));
   1131    else
   1132       d = unsafeIRDirty_1_N(fcsr, 0,
   1133                             "mips_dirtyhelper_calculate_FCSR_fp32",
   1134                             &mips_dirtyhelper_calculate_FCSR_fp32,
   1135                             mkIRExprVec_4(IRExpr_BBPTR(),
   1136                                           mkU32(fs),
   1137                                           mkU32(ft),
   1138                                           mkU32(inst)));
   1139 
   1140    if (opN == 1) {  /* Unary operation. */
   1141       /* Declare we're reading guest state. */
   1142       if (sz32 || fp_mode64)
   1143          d->nFxState = 2;
   1144       else
   1145          d->nFxState = 3;
   1146       vex_bzero(&d->fxState, sizeof(d->fxState));
   1147 
   1148       d->fxState[0].fx     = Ifx_Read;  /* read */
   1149       if (mode64)
   1150          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1151       else
   1152          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1153       d->fxState[0].size   = sizeof(UInt);
   1154       d->fxState[1].fx     = Ifx_Read;  /* read */
   1155       d->fxState[1].offset = floatGuestRegOffset(fs);
   1156       d->fxState[1].size   = sizeof(ULong);
   1157 
   1158       if (!(sz32 || fp_mode64)) {
   1159          d->fxState[2].fx     = Ifx_Read;  /* read */
   1160          d->fxState[2].offset = floatGuestRegOffset(fs+1);
   1161          d->fxState[2].size   = sizeof(ULong);
   1162       }
   1163    } else if (opN == 2) {  /* Binary operation. */
   1164       /* Declare we're reading guest state. */
   1165       if (sz32 || fp_mode64)
   1166          d->nFxState = 3;
   1167       else
   1168          d->nFxState = 5;
   1169       vex_bzero(&d->fxState, sizeof(d->fxState));
   1170 
   1171       d->fxState[0].fx     = Ifx_Read;  /* read */
   1172       if (mode64)
   1173          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1174       else
   1175          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1176       d->fxState[0].size   = sizeof(UInt);
   1177       d->fxState[1].fx     = Ifx_Read;  /* read */
   1178       d->fxState[1].offset = floatGuestRegOffset(fs);
   1179       d->fxState[1].size   = sizeof(ULong);
   1180       d->fxState[2].fx     = Ifx_Read;  /* read */
   1181       d->fxState[2].offset = floatGuestRegOffset(ft);
   1182       d->fxState[2].size   = sizeof(ULong);
   1183 
   1184       if (!(sz32 || fp_mode64)) {
   1185          d->fxState[3].fx     = Ifx_Read;  /* read */
   1186          d->fxState[3].offset = floatGuestRegOffset(fs+1);
   1187          d->fxState[3].size   = sizeof(ULong);
   1188          d->fxState[4].fx     = Ifx_Read;  /* read */
   1189          d->fxState[4].offset = floatGuestRegOffset(ft+1);
   1190          d->fxState[4].size   = sizeof(ULong);
   1191       }
   1192    }
   1193 
   1194    stmt(IRStmt_Dirty(d));
   1195 
   1196    putFCSR(mkexpr(fcsr));
   1197 }
   1198 
   1199 static IRExpr *getULR(void)
   1200 {
   1201    if (mode64)
   1202       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
   1203    else
   1204       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
   1205 }
   1206 
   1207 static void putIReg(UInt archreg, IRExpr * e)
   1208 {
   1209    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1210    vassert(archreg < 32);
   1211    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1212    if (archreg != 0)
   1213       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
   1214 }
   1215 
   1216 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
   1217 {
   1218    vassert(ty == Ity_I32 || ty == Ity_I64);
   1219    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
   1220 }
   1221 
   1222 static void putLO(IRExpr * e)
   1223 {
   1224    if (mode64) {
   1225       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
   1226    } else {
   1227       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
   1228    /* Add value to lower 32 bits of ac0 to maintain compatibility between
   1229       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
   1230       unchanged. */
   1231       IRTemp t_lo = newTemp(Ity_I32);
   1232       IRTemp t_hi = newTemp(Ity_I32);
   1233       assign(t_lo, e);
   1234       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
   1235       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1236            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1237    }
   1238 }
   1239 
   1240 static void putHI(IRExpr * e)
   1241 {
   1242    if (mode64) {
   1243       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
   1244    } else {
   1245       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
   1246    /* Add value to higher 32 bits of ac0 to maintain compatibility between
   1247       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
   1248       unchanged. */
   1249       IRTemp t_lo = newTemp(Ity_I32);
   1250       IRTemp t_hi = newTemp(Ity_I32);
   1251       assign(t_hi, e);
   1252       assign(t_lo, unop(Iop_64to32, getAcc(0)));
   1253       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1254            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1255    }
   1256 }
   1257 
   1258 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
   1259 static void putAcc(UInt acNo, IRExpr * e)
   1260 {
   1261    vassert(!mode64);
   1262    vassert(acNo <= 3);
   1263    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
   1264    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
   1265 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
   1266    between MIPS32 and MIPS DSP ASE insn sets. */
   1267    if (0 == acNo) {
   1268      putLO(unop(Iop_64to32, e));
   1269      putHI(unop(Iop_64HIto32, e));
   1270    }
   1271 }
   1272 
   1273 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
   1274 {
   1275    vassert(ty == Ity_I32 || ty == Ity_I64);
   1276    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
   1277 }
   1278 
   1279 static void putPC(IRExpr * e)
   1280 {
   1281    stmt(IRStmt_Put(OFFB_PC, e));
   1282 }
   1283 
   1284 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
   1285 {
   1286    vassert(ty == Ity_I32 || ty == Ity_I64);
   1287    if (ty == Ity_I32)
   1288       return src;
   1289    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
   1290 }
   1291 
   1292 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
   1293    of these combinations make sense. */
   1294 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
   1295 {
   1296    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
   1297    if (src_ty == dst_ty)
   1298       return e;
   1299    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
   1300       return unop(Iop_32to16, e);
   1301    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
   1302       return unop(Iop_32to8, e);
   1303    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
   1304       vassert(mode64);
   1305       return unop(Iop_64to8, e);
   1306    }
   1307    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
   1308       vassert(mode64);
   1309       return unop(Iop_64to16, e);
   1310    }
   1311    vpanic("narrowTo(mips)");
   1312    return 0;
   1313 }
   1314 
   1315 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
   1316 {
   1317    vassert(ty == Ity_F32 || ty == Ity_F64);
   1318    if (ty == Ity_F64) {
   1319       IRTemp t0, t1;
   1320       t0 = newTemp(Ity_I64);
   1321       t1 = newTemp(Ity_I32);
   1322       assign(t0, unop(Iop_ReinterpF64asI64, src));
   1323       assign(t1, unop(Iop_64to32, mkexpr(t0)));
   1324       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
   1325    } else
   1326       return src;
   1327 }
   1328 
   1329 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
   1330 {
   1331    vassert(ty == Ity_F32 || ty == Ity_F64);
   1332    if (ty == Ity_F64) {
   1333       IRTemp t0 = newTemp(Ity_I32);
   1334       IRTemp t1 = newTemp(Ity_I64);
   1335       assign(t0, unop(Iop_ReinterpF32asI32, src));
   1336       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
   1337       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
   1338    } else
   1339       return src;
   1340 }
   1341 
   1342 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
   1343 {
   1344    ULong branch_offset;
   1345    IRTemp t0;
   1346 
   1347    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1348       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1349       is added to the address of the instruction following
   1350       the branch (not the branch itself), in the branch delay slot, to form
   1351       a PC-relative effective target address. */
   1352    if (mode64)
   1353       branch_offset = extend_s_18to64(imm << 2);
   1354    else
   1355       branch_offset = extend_s_18to32(imm << 2);
   1356 
   1357    t0 = newTemp(Ity_I1);
   1358    assign(t0, guard);
   1359 
   1360    if (mode64)
   1361       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1362                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
   1363    else
   1364       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1365                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
   1366 
   1367    irsb->jumpkind = Ijk_Boring;
   1368 
   1369    if (mode64)
   1370       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
   1371    else
   1372       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
   1373 }
   1374 
   1375 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
   1376 {
   1377    ULong branch_offset;
   1378    IRTemp t0;
   1379 
   1380    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
   1381       if (mode64)
   1382          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   1383       else
   1384          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   1385    }
   1386 
   1387    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1388       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1389       is added to the address of the instruction following
   1390       the branch (not the branch itself), in the branch delay slot, to form
   1391       a PC-relative effective target address. */
   1392 
   1393    if (mode64)
   1394       branch_offset = extend_s_18to64(imm << 2);
   1395    else
   1396       branch_offset = extend_s_18to32(imm << 2);
   1397 
   1398    t0 = newTemp(Ity_I1);
   1399    assign(t0, guard);
   1400    if (mode64)
   1401       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1402                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
   1403                          OFFB_PC);
   1404    else
   1405       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1406                          IRConst_U32(guest_PC_curr_instr + 4 +
   1407                                      (UInt) branch_offset), OFFB_PC);
   1408 }
   1409 
   1410 static IRExpr *getFReg(UInt fregNo)
   1411 {
   1412    vassert(fregNo < 32);
   1413    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1414    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
   1415 }
   1416 
   1417 static IRExpr *getDReg(UInt dregNo)
   1418 {
   1419    vassert(dregNo < 32);
   1420    if (fp_mode64) {
   1421       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
   1422    } else {
   1423       /* Read a floating point register pair and combine their contents into a
   1424          64-bit value */
   1425       IRTemp t0 = newTemp(Ity_F32);
   1426       IRTemp t1 = newTemp(Ity_F32);
   1427       IRTemp t2 = newTemp(Ity_F64);
   1428       IRTemp t3 = newTemp(Ity_I32);
   1429       IRTemp t4 = newTemp(Ity_I32);
   1430       IRTemp t5 = newTemp(Ity_I64);
   1431 
   1432       assign(t0, getFReg(dregNo));
   1433       assign(t1, getFReg(dregNo + 1));
   1434 
   1435       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
   1436       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
   1437       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
   1438       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
   1439 
   1440       return mkexpr(t2);
   1441    }
   1442 }
   1443 
   1444 static void putFReg(UInt dregNo, IRExpr * e)
   1445 {
   1446    vassert(dregNo < 32);
   1447    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1448    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1449    stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1450 }
   1451 
   1452 static void putDReg(UInt dregNo, IRExpr * e)
   1453 {
   1454    if (fp_mode64) {
   1455       vassert(dregNo < 32);
   1456       IRType ty = Ity_F64;
   1457       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1458       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1459    } else {
   1460       vassert(dregNo < 32);
   1461       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
   1462       IRTemp t1 = newTemp(Ity_F64);
   1463       IRTemp t4 = newTemp(Ity_I32);
   1464       IRTemp t5 = newTemp(Ity_I32);
   1465       IRTemp t6 = newTemp(Ity_I64);
   1466       assign(t1, e);
   1467       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
   1468       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
   1469       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
   1470       putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
   1471       putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
   1472    }
   1473 }
   1474 
   1475 static void setFPUCondCode(IRExpr * e, UInt cc)
   1476 {
   1477    if (cc == 0) {
   1478       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
   1479       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
   1480    } else {
   1481       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
   1482                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
   1483       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
   1484    }
   1485 }
   1486 
   1487 static IRExpr* get_IR_roundingmode ( void )
   1488 {
   1489 /*
   1490    rounding mode | MIPS | IR
   1491    ------------------------
   1492    to nearest    | 00  | 00
   1493    to zero       | 01  | 11
   1494    to +infinity  | 10  | 10
   1495    to -infinity  | 11  | 01
   1496 */
   1497    IRTemp rm_MIPS = newTemp(Ity_I32);
   1498    /* Last two bits in FCSR are rounding mode. */
   1499 
   1500    if (mode64)
   1501       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
   1502                                        guest_FCSR), Ity_I32), mkU32(3)));
   1503    else
   1504       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
   1505                                        guest_FCSR), Ity_I32), mkU32(3)));
   1506 
   1507    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
   1508 
   1509    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
   1510                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
   1511 }
   1512 
   1513 /* sz, ULong -> IRExpr */
   1514 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
   1515 {
   1516    vassert(ty == Ity_I32 || ty == Ity_I64);
   1517    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
   1518 }
   1519 
   1520 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
   1521 {
   1522    vassert(ty == Ity_I32 || ty == Ity_I64);
   1523    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
   1524 }
   1525 
   1526 /* Make sure we get valid 32 and 64bit addresses */
   1527 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
   1528 {
   1529    vassert(ty == Ity_I32 || ty == Ity_I64);
   1530    return (ty == Ity_I64 ? (Addr64) addr :
   1531                            (Addr64) extend_s_32to64(toUInt(addr)));
   1532 }
   1533 
   1534 /* Shift and Rotate instructions for MIPS64 */
   1535 static Bool dis_instr_shrt ( UInt theInstr )
   1536 {
   1537    UInt opc2 = get_function(theInstr);
   1538    UChar regRs = get_rs(theInstr);
   1539    UChar regRt = get_rt(theInstr);
   1540    UChar regRd = get_rd(theInstr);
   1541    UChar uImmsa = get_sa(theInstr);
   1542    Long sImmsa = extend_s_16to64(uImmsa);
   1543    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1544    IRTemp tmp = newTemp(ty);
   1545    IRTemp tmpOr = newTemp(ty);
   1546    IRTemp tmpRt = newTemp(ty);
   1547    IRTemp tmpRs = newTemp(ty);
   1548    IRTemp tmpRd = newTemp(ty);
   1549 
   1550    assign(tmpRs, getIReg(regRs));
   1551    assign(tmpRt, getIReg(regRt));
   1552 
   1553    switch (opc2) {
   1554       case 0x3A:
   1555          if ((regRs & 0x01) == 0) {
   1556             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
   1557             DIP("dsrl r%u, r%u, %lld", regRd, regRt, sImmsa);
   1558             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1559             putIReg(regRd, mkexpr(tmpRd));
   1560          } else if ((regRs & 0x01) == 1) {
   1561             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
   1562             vassert(mode64);
   1563             DIP("drotr r%u, r%u, %lld", regRd, regRt, sImmsa);
   1564             IRTemp tmpL = newTemp(ty);
   1565             IRTemp tmpR = newTemp(ty);
   1566             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1567             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
   1568             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1569             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1570             putIReg(regRd, mkexpr(tmpRd));
   1571          } else
   1572             return False;
   1573          break;
   1574 
   1575       case 0x3E:
   1576          if ((regRs & 0x01) == 0) {
   1577             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
   1578             DIP("dsrl32 r%u, r%u, %lld", regRd, regRt, sImmsa + 32);
   1579             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1580             putIReg(regRd, mkexpr(tmpRd));
   1581          } else if ((regRs & 0x01) == 1) {
   1582             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
   1583             DIP("drotr32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1584             vassert(mode64);
   1585             IRTemp tmpL = newTemp(ty);
   1586             IRTemp tmpR = newTemp(ty);
   1587             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
   1588             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1589             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
   1590                               mkU8(63 - (uImmsa + 32))));
   1591             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1592             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1593             putIReg(regRd, mkexpr(tmpRd));
   1594          } else
   1595             return False;
   1596          break;
   1597 
   1598       case 0x16:
   1599          if ((uImmsa & 0x01) == 0) {
   1600             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
   1601             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
   1602             IRTemp tmpRs8 = newTemp(Ity_I8);
   1603             /* s = tmpRs[5..0] */
   1604             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
   1605             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1606             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1607             putIReg(regRd, mkexpr(tmpRd));
   1608          } else if ((uImmsa & 0x01) == 1) {
   1609             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
   1610             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
   1611             IRTemp tmpL = newTemp(ty);
   1612             IRTemp tmpR = newTemp(ty);
   1613             IRTemp tmpRs8 = newTemp(Ity_I8);
   1614             IRTemp tmpLs8 = newTemp(Ity_I8);
   1615             IRTemp tmp64 = newTemp(ty);
   1616             /* s = tmpRs[5...0]
   1617                m = 64 - s
   1618                (tmpRt << s) | (tmpRt >> m) */
   1619 
   1620             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1621             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
   1622 
   1623             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1624             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
   1625 
   1626             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1627             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
   1628             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
   1629             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
   1630 
   1631             putIReg(regRd, mkexpr(tmpOr));
   1632          } else
   1633             return False;
   1634          break;
   1635 
   1636       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
   1637          DIP("dsll r%u, r%u, %lld", regRd, regRt, sImmsa);
   1638          vassert(mode64);
   1639          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
   1640          putIReg(regRd, mkexpr(tmpRd));
   1641          break;
   1642 
   1643       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
   1644          DIP("dsll32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1645          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1646          putIReg(regRd, mkexpr(tmpRd));
   1647          break;
   1648 
   1649       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
   1650          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
   1651          IRTemp tmpRs8 = newTemp(Ity_I8);
   1652 
   1653          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1654          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1655          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1656          putIReg(regRd, mkexpr(tmpRd));
   1657          break;
   1658       }
   1659 
   1660       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
   1661          DIP("dsra r%u, r%u, %lld", regRd, regRt, sImmsa);
   1662          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
   1663          putIReg(regRd, mkexpr(tmpRd));
   1664          break;
   1665 
   1666       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
   1667                      MIPS64 */
   1668          DIP("dsra32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1669          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1670          putIReg(regRd, mkexpr(tmpRd));
   1671          break;
   1672 
   1673       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
   1674                        MIPS64 */
   1675          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
   1676          IRTemp tmpRs8 = newTemp(Ity_I8);
   1677          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1678          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1679          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1680          putIReg(regRd, mkexpr(tmpRd));
   1681          break;
   1682 
   1683       }
   1684 
   1685       default:
   1686          return False;
   1687 
   1688    }
   1689    return True;
   1690 }
   1691 
   1692 static IROp mkSzOp ( IRType ty, IROp op8 )
   1693 {
   1694    Int adj;
   1695    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
   1696    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
   1697            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
   1698            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
   1699            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
   1700    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
   1701    return adj + op8;
   1702 }
   1703 
   1704 /*********************************************************/
   1705 /*---             Floating Point Compare              ---*/
   1706 /*********************************************************/
   1707 /* Function that returns a string that represent mips cond
   1708    mnemonic for the input code. */
   1709 static const HChar* showCondCode(UInt code) {
   1710    const HChar* ret;
   1711    switch (code) {
   1712       case 0: ret = "f"; break;
   1713       case 1: ret = "un"; break;
   1714       case 2: ret = "eq"; break;
   1715       case 3: ret = "ueq"; break;
   1716       case 4: ret = "olt"; break;
   1717       case 5: ret = "ult"; break;
   1718       case 6: ret = "ole"; break;
   1719       case 7: ret = "ule"; break;
   1720       case 8: ret = "sf"; break;
   1721       case 9: ret = "ngle"; break;
   1722       case 10: ret = "seq"; break;
   1723       case 11: ret = "ngl"; break;
   1724       case 12: ret = "lt"; break;
   1725       case 13: ret = "nge"; break;
   1726       case 14: ret = "le"; break;
   1727       case 15: ret = "ngt"; break;
   1728       default: vpanic("showCondCode"); break;
   1729    }
   1730    return ret;
   1731 }
   1732 
   1733 static Bool dis_instr_CCondFmt ( UInt cins )
   1734 {
   1735    IRTemp t0, t1, t2, t3, tmp5, tmp6;
   1736    IRTemp ccIR = newTemp(Ity_I32);
   1737    IRTemp ccMIPS = newTemp(Ity_I32);
   1738    UInt FC = get_FC(cins);
   1739    UInt fmt = get_fmt(cins);
   1740    UInt fs = get_fs(cins);
   1741    UInt ft = get_ft(cins);
   1742    UInt cond = get_cond(cins);
   1743 
   1744    if (FC == 0x3) {  /* C.cond.fmt */
   1745       UInt fpc_cc = get_fpc_cc(cins);
   1746       switch (fmt) {
   1747          case 0x10: {  /* C.cond.S */
   1748             DIP("c.%s.s %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   1749             if (fp_mode64) {
   1750                t0 = newTemp(Ity_I32);
   1751                t1 = newTemp(Ity_I32);
   1752                t2 = newTemp(Ity_I32);
   1753                t3 = newTemp(Ity_I32);
   1754 
   1755                tmp5 = newTemp(Ity_F64);
   1756                tmp6 = newTemp(Ity_F64);
   1757 
   1758                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1759                                  getFReg(fs))));
   1760                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1761                                  getFReg(ft))));
   1762 
   1763                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
   1764                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1765                                    mkexpr(ccIR), True));
   1766                /* Map compare result from IR to MIPS
   1767                   FP cmp result | MIPS | IR
   1768                   --------------------------
   1769                   UN            | 0x1 | 0x45
   1770                   EQ            | 0x2 | 0x40
   1771                   GT            | 0x4 | 0x00
   1772                   LT            | 0x8 | 0x01
   1773                 */
   1774 
   1775                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1776                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1777                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1778                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
   1779                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1780                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1781                               mkU32(1))))));
   1782                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1783                                    mkexpr(ccMIPS), True));
   1784 
   1785                /* UN */
   1786                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1787                /* EQ */
   1788                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1789                                                  mkU8(0x1)), mkU32(0x1)));
   1790                /* NGT */
   1791                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1792                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
   1793                /* LT */
   1794                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1795                                                  mkU8(0x3)), mkU32(0x1)));
   1796                switch (cond) {
   1797                   case 0x0:
   1798                      setFPUCondCode(mkU32(0), fpc_cc);
   1799                      break;
   1800                   case 0x1:
   1801                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1802                      break;
   1803                   case 0x2:
   1804                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1805                      break;
   1806                   case 0x3:
   1807                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1808                                           fpc_cc);
   1809                      break;
   1810                   case 0x4:
   1811                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1812                      break;
   1813                   case 0x5:
   1814                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1815                                           fpc_cc);
   1816                      break;
   1817                   case 0x6:
   1818                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1819                                           fpc_cc);
   1820                      break;
   1821                   case 0x7:
   1822                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1823                      break;
   1824                   case 0x8:
   1825                      setFPUCondCode(mkU32(0), fpc_cc);
   1826                      break;
   1827                   case 0x9:
   1828                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1829                      break;
   1830                   case 0xA:
   1831                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1832                      break;
   1833                   case 0xB:
   1834                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1835                                           fpc_cc);
   1836                      break;
   1837                   case 0xC:
   1838                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1839                      break;
   1840                   case 0xD:
   1841                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1842                                           fpc_cc);
   1843                      break;
   1844                   case 0xE:
   1845                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1846                                           fpc_cc);
   1847                      break;
   1848                   case 0xF:
   1849                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1850                      break;
   1851 
   1852                   default:
   1853                      return False;
   1854                }
   1855 
   1856             } else {
   1857                t0 = newTemp(Ity_I32);
   1858                t1 = newTemp(Ity_I32);
   1859                t2 = newTemp(Ity_I32);
   1860                t3 = newTemp(Ity_I32);
   1861 
   1862                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
   1863                                   unop(Iop_F32toF64, getFReg(ft))));
   1864                /* Map compare result from IR to MIPS
   1865                   FP cmp result | MIPS | IR
   1866                   --------------------------
   1867                   UN            | 0x1 | 0x45
   1868                   EQ            | 0x2 | 0x40
   1869                   GT            | 0x4 | 0x00
   1870                   LT            | 0x8 | 0x01
   1871                 */
   1872 
   1873                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1874                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1875                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1876                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
   1877                                     mkU32(2)), binop(Iop_And32,
   1878                               binop(Iop_Xor32, mkexpr(ccIR),
   1879                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1880                               mkU32(1))))));
   1881                /* UN */
   1882                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1883                /* EQ */
   1884                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1885                       mkU8(0x1)), mkU32(0x1)));
   1886                /* NGT */
   1887                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1888                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1889                /* LT */
   1890                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1891                       mkU8(0x3)), mkU32(0x1)));
   1892 
   1893                switch (cond) {
   1894                   case 0x0:
   1895                      setFPUCondCode(mkU32(0), fpc_cc);
   1896                      break;
   1897                   case 0x1:
   1898                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1899                      break;
   1900                   case 0x2:
   1901                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1902                      break;
   1903                   case 0x3:
   1904                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1905                                           fpc_cc);
   1906                      break;
   1907                   case 0x4:
   1908                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1909                      break;
   1910                   case 0x5:
   1911                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1912                                           fpc_cc);
   1913                      break;
   1914                   case 0x6:
   1915                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1916                                           fpc_cc);
   1917                      break;
   1918                   case 0x7:
   1919                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1920                      break;
   1921                   case 0x8:
   1922                      setFPUCondCode(mkU32(0), fpc_cc);
   1923                      break;
   1924                   case 0x9:
   1925                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1926                      break;
   1927                   case 0xA:
   1928                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1929                      break;
   1930                   case 0xB:
   1931                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1932                                           fpc_cc);
   1933                      break;
   1934                   case 0xC:
   1935                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1936                      break;
   1937                   case 0xD:
   1938                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1939                                           fpc_cc);
   1940                      break;
   1941                   case 0xE:
   1942                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1943                                           fpc_cc);
   1944                      break;
   1945                   case 0xF:
   1946                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1947                      break;
   1948 
   1949                   default:
   1950                      return False;
   1951                }
   1952             }
   1953          }
   1954             break;
   1955 
   1956          case 0x11: {  /* C.cond.D */
   1957             DIP("c.%s.d %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   1958             t0 = newTemp(Ity_I32);
   1959             t1 = newTemp(Ity_I32);
   1960             t2 = newTemp(Ity_I32);
   1961             t3 = newTemp(Ity_I32);
   1962             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
   1963             /* Map compare result from IR to MIPS
   1964                FP cmp result | MIPS | IR
   1965                --------------------------
   1966                UN            | 0x1 | 0x45
   1967                EQ            | 0x2 | 0x40
   1968                GT            | 0x4 | 0x00
   1969                LT            | 0x8 | 0x01
   1970              */
   1971 
   1972             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1973             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1974                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1975                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
   1976                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1977                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1978                            mkU32(1))))));
   1979 
   1980             /* UN */
   1981             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1982             /* EQ */
   1983             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1984                    mkU8(0x1)), mkU32(0x1)));
   1985             /* NGT */
   1986             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1987                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1988             /* LT */
   1989             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1990                    mkU8(0x3)), mkU32(0x1)));
   1991 
   1992             switch (cond) {
   1993                case 0x0:
   1994                   setFPUCondCode(mkU32(0), fpc_cc);
   1995                   break;
   1996                case 0x1:
   1997                   setFPUCondCode(mkexpr(t0), fpc_cc);
   1998                   break;
   1999                case 0x2:
   2000                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2001                   break;
   2002                case 0x3:
   2003                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2004                                        fpc_cc);
   2005                   break;
   2006                case 0x4:
   2007                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2008                   break;
   2009                case 0x5:
   2010                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2011                                        fpc_cc);
   2012                   break;
   2013                case 0x6:
   2014                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2015                                        fpc_cc);
   2016                   break;
   2017                case 0x7:
   2018                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2019                   break;
   2020                case 0x8:
   2021                   setFPUCondCode(mkU32(0), fpc_cc);
   2022                   break;
   2023                case 0x9:
   2024                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2025                   break;
   2026                case 0xA:
   2027                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2028                   break;
   2029                case 0xB:
   2030                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2031                                        fpc_cc);
   2032                   break;
   2033                case 0xC:
   2034                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2035                   break;
   2036                case 0xD:
   2037                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2038                                        fpc_cc);
   2039                   break;
   2040                case 0xE:
   2041                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2042                                        fpc_cc);
   2043                   break;
   2044                case 0xF:
   2045                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2046                   break;
   2047                default:
   2048                   return False;
   2049             }
   2050          }
   2051          break;
   2052 
   2053          default:
   2054             return False;
   2055       }
   2056    } else {
   2057       return False;
   2058    }
   2059 
   2060    return True;
   2061 }
   2062 
   2063 /*********************************************************/
   2064 /*---        Branch Instructions for mips64           ---*/
   2065 /*********************************************************/
   2066 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
   2067                                Bool(*resteerOkFn) (void *, Addr),
   2068                                void *callback_opaque, IRStmt ** set )
   2069 {
   2070    UInt jmpKind = 0;
   2071    UChar opc1 = get_opcode(theInstr);
   2072    UChar regRs = get_rs(theInstr);
   2073    UChar regRt = get_rt(theInstr);
   2074    UInt offset = get_imm(theInstr);
   2075    Long sOffset = extend_s_16to64(offset);
   2076    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   2077    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
   2078 
   2079    IRTemp tmp = newTemp(ty);
   2080    IRTemp tmpRs = newTemp(ty);
   2081    IRTemp tmpRt = newTemp(ty);
   2082    IRTemp tmpLt = newTemp(ty);
   2083    IRTemp tmpReg0 = newTemp(ty);
   2084 
   2085    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
   2086    Addr64 addrTgt = 0;
   2087    Addr64 cia = guest_PC_curr_instr;
   2088 
   2089    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
   2090    IRExpr *eNia = mkSzImm(ty, cia + 8);
   2091    IRExpr *eCond = NULL;
   2092 
   2093    assign(tmpRs, getIReg(regRs));
   2094    assign(tmpRt, getIReg(regRt));
   2095    assign(tmpReg0, getIReg(0));
   2096 
   2097    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
   2098 
   2099    switch (opc1) {
   2100       case 0x01:
   2101          switch (regRt) {
   2102             case 0x00: {  /* BLTZ rs, offset */
   2103                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2104                IRTemp tmpLtRes = newTemp(Ity_I1);
   2105 
   2106                assign(tmp, eConst0);
   2107                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2108                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2109                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2110 
   2111                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
   2112                              mkexpr(tmpReg0));
   2113 
   2114                jmpKind = Ijk_Boring;
   2115                break;
   2116             }
   2117 
   2118             case 0x01: {  /* BGEZ rs, offset */
   2119                IRTemp tmpLtRes = newTemp(Ity_I1);
   2120                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2121 
   2122                assign(tmp, eConst0);
   2123                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2124                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2125                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2126                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2127                                     mkexpr(tmpReg0));
   2128 
   2129                jmpKind = Ijk_Boring;
   2130                break;
   2131             }
   2132 
   2133             case 0x11: {  /* BGEZAL rs, offset */
   2134                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2135                putIReg(regLnk, eNia);
   2136                IRTemp tmpLtRes = newTemp(Ity_I1);
   2137 
   2138                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
   2139                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2140                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2141 
   2142                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2143                                     mkexpr(tmpReg0));
   2144 
   2145                jmpKind = Ijk_Call;
   2146                break;
   2147             }
   2148 
   2149             case 0x10: {  /* BLTZAL rs, offset */
   2150                IRTemp tmpLtRes = newTemp(Ity_I1);
   2151                IRTemp tmpRes = newTemp(ty);
   2152 
   2153                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2154                putIReg(regLnk, eNia);
   2155 
   2156                assign(tmp, eConst0);
   2157                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2158                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
   2159                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2160                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
   2161                                                      mkexpr(tmpReg0));
   2162 
   2163                jmpKind = Ijk_Call;
   2164                break;
   2165             }
   2166 
   2167          }
   2168          break;
   2169       default:
   2170          return False;
   2171       }
   2172    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
   2173    return True;
   2174 }
   2175 
   2176 /*********************************************************/
   2177 /*---         Cavium Specific Instructions            ---*/
   2178 /*********************************************************/
   2179 
   2180 /* Convenience function to yield to thread scheduler */
   2181 static void jump_back(IRExpr *condition)
   2182 {
   2183    stmt( IRStmt_Exit(condition,
   2184                      Ijk_Yield,
   2185                      IRConst_U64( guest_PC_curr_instr ),
   2186                      OFFB_PC) );
   2187 }
   2188 
   2189 /* Based on s390_irgen_load_and_add32. */
   2190 static void mips_irgen_load_and_add32(IRTemp op1addr, IRTemp new_val,
   2191                                       UChar rd, Bool putIntoRd)
   2192 {
   2193    IRCAS *cas;
   2194    IRTemp old_mem = newTemp(Ity_I32);
   2195    IRTemp expd    = newTemp(Ity_I32);
   2196 
   2197    assign(expd, load(Ity_I32, mkexpr(op1addr)));
   2198 
   2199    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2200                  Iend_LE, mkexpr(op1addr),
   2201                  NULL, mkexpr(expd), /* expected value */
   2202                  NULL, mkexpr(new_val)  /* new value */);
   2203    stmt(IRStmt_CAS(cas));
   2204 
   2205    /* If old_mem contains the expected value, then the CAS succeeded.
   2206       Otherwise, it did not */
   2207    jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd)));
   2208    if (putIntoRd)
   2209       putIReg(rd, mkWidenFrom32(Ity_I64, mkexpr(old_mem), True));
   2210 }
   2211 
   2212 /* Based on s390_irgen_load_and_add64. */
   2213 static void mips_irgen_load_and_add64(IRTemp op1addr, IRTemp new_val,
   2214                                       UChar rd, Bool putIntoRd)
   2215 {
   2216    IRCAS *cas;
   2217    IRTemp old_mem = newTemp(Ity_I64);
   2218    IRTemp expd    = newTemp(Ity_I64);
   2219 
   2220    assign(expd, load(Ity_I64, mkexpr(op1addr)));
   2221 
   2222    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2223                  Iend_LE, mkexpr(op1addr),
   2224                  NULL, mkexpr(expd), /* expected value */
   2225                  NULL, mkexpr(new_val)  /* new value */);
   2226    stmt(IRStmt_CAS(cas));
   2227 
   2228    /* If old_mem contains the expected value, then the CAS succeeded.
   2229       Otherwise, it did not */
   2230    jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd)));
   2231    if (putIntoRd)
   2232       putIReg(rd, mkexpr(old_mem));
   2233 }
   2234 
   2235 static Bool dis_instr_CVM ( UInt theInstr )
   2236 {
   2237    UChar  opc2     = get_function(theInstr);
   2238    UChar  opc1     = get_opcode(theInstr);
   2239    UChar  regRs    = get_rs(theInstr);
   2240    UChar  regRt    = get_rt(theInstr);
   2241    UChar  regRd    = get_rd(theInstr);
   2242    /* MIPS trap instructions extract code from theInstr[15:6].
   2243       Cavium OCTEON instructions SNEI, SEQI extract immediate operands
   2244       from the same bit field [15:6]. */
   2245    UInt   imm      = get_code(theInstr);
   2246    UChar  lenM1    = get_msb(theInstr);
   2247    UChar  p        = get_lsb(theInstr);
   2248    IRType ty       = mode64? Ity_I64 : Ity_I32;
   2249    IRTemp tmp      = newTemp(ty);
   2250    IRTemp tmpRs    = newTemp(ty);
   2251    IRTemp tmpRt    = newTemp(ty);
   2252    IRTemp t1       = newTemp(ty);
   2253    UInt size;
   2254    assign(tmpRs, getIReg(regRs));
   2255 
   2256    switch(opc1) {
   2257       case 0x1C: {
   2258          switch(opc2) {
   2259             case 0x03: {  /* DMUL rd, rs, rt */
   2260                DIP("dmul r%u, r%u, r%u", regRd, regRs, regRt);
   2261                IRTemp t0 = newTemp(Ity_I128);
   2262                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
   2263                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
   2264                break;
   2265             }
   2266 
   2267             case 0x18: {  /* Store Atomic Add Word - SAA; Cavium OCTEON */
   2268                DIP("saa r%u, (r%u)", regRt, regRs);
   2269                IRTemp addr = newTemp(Ity_I64);
   2270                IRTemp new  = newTemp(Ity_I32);
   2271                assign (addr, getIReg(regRs));
   2272                assign(new, binop(Iop_Add32,
   2273                                  load(Ity_I32, mkexpr(addr)),
   2274                                  mkNarrowTo32(ty, getIReg(regRt))));
   2275                mips_irgen_load_and_add32(addr, new, 0, False);
   2276                break;
   2277             }
   2278 
   2279             /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
   2280             case 0x19: {
   2281                DIP( "saad r%u, (r%u)", regRt, regRs);
   2282                IRTemp addr = newTemp(Ity_I64);
   2283                IRTemp new  = newTemp(Ity_I64);
   2284                assign (addr, getIReg(regRs));
   2285                assign(new, binop(Iop_Add64,
   2286                                  load(Ity_I64, mkexpr(addr)),
   2287                                  getIReg(regRt)));
   2288                mips_irgen_load_and_add64(addr, new, 0, False);
   2289                break;
   2290             }
   2291 
   2292             /* LAI, LAID, LAD, LADD, LAS, LASD,
   2293                LAC, LACD, LAA, LAAD, LAW, LAWD */
   2294             case 0x1f: {
   2295                UInt opc3 = get_sa(theInstr);
   2296                IRTemp addr = newTemp(Ity_I64);
   2297                switch (opc3) {
   2298                   /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
   2299                   case 0x02: {
   2300                      DIP("lai r%u,(r%u)\n", regRd, regRs);
   2301                      IRTemp new  = newTemp(Ity_I32);
   2302                      assign(addr, getIReg(regRs));
   2303                      assign(new, binop(Iop_Add32,
   2304                                        load(Ity_I32, mkexpr(addr)),
   2305                                        mkU32(1)));
   2306                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2307                      break;
   2308                   }
   2309                   /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
   2310                   case 0x03: {
   2311                      DIP("laid r%u,(r%u)\n", regRd, regRs);
   2312                      IRTemp new  = newTemp(Ity_I64);
   2313                      assign(addr, getIReg(regRs));
   2314                      assign(new, binop(Iop_Add64,
   2315                                        load(Ity_I64, mkexpr(addr)),
   2316                                        mkU64(1)));
   2317                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2318                      break;
   2319                   }
   2320                   /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
   2321                   case 0x06: {
   2322                      DIP("lad r%u,(r%u)\n", regRd, regRs);
   2323                      IRTemp new  = newTemp(Ity_I32);
   2324                      assign(addr, getIReg(regRs));
   2325                      assign(new, binop(Iop_Sub32,
   2326                                        load(Ity_I32, mkexpr(addr)),
   2327                                        mkU32(1)));
   2328                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2329                      break;
   2330                   }
   2331                   /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
   2332                   case 0x07: {
   2333                      DIP("ladd r%u,(r%u)\n", regRd, regRs);
   2334                      IRTemp new  = newTemp(Ity_I64);
   2335                      assign (addr, getIReg(regRs));
   2336                      assign(new, binop(Iop_Sub64,
   2337                                        load(Ity_I64, mkexpr(addr)),
   2338                                        mkU64(1)));
   2339                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2340                      break;
   2341                   }
   2342                   /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
   2343                   case 0x0a: {
   2344                      DIP("las r%u,(r%u)\n", regRd, regRs);
   2345                      IRTemp new  = newTemp(Ity_I32);
   2346                      assign(addr, getIReg(regRs));
   2347                      assign(new, mkU32(0xffffffff));
   2348                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2349                      break;
   2350                   }
   2351                   /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
   2352                   case 0x0b: {
   2353                      DIP("lasd r%u,(r%u)\n", regRd, regRs);
   2354                      IRTemp new  = newTemp(Ity_I64);
   2355                      assign (addr, getIReg(regRs));
   2356                      assign(new, mkU64(0xffffffffffffffffULL));
   2357                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2358                      break;
   2359                   }
   2360                   /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
   2361                   case 0x0e: {
   2362                      DIP("lac r%u,(r%u)\n", regRd, regRs);
   2363                      IRTemp new  = newTemp(Ity_I32);
   2364                      assign (addr, getIReg(regRs));
   2365                      assign(new, mkU32(0));
   2366                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2367                      break;
   2368                   }
   2369                   /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
   2370                   case 0x0f: {
   2371                      DIP("lacd r%u,(r%u)\n", regRd, regRs);
   2372                      IRTemp new  = newTemp(Ity_I64);
   2373                      assign(addr, getIReg(regRs));
   2374                      assign(new, mkU64(0));
   2375                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2376                      break;
   2377                   }
   2378                   /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
   2379                   case 0x12: {
   2380                      DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2381                      IRTemp new  = newTemp(Ity_I32);
   2382                      assign(addr, getIReg(regRs));
   2383                      assign(new, binop(Iop_Add32,
   2384                                        load(Ity_I32, mkexpr(addr)),
   2385                                        mkNarrowTo32(ty, getIReg(regRt))));
   2386                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2387                      break;
   2388                   }
   2389                   /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
   2390                   case 0x13: {
   2391                      DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2392                      IRTemp new  = newTemp(Ity_I64);
   2393                      assign (addr, getIReg(regRs));
   2394                      assign(new, binop(Iop_Add64,
   2395                                        load(Ity_I64, mkexpr(addr)),
   2396                                        getIReg(regRt)));
   2397                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2398                      break;
   2399                   }
   2400                   /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
   2401                   case 0x16: {
   2402                      DIP("law r%u,(r%u)\n", regRd, regRs);
   2403                      IRTemp new  = newTemp(Ity_I32);
   2404                      assign(addr, getIReg(regRs));
   2405                      assign(new, mkNarrowTo32(ty, getIReg(regRt)));
   2406                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2407                      break;
   2408                   }
   2409                   /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
   2410                   case 0x17: {
   2411                      DIP("lawd r%u,(r%u)\n", regRd, regRs);
   2412                      IRTemp new  = newTemp(Ity_I64);
   2413                      assign(addr, getIReg(regRs));
   2414                      assign(new, getIReg(regRt));
   2415                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2416                      break;
   2417                   }
   2418                   default:
   2419                      vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3);
   2420                      vex_printf("Instruction=0x%08x\n", theInstr);
   2421                      return False;
   2422                }
   2423                break;
   2424             }
   2425 
   2426             /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
   2427             case 0x28: {
   2428                DIP("BADDU r%u, r%u, r%u", regRs, regRt, regRd);
   2429                IRTemp t0 = newTemp(Ity_I8);
   2430 
   2431                assign(t0, binop(Iop_Add8,
   2432                                 mkNarrowTo8(ty, getIReg(regRs)),
   2433                                 mkNarrowTo8(ty, getIReg(regRt))));
   2434 
   2435                if (mode64)
   2436                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2437                                        unop(Iop_8Uto64, mkexpr(t0)),
   2438                                        mkSzImm(ty, 0xFF)));
   2439                else
   2440                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2441                                        unop(Iop_8Uto32, mkexpr(t0)),
   2442                                        mkSzImm(ty, 0xFF)));
   2443                break;
   2444             }
   2445 
   2446             case 0x2c: {  /* Count Ones in a Word - POP; Cavium OCTEON */
   2447                int i, shift[5];
   2448                IRTemp mask[5];
   2449                IRTemp old = newTemp(ty);
   2450                IRTemp nyu = IRTemp_INVALID;
   2451                assign(old, getIReg(regRs));
   2452                DIP("pop r%u, r%u", regRd, regRs);
   2453 
   2454                for (i = 0; i < 5; i++) {
   2455                   mask[i] = newTemp(ty);
   2456                   shift[i] = 1 << i;
   2457                }
   2458                if(mode64) {
   2459                   assign(mask[0], mkU64(0x0000000055555555));
   2460                   assign(mask[1], mkU64(0x0000000033333333));
   2461                   assign(mask[2], mkU64(0x000000000F0F0F0F));
   2462                   assign(mask[3], mkU64(0x0000000000FF00FF));
   2463                   assign(mask[4], mkU64(0x000000000000FFFF));
   2464 
   2465                   for (i = 0; i < 5; i++) {
   2466                      nyu = newTemp(ty);
   2467                      assign(nyu,
   2468                             binop(Iop_Add64,
   2469                                   binop(Iop_And64,
   2470                                         mkexpr(old), mkexpr(mask[i])),
   2471                                   binop(Iop_And64,
   2472                                         binop(Iop_Shr64,
   2473                                               mkexpr(old), mkU8(shift[i])),
   2474                                         mkexpr(mask[i]))));
   2475                      old = nyu;
   2476                   }
   2477                } else {
   2478                   assign(mask[0], mkU32(0x55555555));
   2479                   assign(mask[1], mkU32(0x33333333));
   2480                   assign(mask[2], mkU32(0x0F0F0F0F));
   2481                   assign(mask[3], mkU32(0x00FF00FF));
   2482                   assign(mask[4], mkU32(0x0000FFFF));
   2483                   assign(old, getIReg(regRs));
   2484 
   2485                   for (i = 0; i < 5; i++) {
   2486                      nyu = newTemp(ty);
   2487                      assign(nyu,
   2488                             binop(Iop_Add32,
   2489                                   binop(Iop_And32,
   2490                                         mkexpr(old), mkexpr(mask[i])),
   2491                                   binop(Iop_And32,
   2492                                         binop(Iop_Shr32,
   2493                                               mkexpr(old), mkU8(shift[i])),
   2494                                         mkexpr(mask[i]))));
   2495                      old = nyu;
   2496                   }
   2497                }
   2498                putIReg(regRd, mkexpr(nyu));
   2499                break;
   2500             }
   2501 
   2502             /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
   2503             case 0x2d: {
   2504                int i, shift[6];
   2505                IRTemp mask[6];
   2506                IRTemp old = newTemp(ty);
   2507                IRTemp nyu = IRTemp_INVALID;
   2508                DIP("dpop r%u, r%u", regRd, regRs);
   2509 
   2510                for (i = 0; i < 6; i++) {
   2511                   mask[i] = newTemp(ty);
   2512                   shift[i] = 1 << i;
   2513                }
   2514                vassert(mode64); /*Caution! Only for Mode 64*/
   2515                assign(mask[0], mkU64(0x5555555555555555ULL));
   2516                assign(mask[1], mkU64(0x3333333333333333ULL));
   2517                assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
   2518                assign(mask[3], mkU64(0x00FF00FF00FF00FFULL));
   2519                assign(mask[4], mkU64(0x0000FFFF0000FFFFULL));
   2520                assign(mask[5], mkU64(0x00000000FFFFFFFFULL));
   2521                assign(old, getIReg(regRs));
   2522                for (i = 0; i < 6; i++) {
   2523                   nyu = newTemp(Ity_I64);
   2524                   assign(nyu,
   2525                          binop(Iop_Add64,
   2526                                binop(Iop_And64,
   2527                                      mkexpr(old), mkexpr(mask[i])),
   2528                                binop(Iop_And64,
   2529                                      binop(Iop_Shr64,
   2530                                            mkexpr(old), mkU8(shift[i])),
   2531                                      mkexpr(mask[i]))));
   2532                   old = nyu;
   2533                }
   2534                putIReg(regRd, mkexpr(nyu));
   2535                break;
   2536             }
   2537 
   2538             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
   2539                DIP("cins r%u, r%u, %u, %u\n", regRt, regRs, p, lenM1);
   2540                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2541                                      mkU8(64-( lenM1+1 ))));
   2542                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2543                                      mkU8(64-(p+lenM1+1))));
   2544                putIReg( regRt, mkexpr(tmpRt));
   2545                break;
   2546 
   2547             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
   2548                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
   2549                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2550                                      mkU8(64-( lenM1+1 ))));
   2551                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2552                                      mkU8(32-(p+lenM1+1))));
   2553                putIReg( regRt, mkexpr(tmpRt));
   2554                break;
   2555 
   2556             case 0x3A:  /* 3. EXTS rt, rs, p len */
   2557                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2558                size = lenM1 + 1;  /* lenm1+1 */
   2559                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
   2560                UChar rsAmt = 64 - size;  /* lenm1+1 */
   2561                tmp = newTemp(Ity_I64);
   2562                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   2563                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
   2564                break;
   2565 
   2566             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
   2567                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2568                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2569                                      mkU8(32-(p+lenM1+1))));
   2570                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
   2571                                      mkU8(64-(lenM1+1))) );
   2572                putIReg( regRt, mkexpr(tmpRt));
   2573                break;
   2574 
   2575             case 0x2B:  /* 20. SNE rd, rs, rt */
   2576                DIP("sne r%u, r%u, r%u", regRd,regRs, regRt);
   2577                if (mode64)
   2578                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
   2579                                                         getIReg(regRs),
   2580                                                         getIReg(regRt))));
   2581                else
   2582                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
   2583                                                        getIReg(regRs),
   2584                                                        getIReg(regRt))));
   2585                break;
   2586 
   2587             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
   2588                DIP("seq r%u, r%u, %d", regRd, regRs, regRt);
   2589                if (mode64)
   2590                   putIReg(regRd, unop(Iop_1Uto64,
   2591                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2592                                             getIReg(regRt))));
   2593                else
   2594                   putIReg(regRd, unop(Iop_1Uto32,
   2595                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2596                                             getIReg(regRt))));
   2597                break;
   2598 
   2599             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
   2600                DIP("seqi r%u, r%u, %u", regRt, regRs, imm);
   2601                if (mode64)
   2602                   putIReg(regRt, unop(Iop_1Uto64,
   2603                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2604                                             mkU64(extend_s_10to64(imm)))));
   2605                else
   2606                   putIReg(regRt, unop(Iop_1Uto32,
   2607                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2608                                             mkU32(extend_s_10to32(imm)))));
   2609                break;
   2610 
   2611             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
   2612                DIP("snei r%u, r%u, %u", regRt, regRs, imm);
   2613                if (mode64)
   2614                   putIReg(regRt, unop(Iop_1Uto64,
   2615                                    binop(Iop_CmpNE64,
   2616                                          getIReg(regRs),
   2617                                          mkU64(extend_s_10to64(imm)))));
   2618                else
   2619                   putIReg(regRt, unop(Iop_1Uto32,
   2620                                    binop(Iop_CmpNE32,
   2621                                          getIReg(regRs),
   2622                                          mkU32(extend_s_10to32(imm)))));
   2623                break;
   2624 
   2625             default:
   2626                return False;
   2627          }
   2628          break;
   2629       } /* opc1 0x1C ends here*/
   2630       case 0x1F: {
   2631          switch(opc2) {
   2632             case 0x0A: {  // lx - Load indexed instructions
   2633                switch (get_sa(theInstr)) {
   2634                   case 0x00: {  // LWX rd, index(base)
   2635                      DIP("lwx r%u, r%u(r%u)", regRd, regRt, regRs);
   2636                      LOADX_STORE_PATTERN;
   2637                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2638                                                   True));
   2639                      break;
   2640                   }
   2641                   case 0x04:  // LHX rd, index(base)
   2642                      DIP("lhx r%u, r%u(r%u)", regRd, regRt, regRs);
   2643                      LOADX_STORE_PATTERN;
   2644                      if (mode64)
   2645                         putIReg(regRd, unop(Iop_16Sto64, load(Ity_I16,
   2646                                                               mkexpr(t1))));
   2647                      else
   2648                         putIReg(regRd, unop(Iop_16Sto32, load(Ity_I16,
   2649                                                               mkexpr(t1))));
   2650                      break;
   2651                   case 0x08: {  // LDX rd, index(base)
   2652                      DIP("ldx r%u, r%u(r%u)", regRd, regRt, regRs);
   2653                      vassert(mode64); /* Currently Implemented only for n64 */
   2654                      LOADX_STORE_PATTERN;
   2655                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
   2656                      break;
   2657                   }
   2658                   case 0x06: {  // LBUX rd, index(base)
   2659                      DIP("lbux r%u, r%u(r%u)", regRd, regRt, regRs);
   2660                      LOADX_STORE_PATTERN;
   2661                      if (mode64)
   2662                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
   2663                                                              mkexpr(t1))));
   2664                      else
   2665                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
   2666                                                              mkexpr(t1))));
   2667                      break;
   2668                   }
   2669                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
   2670                      DIP("lwux r%u, r%u(r%u)", regRd, regRt, regRs);
   2671                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
   2672                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2673                                                   False));
   2674                      break;
   2675                   }
   2676                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
   2677                      DIP("lhux r%u, r%u(r%u)", regRd, regRt, regRs);
   2678                      LOADX_STORE_PATTERN;
   2679                      if (mode64)
   2680                         putIReg(regRd,
   2681                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   2682                      else
   2683                         putIReg(regRd,
   2684                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   2685                      break;
   2686                   }
   2687                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
   2688                      DIP("lbx r%u, r%u(r%u)", regRd, regRs, regRt);
   2689                      LOADX_STORE_PATTERN;
   2690                      if (mode64)
   2691                         putIReg(regRd,
   2692                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   2693                      else
   2694                         putIReg(regRd,
   2695                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   2696                      break;
   2697                   }
   2698                   default:
   2699                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
   2700                                 get_sa(theInstr));
   2701                      return False;
   2702                }
   2703                break;
   2704             }
   2705          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
   2706          break;
   2707       } /* opc1 = 0x1F ends here*/
   2708       default:
   2709          return False;
   2710    } /* main opc1 switch ends here */
   2711    return True;
   2712 }
   2713 
   2714 /*------------------------------------------------------------*/
   2715 /*---       Disassemble a single DSP ASE instruction       ---*/
   2716 /*------------------------------------------------------------*/
   2717 
   2718 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
   2719 {
   2720    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
   2721           t15, t16, t17;
   2722    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
   2723         wrdsp_mask, dsp_imm, shift;
   2724 
   2725    opcode = get_opcode(cins);
   2726    rs = get_rs(cins);
   2727    rt = get_rt(cins);
   2728    rd = get_rd(cins);
   2729    sa = get_sa(cins);
   2730    function = get_function(cins);
   2731    ac = get_acNo(cins);
   2732    ac_mfhilo = get_acNo_mfhilo(cins);
   2733    rddsp_mask = get_rddspMask(cins);
   2734    wrdsp_mask = get_wrdspMask(cins);
   2735    dsp_imm = get_dspImm(cins);
   2736    shift = get_shift(cins);
   2737 
   2738    switch (opcode) {
   2739       case 0x00: {  /* Special */
   2740          switch (function) {
   2741             case 0x10: {  /* MFHI */
   2742                DIP("mfhi ac%u r%u", ac_mfhilo, rd);
   2743                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
   2744                break;
   2745             }
   2746 
   2747             case 0x11: {  /* MTHI */
   2748                DIP("mthi ac%u r%u", ac, rs);
   2749                t1 = newTemp(Ity_I32);
   2750                assign(t1, unop(Iop_64to32, getAcc(ac)));
   2751                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
   2752                break;
   2753             }
   2754 
   2755             case 0x12: {  /* MFLO */
   2756                DIP("mflo ac%u r%u", ac_mfhilo, rd);
   2757                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
   2758                break;
   2759             }
   2760 
   2761             case 0x13: {  /* MTLO */
   2762                DIP("mtlo ac%u r%u", ac, rs);
   2763                t1 = newTemp(Ity_I32);
   2764                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
   2765                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
   2766                break;
   2767             }
   2768 
   2769             case 0x18: {  /* MULT */
   2770                DIP("mult ac%u r%u, r%u", ac, rs, rt);
   2771                t1 = newTemp(Ity_I64);
   2772                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2773                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
   2774                putAcc(ac, mkexpr(t1));
   2775                break;
   2776             }
   2777 
   2778             case 0x19: {  /* MULTU */
   2779                DIP("multu ac%u r%u, r%u", ac, rs, rt);
   2780                t1 = newTemp(Ity_I64);
   2781                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2782                                              mkNarrowTo32(Ity_I32,
   2783                                                           getIReg(rt))));
   2784                putAcc(ac, mkexpr(t1));
   2785             break;
   2786             }
   2787          }
   2788          break;
   2789       }
   2790       case 0x1C: {  /* Special2 */
   2791          switch (function) {
   2792             case 0x00: {  /* MADD */
   2793                DIP("madd ac%u, r%u, r%u", ac, rs, rt);
   2794                t1 = newTemp(Ity_I64);
   2795                t2 = newTemp(Ity_I64);
   2796                t3 = newTemp(Ity_I64);
   2797 
   2798                assign(t1, getAcc(ac));
   2799                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2800                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
   2801 
   2802                putAcc(ac, mkexpr(t3));
   2803                break;
   2804             }
   2805             case 0x01: {  /* MADDU */
   2806                DIP("maddu ac%u r%u, r%u", ac, rs, rt);
   2807                t1 = newTemp(Ity_I64);
   2808                t2 = newTemp(Ity_I64);
   2809                t3 = newTemp(Ity_I64);
   2810 
   2811                assign(t1, getAcc(ac));
   2812                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2813                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
   2814 
   2815                putAcc(ac, mkexpr(t3));
   2816                break;
   2817             }
   2818             case 0x04: {  /* MSUB */
   2819                DIP("msub ac%u r%u, r%u", ac, rs, rt);
   2820                t1 = newTemp(Ity_I64);
   2821                t2 = newTemp(Ity_I64);
   2822                t3 = newTemp(Ity_I64);
   2823 
   2824                assign(t1, getAcc(ac));
   2825                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2826                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2827 
   2828                putAcc(ac, mkexpr(t3));
   2829                break;
   2830             }
   2831             case 0x05: {  /* MSUBU */
   2832                DIP("msubu ac%u r%u, r%u", ac, rs, rt);
   2833                t1 = newTemp(Ity_I64);
   2834                t2 = newTemp(Ity_I64);
   2835                t3 = newTemp(Ity_I64);
   2836 
   2837                assign(t1, getAcc(ac));
   2838                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2839                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2840 
   2841                putAcc(ac, mkexpr(t3));
   2842                break;
   2843             }
   2844          }
   2845          break;
   2846       }
   2847       case 0x1F: {  /* Special3 */
   2848          switch (function) {
   2849             case 0x12: {  /* ABSQ_S.PH */
   2850                switch (sa) {
   2851                   case 0x1: {  /* ABSQ_S.QB */
   2852                      DIP("absq_s.qb r%u, r%u", rd, rt);
   2853                      vassert(!mode64);
   2854                      t0 = newTemp(Ity_I8);
   2855                      t1 = newTemp(Ity_I1);
   2856                      t2 = newTemp(Ity_I1);
   2857                      t3 = newTemp(Ity_I8);
   2858                      t4 = newTemp(Ity_I8);
   2859                      t5 = newTemp(Ity_I1);
   2860                      t6 = newTemp(Ity_I1);
   2861                      t7 = newTemp(Ity_I8);
   2862                      t8 = newTemp(Ity_I8);
   2863                      t9 = newTemp(Ity_I1);
   2864                      t10 = newTemp(Ity_I1);
   2865                      t11 = newTemp(Ity_I8);
   2866                      t12 = newTemp(Ity_I8);
   2867                      t13 = newTemp(Ity_I1);
   2868                      t14 = newTemp(Ity_I1);
   2869                      t15 = newTemp(Ity_I8);
   2870                      t16 = newTemp(Ity_I32);
   2871                      t17 = newTemp(Ity_I32);
   2872 
   2873                      /* Absolute value of the rightmost byte (bits 7-0). */
   2874                      /* t0 - rightmost byte. */
   2875                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
   2876                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
   2877                      assign(t1, binop(Iop_CmpEQ32,
   2878                                       unop(Iop_8Uto32, mkexpr(t0)),
   2879                                       mkU32(0x00000080)));
   2880                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2881                      assign(t2, unop(Iop_32to1,
   2882                                      binop(Iop_Shr32,
   2883                                            binop(Iop_And32,
   2884                                                  getIReg(rt),
   2885                                                  mkU32(0x00000080)),
   2886                                            mkU8(0x7))));
   2887                      /* t3 holds abs(t0). */
   2888                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2889                                            mkU8(0x7F),
   2890                                            IRExpr_ITE(mkexpr(t2),
   2891                                                       binop(Iop_Add8,
   2892                                                             unop(Iop_Not8,
   2893                                                                  mkexpr(t0)),
   2894                                                             mkU8(0x1)),
   2895                                                       mkexpr(t0))));
   2896 
   2897                      /* Absolute value of bits 15-8. */
   2898                      /* t4 - input byte. */
   2899                      assign(t4,
   2900                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
   2901                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
   2902                      assign(t5, binop(Iop_CmpEQ32,
   2903                                       unop(Iop_8Uto32, mkexpr(t4)),
   2904                                       mkU32(0x00000080)));
   2905                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2906                      assign(t6, unop(Iop_32to1,
   2907                                      binop(Iop_Shr32,
   2908                                            binop(Iop_And32,
   2909                                                  getIReg(rt),
   2910                                                  mkU32(0x00008000)),
   2911                                            mkU8(15))));
   2912                      /* t3 holds abs(t4). */
   2913                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2914                                            mkU8(0x7F),
   2915                                            IRExpr_ITE(mkexpr(t6),
   2916                                                       binop(Iop_Add8,
   2917                                                             unop(Iop_Not8,
   2918                                                                  mkexpr(t4)),
   2919                                                             mkU8(0x1)),
   2920                                                       mkexpr(t4))));
   2921 
   2922                      /* Absolute value of bits 23-15. */
   2923                      /* t8 - input byte. */
   2924                      assign(t8,
   2925                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
   2926                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
   2927                      assign(t9, binop(Iop_CmpEQ32,
   2928                                       unop(Iop_8Uto32, mkexpr(t8)),
   2929                                       mkU32(0x00000080)));
   2930                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
   2931                      assign(t10, unop(Iop_32to1,
   2932                                       binop(Iop_Shr32,
   2933                                             binop(Iop_And32,
   2934                                                   getIReg(rt),
   2935                                                   mkU32(0x00800000)),
   2936                                             mkU8(23))));
   2937                      /* t3 holds abs(t8). */
   2938                      assign(t11, IRExpr_ITE(mkexpr(t9),
   2939                                             mkU8(0x7F),
   2940                                             IRExpr_ITE(mkexpr(t10),
   2941                                                        binop(Iop_Add8,
   2942                                                              unop(Iop_Not8,
   2943                                                                   mkexpr(t8)),
   2944                                                              mkU8(0x1)),
   2945                                                        mkexpr(t8))));
   2946 
   2947                      /* Absolute value of bits 31-24. */
   2948                      /* t12 - input byte. */
   2949                      assign(t12,
   2950                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
   2951                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
   2952                      assign(t13, binop(Iop_CmpEQ32,
   2953                                        unop(Iop_8Uto32, mkexpr(t12)),
   2954                                        mkU32(0x00000080)));
   2955                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
   2956                      assign(t14, unop(Iop_32to1,
   2957                                       binop(Iop_Shr32,
   2958                                             binop(Iop_And32,
   2959                                                   getIReg(rt),
   2960                                                   mkU32(0x80000000)),
   2961                                             mkU8(31))));
   2962                      /* t15 holds abs(t12). */
   2963                      assign(t15, IRExpr_ITE(mkexpr(t13),
   2964                                             mkU8(0x7F),
   2965                                             IRExpr_ITE(mkexpr(t14),
   2966                                                        binop(Iop_Add8,
   2967                                                              unop(Iop_Not8,
   2968                                                                   mkexpr(t12)),
   2969                                                              mkU8(0x1)),
   2970                                                        mkexpr(t12))));
   2971 
   2972                      /* t16 holds !0 if any of input bytes is 0x80 or 0
   2973                         otherwise. */
   2974                      assign(t16,
   2975                             binop(Iop_Or32,
   2976                                   binop(Iop_Or32,
   2977                                         binop(Iop_Or32,
   2978                                               unop(Iop_1Sto32, mkexpr(t13)),
   2979                                               unop(Iop_1Sto32, mkexpr(t9))),
   2980                                         unop(Iop_1Sto32, mkexpr(t5))),
   2981                                   unop(Iop_1Sto32, mkexpr(t1))));
   2982 
   2983                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   2984                                                     mkexpr(t16),
   2985                                                     mkU32(0x0)),
   2986                                               getDSPControl(),
   2987                                               binop(Iop_Or32,
   2988                                                     getDSPControl(),
   2989                                                     mkU32(0x00100000))));
   2990 
   2991                      /* t17 = t15|t11|t7|t3 */
   2992                      assign(t17,
   2993                             binop(Iop_16HLto32,
   2994                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
   2995                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
   2996 
   2997                      putIReg(rd, mkexpr(t17));
   2998                      break;
   2999                   }
   3000                   case 0x2: {  /* REPL.QB */
   3001                      DIP("repl.qb r%u, %u", rd, dsp_imm);
   3002                      vassert(!mode64);
   3003 
   3004                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
   3005                                        (dsp_imm << 8) | (dsp_imm)));
   3006                      break;
   3007                   }
   3008                   case 0x3: {  /* REPLV.QB */
   3009                      DIP("replv.qb r%u, r%u", rd, rt);
   3010                      vassert(!mode64);
   3011                      t0 = newTemp(Ity_I8);
   3012 
   3013                      assign(t0, unop(Iop_32to8,
   3014                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   3015                      putIReg(rd,
   3016                              binop(Iop_16HLto32,
   3017                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
   3018                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
   3019                      break;
   3020                   }
   3021                   case 0x4: {  /* PRECEQU.PH.QBL */
   3022                      DIP("precequ.ph.qbl r%u, r%u", rd, rt);
   3023                      vassert(!mode64);
   3024 
   3025                      putIReg(rd, binop(Iop_Or32,
   3026                                        binop(Iop_Shr32,
   3027                                              binop(Iop_And32,
   3028                                                    getIReg(rt),
   3029                                                    mkU32(0xff000000)),
   3030                                              mkU8(1)),
   3031                                        binop(Iop_Shr32,
   3032                                              binop(Iop_And32,
   3033                                                    getIReg(rt),
   3034                                                    mkU32(0x00ff0000)),
   3035                                              mkU8(9))));
   3036                      break;
   3037                   }
   3038                   case 0x5: {  /* PRECEQU.PH.QBR */
   3039                      DIP("precequ.ph.qbr r%u, r%u", rd, rt);
   3040                      vassert(!mode64);
   3041 
   3042                      putIReg(rd, binop(Iop_Or32,
   3043                                        binop(Iop_Shl32,
   3044                                              binop(Iop_And32,
   3045                                                    getIReg(rt),
   3046                                                    mkU32(0x0000ff00)),
   3047                                              mkU8(15)),
   3048                                        binop(Iop_Shl32,
   3049                                              binop(Iop_And32,
   3050                                                    getIReg(rt),
   3051                                                    mkU32(0x000000ff)),
   3052                                              mkU8(7))));
   3053                      break;
   3054                   }
   3055                   case 0x6: {  /* PRECEQU.PH.QBLA */
   3056                      DIP("precequ.ph.qbla r%u, r%u", rd, rt);
   3057                      vassert(!mode64);
   3058 
   3059                      putIReg(rd, binop(Iop_Or32,
   3060                                        binop(Iop_Shr32,
   3061                                              binop(Iop_And32,
   3062                                                    getIReg(rt),
   3063                                                    mkU32(0xff000000)),
   3064                                              mkU8(1)),
   3065                                        binop(Iop_Shr32,
   3066                                              binop(Iop_And32,
   3067                                                    getIReg(rt),
   3068                                                    mkU32(0x0000ff00)),
   3069                                              mkU8(1))));
   3070                      break;
   3071                   }
   3072                   case 0x7: {  /* PRECEQU.PH.QBRA */
   3073                      DIP("precequ.ph.qbra r%u, r%u", rd, rt);
   3074                      vassert(!mode64);
   3075 
   3076                      putIReg(rd, binop(Iop_Or32,
   3077                                        binop(Iop_Shl32,
   3078                                              binop(Iop_And32,
   3079                                                    getIReg(rt),
   3080                                                    mkU32(0x00ff0000)),
   3081                                              mkU8(7)),
   3082                                        binop(Iop_Shl32,
   3083                                              binop(Iop_And32,
   3084                                                    getIReg(rt),
   3085                                                    mkU32(0x000000ff)),
   3086                                              mkU8(7))));
   3087                      break;
   3088                   }
   3089                   case 0x9: {  /* ABSQ_S.PH */
   3090                      DIP("absq_s.ph r%u, r%u", rd, rt);
   3091                      vassert(!mode64);
   3092                      t0 = newTemp(Ity_I16);
   3093                      t1 = newTemp(Ity_I1);
   3094                      t2 = newTemp(Ity_I1);
   3095                      t3 = newTemp(Ity_I16);
   3096                      t4 = newTemp(Ity_I16);
   3097                      t5 = newTemp(Ity_I1);
   3098                      t6 = newTemp(Ity_I1);
   3099                      t7 = newTemp(Ity_I16);
   3100                      t8 = newTemp(Ity_I32);
   3101                      t9 = newTemp(Ity_I32);
   3102 
   3103                      /* t0 holds lower 16 bits of value in rt. */
   3104                      assign(t0, unop(Iop_32to16, getIReg(rt)));
   3105                      /* t1 holds 1 if t0 is equal to 0x8000. */
   3106                      assign(t1, binop(Iop_CmpEQ32,
   3107                                       unop(Iop_16Uto32, mkexpr(t0)),
   3108                                       mkU32(0x00008000)));
   3109                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   3110                      assign(t2, unop(Iop_32to1,
   3111                                      binop(Iop_Shr32,
   3112                                            binop(Iop_And32,
   3113                                                  getIReg(rt),
   3114                                                  mkU32(0x00008000)),
   3115                                            mkU8(15))));
   3116                      /* t3 holds abs(t0). */
   3117                      assign(t3, IRExpr_ITE(mkexpr(t1),
   3118                                            mkU16(0x7FFF),
   3119                                            IRExpr_ITE(mkexpr(t2),
   3120                                                       binop(Iop_Add16,
   3121                                                             unop(Iop_Not16,
   3122                                                                  mkexpr(t0)),
   3123                                                             mkU16(0x1)),
   3124                                                       mkexpr(t0))));
   3125 
   3126                      /* t4 holds lower 16 bits of value in rt. */
   3127                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
   3128                      /* t5 holds 1 if t4 is equal to 0x8000. */
   3129                      assign(t5, binop(Iop_CmpEQ32,
   3130                                       unop(Iop_16Uto32, mkexpr(t4)),
   3131                                       mkU32(0x00008000)));
   3132                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   3133                      assign(t6, unop(Iop_32to1,
   3134                                      binop(Iop_Shr32,
   3135                                            binop(Iop_And32,
   3136                                                  getIReg(rt),
   3137                                                  mkU32(0x80000000)),
   3138                                            mkU8(31))));
   3139                      /* t7 holds abs(t4). */
   3140                      assign(t7, IRExpr_ITE(mkexpr(t5),
   3141                                            mkU16(0x7FFF),
   3142                                            IRExpr_ITE(mkexpr(t6),
   3143                                                       binop(Iop_Add16,
   3144                                                             unop(Iop_Not16,
   3145                                                                  mkexpr(t4)),
   3146                                                             mkU16(0x1)),
   3147                                                       mkexpr(t4))));
   3148                      /* If any of the two input halfwords is equal 0x8000,
   3149                         set bit 20 in DSPControl register. */
   3150                      assign(t8, binop(Iop_Or32,
   3151                                       unop(Iop_1Sto32, mkexpr(t5)),
   3152                                       unop(Iop_1Sto32, mkexpr(t1))));
   3153 
   3154                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   3155                                                     mkexpr(t8),
   3156                                                     mkU32(0x0)),
   3157                                               getDSPControl(),
   3158                                               binop(Iop_Or32,
   3159                                                     getDSPControl(),
   3160                                                     mkU32(0x00100000))));
   3161 
   3162                      /* t9 = t7|t3 */
   3163                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   3164 
   3165                      putIReg(rd, mkexpr(t9));
   3166                      break;
   3167                   }
   3168                   case 0xA: {  /* REPL.PH */
   3169                      DIP("repl.ph r%u, %u", rd, dsp_imm);
   3170                      vassert(!mode64);
   3171                      UShort immediate = extend_s_10to16(dsp_imm);
   3172 
   3173                      putIReg(rd, mkU32(immediate << 16 | immediate));
   3174                      break;
   3175                   }
   3176                   case 0xB: {  /* REPLV.PH */
   3177                      DIP("replv.ph r%u, r%u", rd, rt);
   3178                      vassert(!mode64);
   3179 
   3180                      putIReg(rd, binop(Iop_16HLto32,
   3181                                        unop(Iop_32to16, getIReg(rt)),
   3182                                        unop(Iop_32to16, getIReg(rt))));
   3183                      break;
   3184                   }
   3185                   case 0xC: {  /* PRECEQ.W.PHL */
   3186                      DIP("preceq.w.phl r%u, r%u", rd, rt);
   3187                      vassert(!mode64);
   3188                      putIReg(rd, binop(Iop_And32,
   3189                                        getIReg(rt),
   3190                                        mkU32(0xffff0000)));
   3191                      break;
   3192                   }
   3193                   case 0xD: {  /* PRECEQ.W.PHR */
   3194                      DIP("preceq.w.phr r%u, r%u", rd, rt);
   3195                      vassert(!mode64);
   3196                      putIReg(rd, binop(Iop_16HLto32,
   3197                                        unop(Iop_32to16, getIReg(rt)),
   3198                                        mkU16(0x0)));
   3199                      break;
   3200                   }
   3201                   case 0x11: {  /* ABSQ_S.W */
   3202                      DIP("absq_s.w r%u, r%u", rd, rt);
   3203                      vassert(!mode64);
   3204                      t0 = newTemp(Ity_I1);
   3205                      t1 = newTemp(Ity_I1);
   3206                      t2 = newTemp(Ity_I32);
   3207 
   3208                      assign(t0,
   3209                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   3210 
   3211                      putDSPControl(IRExpr_ITE(mkexpr(t0),
   3212                                               binop(Iop_Or32,
   3213                                                     getDSPControl(),
   3214                                                     mkU32(0x00100000)),
   3215                                               getDSPControl()));
   3216 
   3217                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
   3218 
   3219                      assign(t2, IRExpr_ITE(mkexpr(t0),
   3220                                            mkU32(0x7FFFFFFF),
   3221                                            IRExpr_ITE(mkexpr(t1),
   3222                                                       binop(Iop_Add32,
   3223                                                             unop(Iop_Not32,
   3224                                                                  getIReg(rt)),
   3225                                                             mkU32(0x1)),
   3226                                                       getIReg(rt))));
   3227                      putIReg(rd, mkexpr(t2));
   3228                      break;
   3229                   }
   3230                   case 0x1B: {  /* BITREV */
   3231                      DIP("bitrev r%u, r%u", rd, rt);
   3232                      vassert(!mode64);
   3233                      /* 32bit reversal as seen on Bit Twiddling Hacks site
   3234                         http://graphics.stanford.edu/~seander/bithacks.html
   3235                         section ReverseParallel */
   3236                      t1 = newTemp(Ity_I32);
   3237                      t2 = newTemp(Ity_I32);
   3238                      t3 = newTemp(Ity_I32);
   3239                      t4 = newTemp(Ity_I32);
   3240                      t5 = newTemp(Ity_I32);
   3241 
   3242                      assign(t1, binop(Iop_Or32,
   3243                                       binop(Iop_Shr32,
   3244                                             binop(Iop_And32,
   3245                                                   getIReg(rt),
   3246                                                   mkU32(0xaaaaaaaa)),
   3247                                             mkU8(0x1)),
   3248                                       binop(Iop_Shl32,
   3249                                             binop(Iop_And32,
   3250                                                   getIReg(rt),
   3251                                                   mkU32(0x55555555)),
   3252                                             mkU8(0x1))));
   3253                      assign(t2, binop(Iop_Or32,
   3254                                       binop(Iop_Shr32,
   3255                                             binop(Iop_And32,
   3256                                                   mkexpr(t1),
   3257                                                   mkU32(0xcccccccc)),
   3258                                             mkU8(0x2)),
   3259                                       binop(Iop_Shl32,
   3260                                             binop(Iop_And32,
   3261                                                   mkexpr(t1),
   3262                                                   mkU32(0x33333333)),
   3263                                             mkU8(0x2))));
   3264                      assign(t3, binop(Iop_Or32,
   3265                                       binop(Iop_Shr32,
   3266                                             binop(Iop_And32,
   3267                                                   mkexpr(t2),
   3268                                                   mkU32(0xf0f0f0f0)),
   3269                                             mkU8(0x4)),
   3270                                       binop(Iop_Shl32,
   3271                                             binop(Iop_And32,
   3272                                                   mkexpr(t2),
   3273                                                   mkU32(0x0f0f0f0f)),
   3274                                             mkU8(0x4))));
   3275                      assign(t4, binop(Iop_Or32,
   3276                                       binop(Iop_Shr32,
   3277                                             binop(Iop_And32,
   3278                                                   mkexpr(t3),
   3279                                                   mkU32(0xff00ff00)),
   3280                                             mkU8(0x8)),
   3281                                       binop(Iop_Shl32,
   3282                                             binop(Iop_And32,
   3283                                                   mkexpr(t3),
   3284                                                   mkU32(0x00ff00ff)),
   3285                                             mkU8(0x8))));
   3286                      assign(t5, binop(Iop_Or32,
   3287                                       binop(Iop_Shr32,
   3288                                             mkexpr(t4),
   3289                                             mkU8(0x10)),
   3290                                       binop(Iop_Shl32,
   3291                                             mkexpr(t4),
   3292                                             mkU8(0x10))));
   3293                      putIReg(rd, binop(Iop_Shr32,
   3294                                        mkexpr(t5),
   3295                                        mkU8(16)));
   3296                      break;
   3297                   }
   3298                   case 0x1C: {  /* PRECEU.PH.QBL */
   3299                      DIP("preceu.ph.qbl r%u, r%u", rd, rt);
   3300                      vassert(!mode64);
   3301 
   3302                      putIReg(rd, binop(Iop_Or32,
   3303                                        binop(Iop_Shr32,
   3304                                              binop(Iop_And32,
   3305                                                    getIReg(rt),
   3306                                                    mkU32(0xff000000)),
   3307                                              mkU8(8)),
   3308                                        binop(Iop_Shr32,
   3309                                              binop(Iop_And32,
   3310                                                    getIReg(rt),
   3311                                                    mkU32(0x00ff0000)),
   3312                                              mkU8(16))));
   3313                      break;
   3314                   }
   3315                   case 0x1E: {  /* PRECEU.PH.QBLA */
   3316                      DIP("preceu.ph.qbla r%u, r%u", rd, rt);
   3317                      vassert(!mode64);
   3318 
   3319                      putIReg(rd, binop(Iop_Or32,
   3320                                        binop(Iop_Shr32,
   3321                                              binop(Iop_And32,
   3322                                                    getIReg(rt),
   3323                                                    mkU32(0xff000000)),
   3324                                              mkU8(8)),
   3325                                        binop(Iop_Shr32,
   3326                                              binop(Iop_And32,
   3327                                                    getIReg(rt),
   3328                                                    mkU32(0x0000ff00)),
   3329                                              mkU8(8))));
   3330                      break;
   3331                   }
   3332                   case 0x1D: {  /* PRECEU.PH.QBR */
   3333                      DIP("preceu.ph.qbr r%u, r%u", rd, rt);
   3334                      vassert(!mode64);
   3335 
   3336                      putIReg(rd, binop(Iop_Or32,
   3337                                        binop(Iop_Shl32,
   3338                                              binop(Iop_And32,
   3339                                                    getIReg(rt),
   3340                                                    mkU32(0x0000ff00)),
   3341                                              mkU8(8)),
   3342                                        binop(Iop_And32,
   3343                                              getIReg(rt),
   3344                                              mkU32(0x000000ff))));
   3345                      break;
   3346                   }
   3347                   case 0x1F: {  /* PRECEU.PH.QBRA */
   3348                      DIP("preceu.ph.qbra r%u, r%u", rd, rt);
   3349                      vassert(!mode64);
   3350 
   3351                      putIReg(rd, binop(Iop_Or32,
   3352                                        binop(Iop_And32,
   3353                                              getIReg(rt),
   3354                                              mkU32(0x00ff0000)),
   3355                                        binop(Iop_And32,
   3356                                              getIReg(rt),
   3357                                              mkU32(0x000000ff))));
   3358                      break;
   3359                   }
   3360                   default:
   3361                      return -1;
   3362                }
   3363                break;  /* end of ABSQ_S.PH */
   3364             }
   3365             case 0x38: {  /* EXTR.W */
   3366                switch(sa) {
   3367                   case 0x0: {  /* EXTR.W */
   3368                      DIP("extr.w r%u, ac%u, %u", rt, ac, rs);
   3369                      vassert(!mode64);
   3370                      t0 = newTemp(Ity_I64);
   3371                      t1 = newTemp(Ity_I64);
   3372                      t2 = newTemp(Ity_I32);
   3373                      t3 = newTemp(Ity_I1);
   3374                      t4 = newTemp(Ity_I1);
   3375                      t5 = newTemp(Ity_I1);
   3376                      t6 = newTemp(Ity_I1);
   3377                      t7 = newTemp(Ity_I32);
   3378                      t8 = newTemp(Ity_I64);
   3379                      t9 = newTemp(Ity_I64);
   3380                      t10 = newTemp(Ity_I1);
   3381                      t11 = newTemp(Ity_I1);
   3382                      t12 = newTemp(Ity_I1);
   3383                      t13 = newTemp(Ity_I1);
   3384                      t14 = newTemp(Ity_I32);
   3385 
   3386                      assign(t0, getAcc(ac));
   3387                      if (0 == rs) {
   3388                         assign(t1, mkexpr(t0));
   3389                      } else {
   3390                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3391                      }
   3392                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3393                      assign(t3, binop(Iop_CmpNE32,
   3394                                       unop(Iop_64HIto32,
   3395                                            mkexpr(t1)),
   3396                                       mkU32(0)));
   3397                      assign(t4, binop(Iop_CmpNE32,
   3398                                       binop(Iop_And32,
   3399                                             unop(Iop_64to32,
   3400                                                  mkexpr(t1)),
   3401                                             mkU32(0x80000000)),
   3402                                       mkU32(0)));
   3403                      /* Check if bits 63..31 of the result in t1 aren't
   3404                         0x1ffffffff. */
   3405                      assign(t5, binop(Iop_CmpNE32,
   3406                                       unop(Iop_64HIto32,
   3407                                            mkexpr(t1)),
   3408                                       mkU32(0xffffffff)));
   3409                      assign(t6, binop(Iop_CmpNE32,
   3410                                       binop(Iop_And32,
   3411                                             unop(Iop_64to32,
   3412                                                  mkexpr(t1)),
   3413                                             mkU32(0x80000000)),
   3414                                       mkU32(0x80000000)));
   3415                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3416                         control register. */
   3417                      assign(t7, binop(Iop_And32,
   3418                                       binop(Iop_Or32,
   3419                                             unop(Iop_1Sto32, mkexpr(t3)),
   3420                                             unop(Iop_1Sto32, mkexpr(t4))),
   3421                                       binop(Iop_Or32,
   3422                                             unop(Iop_1Sto32, mkexpr(t5)),
   3423                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3424                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3425                                                     mkexpr(t7),
   3426                                                     mkU32(0)),
   3427                                               binop(Iop_Or32,
   3428                                                     getDSPControl(),
   3429                                                     mkU32(0x00800000)),
   3430                                               getDSPControl()));
   3431 
   3432                      /* If the last discarded bit is 1, there would be carry
   3433                         when rounding, otherwise there wouldn't. We use that
   3434                         fact and just add the value of the last discarded bit
   3435                         to the least sifgnificant bit of the shifted value
   3436                         from acc. */
   3437                      if (0 == rs) {
   3438                         assign(t8, mkU64(0x0ULL));
   3439                      } else {
   3440                         assign(t8, binop(Iop_And64,
   3441                                          binop(Iop_Shr64,
   3442                                                mkexpr(t0),
   3443                                                mkU8(rs-1)),
   3444                                          mkU64(0x1ULL)));
   3445                      }
   3446                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3447 
   3448                      /* Repeat previous steps for the rounded value. */
   3449                      assign(t10, binop(Iop_CmpNE32,
   3450                                       unop(Iop_64HIto32,
   3451                                            mkexpr(t9)),
   3452                                       mkU32(0)));
   3453                      assign(t11, binop(Iop_CmpNE32,
   3454                                       binop(Iop_And32,
   3455                                             unop(Iop_64to32,
   3456                                                  mkexpr(t9)),
   3457                                             mkU32(0x80000000)),
   3458                                       mkU32(0)));
   3459 
   3460                      assign(t12, binop(Iop_CmpNE32,
   3461                                       unop(Iop_64HIto32,
   3462                                            mkexpr(t9)),
   3463                                       mkU32(0xffffffff)));
   3464                      assign(t13, binop(Iop_CmpNE32,
   3465                                       binop(Iop_And32,
   3466                                             unop(Iop_64to32,
   3467                                                  mkexpr(t9)),
   3468                                             mkU32(0x80000000)),
   3469                                       mkU32(0x80000000)));
   3470 
   3471                      assign(t14, binop(Iop_And32,
   3472                                       binop(Iop_Or32,
   3473                                             unop(Iop_1Sto32, mkexpr(t10)),
   3474                                             unop(Iop_1Sto32, mkexpr(t11))),
   3475                                       binop(Iop_Or32,
   3476                                             unop(Iop_1Sto32, mkexpr(t12)),
   3477                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3478                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3479                                                     mkexpr(t14),
   3480                                                     mkU32(0)),
   3481                                               binop(Iop_Or32,
   3482                                                     getDSPControl(),
   3483                                                     mkU32(0x00800000)),
   3484                                               getDSPControl()));
   3485                      if (0 == rs) {
   3486                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
   3487                      } else {
   3488                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
   3489                      }
   3490                      break;
   3491                   }
   3492                   case 0x1: {  /* EXTRV.W */
   3493                      DIP("extrv.w r%u, ac%u, r%u", rt, ac, rs);
   3494                      vassert(!mode64);
   3495                      t0 = newTemp(Ity_I64);
   3496                      t1 = newTemp(Ity_I64);
   3497                      t2 = newTemp(Ity_I32);
   3498                      t3 = newTemp(Ity_I1);
   3499                      t4 = newTemp(Ity_I1);
   3500                      t5 = newTemp(Ity_I1);
   3501                      t6 = newTemp(Ity_I1);
   3502                      t7 = newTemp(Ity_I32);
   3503                      t8 = newTemp(Ity_I64);
   3504                      t9 = newTemp(Ity_I64);
   3505                      t10 = newTemp(Ity_I1);
   3506                      t11 = newTemp(Ity_I1);
   3507                      t12 = newTemp(Ity_I1);
   3508                      t13 = newTemp(Ity_I1);
   3509                      t14 = newTemp(Ity_I32);
   3510                      t15 = newTemp(Ity_I8);
   3511 
   3512                      assign(t15, unop(Iop_32to8,
   3513                                       binop(Iop_And32,
   3514                                             getIReg(rs),
   3515                                             mkU32(0x1f))));
   3516                      assign(t0, getAcc(ac));
   3517                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3518                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   3519                                                         unop(Iop_8Uto32,
   3520                                                              mkexpr(t15)),
   3521                                                         mkU32(0)),
   3522                                                   unop(Iop_64to32, mkexpr(t0)),
   3523                                                   unop(Iop_64to32, mkexpr(t1))));
   3524 
   3525                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3526                      assign(t3, binop(Iop_CmpNE32,
   3527                                       unop(Iop_64HIto32,
   3528                                            mkexpr(t1)),
   3529                                       mkU32(0)));
   3530                      assign(t4, binop(Iop_CmpNE32,
   3531                                       binop(Iop_And32,
   3532                                             unop(Iop_64to32,
   3533                                                  mkexpr(t1)),
   3534                                             mkU32(0x80000000)),
   3535                                       mkU32(0)));
   3536                      /* Check if bits 63..31 of the result in t1 aren't
   3537                         0x1ffffffff. */
   3538                      assign(t5, binop(Iop_CmpNE32,
   3539                                       unop(Iop_64HIto32,
   3540                                            mkexpr(t1)),
   3541                                       mkU32(0xffffffff)));
   3542                      assign(t6, binop(Iop_CmpNE32,
   3543                                       binop(Iop_And32,
   3544                                             unop(Iop_64to32,
   3545                                                  mkexpr(t1)),
   3546                                             mkU32(0x80000000)),
   3547                                       mkU32(0x80000000)));
   3548                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3549                         control register. */
   3550                      assign(t7, binop(Iop_And32,
   3551                                       binop(Iop_Or32,
   3552                                             unop(Iop_1Sto32, mkexpr(t3)),
   3553                                             unop(Iop_1Sto32, mkexpr(t4))),
   3554                                       binop(Iop_Or32,
   3555                                             unop(Iop_1Sto32, mkexpr(t5)),
   3556                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3557                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3558                                                     mkexpr(t7),
   3559                                                     mkU32(0)),
   3560                                               binop(Iop_Or32,
   3561                                                     getDSPControl(),
   3562                                                     mkU32(0x00800000)),
   3563                                               getDSPControl()));
   3564 
   3565                      /* If the last discarded bit is 1, there would be carry
   3566                         when rounding, otherwise there wouldn't. We use that
   3567                         fact and just add the value of the last discarded bit
   3568                         to the least sifgnificant bit of the shifted value
   3569                         from acc. */
   3570                      assign(t8,
   3571                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3572                                              unop(Iop_8Uto32,
   3573                                                   mkexpr(t15)),
   3574                                              mkU32(0)),
   3575                                        mkU64(0x0ULL),
   3576                                        binop(Iop_And64,
   3577                                              binop(Iop_Shr64,
   3578                                                    mkexpr(t0),
   3579                                                    unop(Iop_32to8,
   3580                                                         binop(Iop_Sub32,
   3581                                                               unop(Iop_8Uto32,
   3582                                                                    mkexpr(t15)),
   3583                                                                    mkU32(1)))),
   3584                                              mkU64(0x1ULL))));
   3585 
   3586                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3587 
   3588                      /* Repeat previous steps for the rounded value. */
   3589                      assign(t10, binop(Iop_CmpNE32,
   3590                                       unop(Iop_64HIto32,
   3591                                            mkexpr(t9)),
   3592                                       mkU32(0)));
   3593                      assign(t11, binop(Iop_CmpNE32,
   3594                                       binop(Iop_And32,
   3595                                             unop(Iop_64to32,
   3596                                                  mkexpr(t9)),
   3597                                             mkU32(0x80000000)),
   3598                                       mkU32(0)));
   3599 
   3600                      assign(t12, binop(Iop_CmpNE32,
   3601                                       unop(Iop_64HIto32,
   3602                                            mkexpr(t9)),
   3603                                       mkU32(0xffffffff)));
   3604                      assign(t13, binop(Iop_CmpNE32,
   3605                                       binop(Iop_And32,
   3606                                             unop(Iop_64to32,
   3607                                                  mkexpr(t9)),
   3608                                             mkU32(0x80000000)),
   3609                                       mkU32(0x80000000)));
   3610 
   3611                      assign(t14, binop(Iop_And32,
   3612                                       binop(Iop_Or32,
   3613                                             unop(Iop_1Sto32, mkexpr(t10)),
   3614                                             unop(Iop_1Sto32, mkexpr(t11))),
   3615                                       binop(Iop_Or32,
   3616                                             unop(Iop_1Sto32, mkexpr(t12)),
   3617                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3618                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3619                                                     mkexpr(t14),
   3620                                                     mkU32(0)),
   3621                                               binop(Iop_Or32,
   3622                                                     getDSPControl(),
   3623                                                     mkU32(0x00800000)),
   3624                                               getDSPControl()));
   3625                      break;
   3626                   }
   3627                   case 0x2: {  /* EXTP */
   3628                      DIP("extp r%u, ac%u, %u", rt, ac, rs);
   3629                      vassert(!mode64);
   3630                      t0 = newTemp(Ity_I64);
   3631                      t1 = newTemp(Ity_I32);
   3632                      t2 = newTemp(Ity_I1);
   3633                      t3 = newTemp(Ity_I1);
   3634                      t4 = newTemp(Ity_I8);
   3635                      t5 = newTemp(Ity_I64);
   3636                      t6 = newTemp(Ity_I64);
   3637                      t7 = newTemp(Ity_I32);
   3638 
   3639                      assign(t0, getAcc(ac));
   3640                      /* Extract pos field of DSPControl register. */
   3641                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3642 
   3643                      /* Check if (pos - size) >= 0 [size <= pos]
   3644                         if (pos < size)
   3645                            put 1 to EFI field of DSPControl register
   3646                         else
   3647                            extract bits from acc and put 0 to EFI field of
   3648                            DSPCtrl */
   3649                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   3650 
   3651                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3652                                               binop(Iop_Or32,
   3653                                                     binop(Iop_And32,
   3654                                                           getDSPControl(),
   3655                                                           mkU32(0xffffbfff)),
   3656                                                     mkU32(0x4000)),
   3657                                               binop(Iop_And32,
   3658                                                     getDSPControl(),
   3659                                                     mkU32(0xffffbfff))));
   3660 
   3661                      /* If pos <= 31, shift right the value from the acc
   3662                         (pos-size) times and take (size+1) bits from the least
   3663                         significant positions. Otherwise, shift left the value
   3664                         (63-pos) times, take (size+1) bits from the most
   3665                         significant positions and shift right (31-size) times.*/
   3666                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3667 
   3668                      assign(t4,
   3669                            IRExpr_ITE(mkexpr(t3),
   3670                                       unop(Iop_32to8,
   3671                                            binop(Iop_Sub32,
   3672                                                  mkexpr(t1), mkU32(rs))),
   3673                                       unop(Iop_32to8,
   3674                                            binop(Iop_Sub32,
   3675                                                  mkU32(63), mkexpr(t1)))));
   3676 
   3677                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3678                                            binop(Iop_Shr64,
   3679                                                  mkexpr(t0), mkexpr(t4)),
   3680                                            binop(Iop_Shl64,
   3681                                                  mkexpr(t0), mkexpr(t4))));
   3682 
   3683                      /* t6 holds a mask for bit extraction */
   3684                      assign(t6,
   3685                             IRExpr_ITE(mkexpr(t3),
   3686                                        unop(Iop_Not64,
   3687                                             binop(Iop_Shl64,
   3688                                                   mkU64(0xffffffffffffffffULL),
   3689                                                   mkU8(rs+1))),
   3690                                        unop(Iop_Not64,
   3691                                             binop(Iop_Shr64,
   3692                                                   mkU64(0xffffffffffffffffULL),
   3693                                                   mkU8(rs+1)))));
   3694 
   3695                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3696                                            unop(Iop_64to32,
   3697                                                 binop(Iop_And64,
   3698                                                       mkexpr(t5),
   3699                                                       mkexpr(t6))),
   3700                                            binop(Iop_Shr32,
   3701                                                  unop(Iop_64HIto32,
   3702                                                       binop(Iop_And64,
   3703                                                             mkexpr(t5),
   3704                                                             mkexpr(t6))),
   3705                                                  mkU8(31-rs))));
   3706 
   3707                      putIReg(rt, mkexpr(t7));
   3708                      break;
   3709                   }
   3710                   case 0x3: {  /* EXTPV */
   3711                      DIP("extpv r%u, ac%u, r%u", rt, ac, rs);
   3712                      vassert(!mode64);
   3713                      t0 = newTemp(Ity_I64);
   3714                      t1 = newTemp(Ity_I32);
   3715                      t2 = newTemp(Ity_I1);
   3716                      t3 = newTemp(Ity_I1);
   3717                      t4 = newTemp(Ity_I8);
   3718                      t5 = newTemp(Ity_I64);
   3719                      t6 = newTemp(Ity_I64);
   3720                      t7 = newTemp(Ity_I32);
   3721                      t8 = newTemp(Ity_I32);
   3722 
   3723                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   3724                      assign(t0, getAcc(ac));
   3725                      /* Extract pos field of DSPControl register. */
   3726                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3727 
   3728                      /* Check if (pos - size) >= 0 [size <= pos]
   3729                         if (pos < size)
   3730                            put 1 to EFI field of DSPControl register
   3731                         else
   3732                            extract bits from acc and put 0 to EFI field of
   3733                            DSPCtrl */
   3734                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   3735 
   3736                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3737                                               binop(Iop_Or32,
   3738                                                     binop(Iop_And32,
   3739                                                           getDSPControl(),
   3740                                                           mkU32(0xffffbfff)),
   3741                                                     mkU32(0x4000)),
   3742                                               binop(Iop_And32,
   3743                                                     getDSPControl(),
   3744                                                     mkU32(0xffffbfff))));
   3745 
   3746                      /* If pos <= 31, shift right the value from the acc
   3747                         (pos-size) times and take (size+1) bits from the least
   3748                         significant positions. Otherwise, shift left the value
   3749                         (63-pos) times, take (size+1) bits from the most
   3750                         significant positions and shift right (31-size)
   3751                         times. */
   3752                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3753 
   3754                      assign(t4,
   3755                            IRExpr_ITE(mkexpr(t3),
   3756                                       unop(Iop_32to8,
   3757                                            binop(Iop_Sub32,
   3758                                                  mkexpr(t1), mkexpr(t8))),
   3759                                       unop(Iop_32to8,
   3760                                            binop(Iop_Sub32,
   3761                                                  mkU32(63), mkexpr(t1)))));
   3762 
   3763                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3764                                            binop(Iop_Shr64,
   3765                                                  mkexpr(t0), mkexpr(t4)),
   3766                                            binop(Iop_Shl64,
   3767                                                  mkexpr(t0), mkexpr(t4))));
   3768 
   3769                      /* t6 holds a mask for bit extraction. */
   3770                      assign(t6,
   3771                             IRExpr_ITE(mkexpr(t3),
   3772                                        unop(Iop_Not64,
   3773                                             binop(Iop_Shl64,
   3774                                                   mkU64(0xffffffffffffffffULL),
   3775                                                   unop(Iop_32to8,
   3776                                                        binop(Iop_Add32,
   3777                                                              mkexpr(t8),
   3778                                                              mkU32(1))))),
   3779                                        unop(Iop_Not64,
   3780                                             binop(Iop_Shr64,
   3781                                                   mkU64(0xffffffffffffffffULL),
   3782                                                   unop(Iop_32to8,
   3783                                                        binop(Iop_Add32,
   3784                                                              mkexpr(t8),
   3785                                                              mkU32(1)))))));
   3786 
   3787                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3788                                            unop(Iop_64to32,
   3789                                                 binop(Iop_And64,
   3790                                                       mkexpr(t5),
   3791                                                       mkexpr(t6))),
   3792                                            binop(Iop_Shr32,
   3793                                                  unop(Iop_64HIto32,
   3794                                                       binop(Iop_And64,
   3795                                                             mkexpr(t5),
   3796                                                             mkexpr(t6))),
   3797                                                  unop(Iop_32to8,
   3798                                                       binop(Iop_Sub32,
   3799                                                             mkU32(31),
   3800                                                             mkexpr(t8))))));
   3801 
   3802                      putIReg(rt, mkexpr(t7));
   3803                      break;
   3804                   }
   3805                   case 0x4: {  /* EXTR_R.W */
   3806                      DIP("extr_r.w r%u, ac%u, %u", rt, ac, rs);
   3807                      vassert(!mode64);
   3808                      t0 = newTemp(Ity_I64);
   3809                      t1 = newTemp(Ity_I64);
   3810                      t2 = newTemp(Ity_I32);
   3811                      t3 = newTemp(Ity_I1);
   3812                      t4 = newTemp(Ity_I1);
   3813                      t5 = newTemp(Ity_I1);
   3814                      t6 = newTemp(Ity_I1);
   3815                      t7 = newTemp(Ity_I32);
   3816                      t8 = newTemp(Ity_I64);
   3817                      t9 = newTemp(Ity_I64);
   3818                      t10 = newTemp(Ity_I1);
   3819                      t11 = newTemp(Ity_I1);
   3820                      t12 = newTemp(Ity_I1);
   3821                      t13 = newTemp(Ity_I1);
   3822                      t14 = newTemp(Ity_I32);
   3823                      t15 = newTemp(Ity_I64);
   3824                      t16 = newTemp(Ity_I1);
   3825 
   3826                      assign(t0, getAcc(ac));
   3827                      assign(t16, binop(Iop_CmpEQ32,
   3828                                        mkU32(rs),
   3829                                        mkU32(0)));
   3830                      assign(t1, IRExpr_ITE(mkexpr(t16),
   3831                                            mkexpr(t0),
   3832                                            binop(Iop_Sar64,
   3833                                                  mkexpr(t0),
   3834                                                  mkU8(rs))));
   3835                      /* If the last discarded bit is 1, there would be carry
   3836                         when rounding, otherwise there wouldn't. We use that
   3837                         fact and just add the value of the last discarded bit
   3838                         to the least significant bit of the shifted value
   3839                         from acc. */
   3840                      assign(t15, binop(Iop_Shr64,
   3841                                        mkexpr(t0),
   3842                                        unop(Iop_32to8,
   3843                                             binop(Iop_Sub32,
   3844                                                   binop(Iop_And32,
   3845                                                         mkU32(rs),
   3846                                                         mkU32(0x1f)),
   3847                                                   mkU32(1)))));
   3848 
   3849                      assign(t8,
   3850                             IRExpr_ITE(mkexpr(t16),
   3851                                        mkU64(0x0ULL),
   3852                                        binop(Iop_And64,
   3853                                              mkexpr(t15),
   3854                                              mkU64(0x0000000000000001ULL))));
   3855                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3856                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3857 
   3858                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3859                      assign(t3, binop(Iop_CmpNE32,
   3860                                       unop(Iop_64HIto32,
   3861                                            mkexpr(t1)),
   3862                                       mkU32(0)));
   3863                      assign(t4, binop(Iop_CmpNE32,
   3864                                       binop(Iop_And32,
   3865                                             unop(Iop_64to32,
   3866                                                  mkexpr(t1)),
   3867                                             mkU32(0x80000000)),
   3868                                       mkU32(0)));
   3869 
   3870                      /* Check if bits 63..31 of the result in t1 aren't
   3871                         0x1ffffffff. */
   3872                      assign(t5, binop(Iop_CmpNE32,
   3873                                       unop(Iop_64HIto32,
   3874                                            mkexpr(t1)),
   3875                                       mkU32(0xffffffff)));
   3876                      assign(t6, binop(Iop_CmpNE32,
   3877                                       binop(Iop_And32,
   3878                                             unop(Iop_64to32,
   3879                                                  mkexpr(t1)),
   3880                                             mkU32(0x80000000)),
   3881                                       mkU32(0x80000000)));
   3882                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3883                         control register. */
   3884                      assign(t7, binop(Iop_And32,
   3885                                       binop(Iop_Or32,
   3886                                             unop(Iop_1Sto32, mkexpr(t3)),
   3887                                             unop(Iop_1Sto32, mkexpr(t4))),
   3888                                       binop(Iop_Or32,
   3889                                             unop(Iop_1Sto32, mkexpr(t5)),
   3890                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3891                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3892                                                     mkexpr(t7),
   3893                                                     mkU32(0)),
   3894                                               binop(Iop_Or32,
   3895                                                     getDSPControl(),
   3896                                                     mkU32(0x00800000)),
   3897                                               getDSPControl()));
   3898 
   3899                      /* Repeat previous steps for the rounded value. */
   3900                      assign(t10, binop(Iop_CmpNE32,
   3901                                       unop(Iop_64HIto32,
   3902                                            mkexpr(t9)),
   3903                                       mkU32(0)));
   3904                      assign(t11, binop(Iop_CmpNE32,
   3905                                       binop(Iop_And32,
   3906                                             unop(Iop_64to32,
   3907                                                  mkexpr(t9)),
   3908                                             mkU32(0x80000000)),
   3909                                       mkU32(0)));
   3910 
   3911                      assign(t12, binop(Iop_CmpNE32,
   3912                                       unop(Iop_64HIto32,
   3913                                            mkexpr(t9)),
   3914                                       mkU32(0xffffffff)));
   3915                      assign(t13, binop(Iop_CmpNE32,
   3916                                       binop(Iop_And32,
   3917                                             unop(Iop_64to32,
   3918                                                  mkexpr(t9)),
   3919                                             mkU32(0x80000000)),
   3920                                       mkU32(0x80000000)));
   3921 
   3922                      assign(t14, binop(Iop_And32,
   3923                                       binop(Iop_Or32,
   3924                                             unop(Iop_1Sto32, mkexpr(t10)),
   3925                                             unop(Iop_1Sto32, mkexpr(t11))),
   3926                                       binop(Iop_Or32,
   3927                                             unop(Iop_1Sto32, mkexpr(t12)),
   3928                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3929                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3930                                                     mkexpr(t14),
   3931                                                     mkU32(0)),
   3932                                               binop(Iop_Or32,
   3933                                                     getDSPControl(),
   3934                                                     mkU32(0x00800000)),
   3935                                               getDSPControl()));
   3936                      break;
   3937                   }
   3938                   case 0x5: {  /* EXTRV_R.W */
   3939                      DIP("extrv_r.w r%u, ac%u, r%u", rt, ac, rs);
   3940                      vassert(!mode64);
   3941                      t0 = newTemp(Ity_I64);
   3942                      t1 = newTemp(Ity_I64);
   3943                      t2 = newTemp(Ity_I32);
   3944                      t3 = newTemp(Ity_I1);
   3945                      t4 = newTemp(Ity_I1);
   3946                      t5 = newTemp(Ity_I1);
   3947                      t6 = newTemp(Ity_I1);
   3948                      t7 = newTemp(Ity_I32);
   3949                      t8 = newTemp(Ity_I64);
   3950                      t9 = newTemp(Ity_I64);
   3951                      t10 = newTemp(Ity_I1);
   3952                      t11 = newTemp(Ity_I1);
   3953                      t12 = newTemp(Ity_I1);
   3954                      t13 = newTemp(Ity_I1);
   3955                      t14 = newTemp(Ity_I32);
   3956                      t15 = newTemp(Ity_I8);
   3957 
   3958                      assign(t15, unop(Iop_32to8,
   3959                                       binop(Iop_And32,
   3960                                             getIReg(rs),
   3961                                             mkU32(0x1f))));
   3962                      assign(t0, getAcc(ac));
   3963                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3964 
   3965                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3966                      assign(t3, binop(Iop_CmpNE32,
   3967                                       unop(Iop_64HIto32,
   3968                                            mkexpr(t1)),
   3969                                       mkU32(0)));
   3970                      assign(t4, binop(Iop_CmpNE32,
   3971                                       binop(Iop_And32,
   3972                                             unop(Iop_64to32,
   3973                                                  mkexpr(t1)),
   3974                                             mkU32(0x80000000)),
   3975                                       mkU32(0)));
   3976                      /* Check if bits 63..31 of the result in t1 aren't
   3977                         0x1ffffffff. */
   3978                      assign(t5, binop(Iop_CmpNE32,
   3979                                       unop(Iop_64HIto32,
   3980                                            mkexpr(t1)),
   3981                                       mkU32(0xffffffff)));
   3982                      assign(t6, binop(Iop_CmpNE32,
   3983                                       binop(Iop_And32,
   3984                                             unop(Iop_64to32,
   3985                                                  mkexpr(t1)),
   3986                                             mkU32(0x80000000)),
   3987                                       mkU32(0x80000000)));
   3988                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3989                         control register. */
   3990                      assign(t7, binop(Iop_And32,
   3991                                       binop(Iop_Or32,
   3992                                             unop(Iop_1Sto32, mkexpr(t3)),
   3993                                             unop(Iop_1Sto32, mkexpr(t4))),
   3994                                       binop(Iop_Or32,
   3995                                             unop(Iop_1Sto32, mkexpr(t5)),
   3996                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3997                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3998                                                     mkexpr(t7),
   3999                                                     mkU32(0)),
   4000                                               binop(Iop_Or32,
   4001                                                     getDSPControl(),
   4002                                                     mkU32(0x00800000)),
   4003                                               getDSPControl()));
   4004 
   4005                      /* If the last discarded bit is 1, there would be carry
   4006                         when rounding, otherwise there wouldn't. We use that
   4007                         fact and just add the value of the last discarded bit
   4008                         to the least sifgnificant bit of the shifted value
   4009                         from acc. */
   4010                      assign(t8,
   4011                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4012                                              unop(Iop_8Uto32,
   4013                                                   mkexpr(t15)),
   4014                                              mkU32(0)),
   4015                                        mkU64(0x0ULL),
   4016                                        binop(Iop_And64,
   4017                                              binop(Iop_Shr64,
   4018                                                    mkexpr(t0),
   4019                                                    unop(Iop_32to8,
   4020                                                         binop(Iop_Sub32,
   4021                                                               unop(Iop_8Uto32,
   4022                                                                    mkexpr(t15)),
   4023                                                                    mkU32(1)))),
   4024                                              mkU64(0x1ULL))));
   4025 
   4026                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4027                      /* Put rounded value in destination register. */
   4028                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   4029 
   4030                      /* Repeat previous steps for the rounded value. */
   4031                      assign(t10, binop(Iop_CmpNE32,
   4032                                       unop(Iop_64HIto32,
   4033                                            mkexpr(t9)),
   4034                                       mkU32(0)));
   4035                      assign(t11, binop(Iop_CmpNE32,
   4036                                       binop(Iop_And32,
   4037                                             unop(Iop_64to32,
   4038                                                  mkexpr(t9)),
   4039                                             mkU32(0x80000000)),
   4040                                       mkU32(0)));
   4041 
   4042                      assign(t12, binop(Iop_CmpNE32,
   4043                                       unop(Iop_64HIto32,
   4044                                            mkexpr(t9)),
   4045                                       mkU32(0xffffffff)));
   4046                      assign(t13, binop(Iop_CmpNE32,
   4047                                       binop(Iop_And32,
   4048                                             unop(Iop_64to32,
   4049                                                  mkexpr(t9)),
   4050                                             mkU32(0x80000000)),
   4051                                       mkU32(0x80000000)));
   4052 
   4053                      assign(t14, binop(Iop_And32,
   4054                                       binop(Iop_Or32,
   4055                                             unop(Iop_1Sto32, mkexpr(t10)),
   4056                                             unop(Iop_1Sto32, mkexpr(t11))),
   4057                                       binop(Iop_Or32,
   4058                                             unop(Iop_1Sto32, mkexpr(t12)),
   4059                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4060                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4061                                                     mkexpr(t14),
   4062                                                     mkU32(0)),
   4063                                               binop(Iop_Or32,
   4064                                                     getDSPControl(),
   4065                                                     mkU32(0x00800000)),
   4066                                               getDSPControl()));
   4067                      break;
   4068                   }
   4069                   case 0x6: {  /* EXTR_RS.W */
   4070                      DIP("extr_rs.w r%u, ac%u, %u", rt, ac, rs);
   4071                      vassert(!mode64);
   4072                      t0 = newTemp(Ity_I64);
   4073                      t1 = newTemp(Ity_I64);
   4074                      t2 = newTemp(Ity_I32);
   4075                      t3 = newTemp(Ity_I1);
   4076                      t4 = newTemp(Ity_I1);
   4077                      t5 = newTemp(Ity_I1);
   4078                      t6 = newTemp(Ity_I1);
   4079                      t7 = newTemp(Ity_I32);
   4080                      t8 = newTemp(Ity_I64);
   4081                      t9 = newTemp(Ity_I64);
   4082                      t10 = newTemp(Ity_I1);
   4083                      t11 = newTemp(Ity_I1);
   4084                      t12 = newTemp(Ity_I1);
   4085                      t13 = newTemp(Ity_I1);
   4086                      t14 = newTemp(Ity_I32);
   4087                      t16 = newTemp(Ity_I32);
   4088 
   4089                      assign(t0, getAcc(ac));
   4090                      if (0 == rs) {
   4091                         assign(t1, mkexpr(t0));
   4092                      } else {
   4093                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4094                      }
   4095 
   4096                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4097                      assign(t3, binop(Iop_CmpNE32,
   4098                                       unop(Iop_64HIto32,
   4099                                            mkexpr(t1)),
   4100                                       mkU32(0)));
   4101                      assign(t4, binop(Iop_CmpNE32,
   4102                                       binop(Iop_And32,
   4103                                             unop(Iop_64to32,
   4104                                                  mkexpr(t1)),
   4105                                             mkU32(0x80000000)),
   4106                                       mkU32(0)));
   4107                      /* Check if bits 63..31 of the result in t1 aren't
   4108                         0x1ffffffff. */
   4109                      assign(t5, binop(Iop_CmpNE32,
   4110                                       unop(Iop_64HIto32,
   4111                                            mkexpr(t1)),
   4112                                       mkU32(0xffffffff)));
   4113                      assign(t6, binop(Iop_CmpNE32,
   4114                                       binop(Iop_And32,
   4115                                             unop(Iop_64to32,
   4116                                                  mkexpr(t1)),
   4117                                             mkU32(0x80000000)),
   4118                                       mkU32(0x80000000)));
   4119                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4120                         control register. */
   4121                      assign(t7, binop(Iop_And32,
   4122                                       binop(Iop_Or32,
   4123                                             unop(Iop_1Sto32, mkexpr(t3)),
   4124                                             unop(Iop_1Sto32, mkexpr(t4))),
   4125                                       binop(Iop_Or32,
   4126                                             unop(Iop_1Sto32, mkexpr(t5)),
   4127                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4128                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4129                                                     mkexpr(t7),
   4130                                                     mkU32(0)),
   4131                                               binop(Iop_Or32,
   4132                                                     getDSPControl(),
   4133                                                     mkU32(0x00800000)),
   4134                                               getDSPControl()));
   4135 
   4136                      /* If the last discarded bit is 1, there would be carry
   4137                         when rounding, otherwise there wouldn't. We use that
   4138                         fact and just add the value of the last discarded bit
   4139                         to the least sifgnificant bit of the shifted value
   4140                         from acc. */
   4141                      if (0 == rs) {
   4142                         assign(t8, mkU64(0x0ULL));
   4143                      } else {
   4144                         assign(t8, binop(Iop_And64,
   4145                                          binop(Iop_Shr64,
   4146                                                mkexpr(t0),
   4147                                                mkU8(rs-1)),
   4148                                          mkU64(0x1ULL)));
   4149                      }
   4150 
   4151                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4152 
   4153                      /* Repeat previous steps for the rounded value. */
   4154                      assign(t10, binop(Iop_CmpNE32,
   4155                                       unop(Iop_64HIto32,
   4156                                            mkexpr(t9)),
   4157                                       mkU32(0)));
   4158                      assign(t11, binop(Iop_CmpNE32,
   4159                                       binop(Iop_And32,
   4160                                             unop(Iop_64to32,
   4161                                                  mkexpr(t9)),
   4162                                             mkU32(0x80000000)),
   4163                                       mkU32(0)));
   4164 
   4165                      assign(t12, binop(Iop_CmpNE32,
   4166                                       unop(Iop_64HIto32,
   4167                                            mkexpr(t9)),
   4168                                       mkU32(0xffffffff)));
   4169                      assign(t13, binop(Iop_CmpNE32,
   4170                                       binop(Iop_And32,
   4171                                             unop(Iop_64to32,
   4172                                                  mkexpr(t9)),
   4173                                             mkU32(0x80000000)),
   4174                                       mkU32(0x80000000)));
   4175 
   4176                      assign(t14, binop(Iop_And32,
   4177                                       binop(Iop_Or32,
   4178                                             unop(Iop_1Sto32, mkexpr(t10)),
   4179                                             unop(Iop_1Sto32, mkexpr(t11))),
   4180                                       binop(Iop_Or32,
   4181                                             unop(Iop_1Sto32, mkexpr(t12)),
   4182                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4183                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4184                                                     mkexpr(t14),
   4185                                                     mkU32(0)),
   4186                                               binop(Iop_Or32,
   4187                                                     getDSPControl(),
   4188                                                     mkU32(0x00800000)),
   4189                                               getDSPControl()));
   4190 
   4191                      assign(t16, binop(Iop_And32,
   4192                                        unop(Iop_64HIto32,
   4193                                             mkexpr(t9)),
   4194                                        mkU32(0x80000000)));
   4195                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4196                                                   mkexpr(t14),
   4197                                                   mkU32(0)),
   4198                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4199                                                              mkexpr(t16),
   4200                                                              mkU32(0)),
   4201                                                        mkU32(0x7fffffff),
   4202                                                        mkU32(0x80000000)),
   4203                                             unop(Iop_64to32, mkexpr(t9))));
   4204                      break;
   4205                   }
   4206                   case 0x7: {  /* EXTRV_RS.W */
   4207                      DIP("extrv_rs.w r%u, ac%u, r%u", rt, ac, rs);
   4208                      vassert(!mode64);
   4209                      t0 = newTemp(Ity_I64);
   4210                      t1 = newTemp(Ity_I64);
   4211                      t2 = newTemp(Ity_I32);
   4212                      t3 = newTemp(Ity_I1);
   4213                      t4 = newTemp(Ity_I1);
   4214                      t5 = newTemp(Ity_I1);
   4215                      t6 = newTemp(Ity_I1);
   4216                      t7 = newTemp(Ity_I32);
   4217                      t8 = newTemp(Ity_I64);
   4218                      t9 = newTemp(Ity_I64);
   4219                      t10 = newTemp(Ity_I1);
   4220                      t11 = newTemp(Ity_I1);
   4221                      t12 = newTemp(Ity_I1);
   4222                      t13 = newTemp(Ity_I1);
   4223                      t14 = newTemp(Ity_I32);
   4224                      t15 = newTemp(Ity_I32);
   4225                      t16 = newTemp(Ity_I32);
   4226                      t17 = newTemp(Ity_I1);
   4227 
   4228                      assign(t15, binop(Iop_And32,
   4229                                        getIReg(rs),
   4230                                        mkU32(0x1f)));
   4231                      assign(t17, binop(Iop_CmpEQ32,
   4232                                        mkexpr(t15),
   4233                                        mkU32(0)));
   4234                      assign(t0, getAcc(ac));
   4235                      assign(t1, IRExpr_ITE(mkexpr(t17),
   4236                                            mkexpr(t0),
   4237                                            binop(Iop_Sar64,
   4238                                                  mkexpr(t0),
   4239                                                  unop(Iop_32to8,
   4240                                                       mkexpr(t15)))));
   4241 
   4242                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4243                      assign(t3, binop(Iop_CmpNE32,
   4244                                       unop(Iop_64HIto32,
   4245                                            mkexpr(t1)),
   4246                                       mkU32(0)));
   4247                      assign(t4, binop(Iop_CmpNE32,
   4248                                       binop(Iop_And32,
   4249                                             unop(Iop_64to32,
   4250                                                  mkexpr(t1)),
   4251                                             mkU32(0x80000000)),
   4252                                       mkU32(0)));
   4253                      /* Check if bits 63..31 of the result in t1 aren't
   4254                         0x1ffffffff. */
   4255                      assign(t5, binop(Iop_CmpNE32,
   4256                                       unop(Iop_64HIto32,
   4257                                            mkexpr(t1)),
   4258                                       mkU32(0xffffffff)));
   4259                      assign(t6, binop(Iop_CmpNE32,
   4260                                       binop(Iop_And32,
   4261                                             unop(Iop_64to32,
   4262                                                  mkexpr(t1)),
   4263                                             mkU32(0x80000000)),
   4264                                       mkU32(0x80000000)));
   4265                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4266                         control register. */
   4267                      assign(t7, binop(Iop_And32,
   4268                                       binop(Iop_Or32,
   4269                                             unop(Iop_1Sto32, mkexpr(t3)),
   4270                                             unop(Iop_1Sto32, mkexpr(t4))),
   4271                                       binop(Iop_Or32,
   4272                                             unop(Iop_1Sto32, mkexpr(t5)),
   4273                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4274                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4275                                                     mkexpr(t7),
   4276                                                     mkU32(0)),
   4277                                               binop(Iop_Or32,
   4278                                                     getDSPControl(),
   4279                                                     mkU32(0x00800000)),
   4280                                               getDSPControl()));
   4281 
   4282                      /* If the last discarded bit is 1, there would be carry
   4283                         when rounding, otherwise there wouldn't. We use that
   4284                         fact and just add the value of the last discarded bit
   4285                         to the least sifgnificant bit of the shifted value
   4286                         from acc. */
   4287                      assign(t8,
   4288                             IRExpr_ITE(mkexpr(t17),
   4289                                        mkU64(0x0ULL),
   4290                                        binop(Iop_And64,
   4291                                              binop(Iop_Shr64,
   4292                                                    mkexpr(t0),
   4293                                                    unop(Iop_32to8,
   4294                                                         binop(Iop_Sub32,
   4295                                                               mkexpr(t15),
   4296                                                               mkU32(1)))),
   4297                                              mkU64(0x1ULL))));
   4298 
   4299                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4300 
   4301                      /* Repeat previous steps for the rounded value. */
   4302                      assign(t10, binop(Iop_CmpNE32,
   4303                                       unop(Iop_64HIto32,
   4304                                            mkexpr(t9)),
   4305                                       mkU32(0)));
   4306                      assign(t11, binop(Iop_CmpNE32,
   4307                                       binop(Iop_And32,
   4308                                             unop(Iop_64to32,
   4309                                                  mkexpr(t9)),
   4310                                             mkU32(0x80000000)),
   4311                                       mkU32(0)));
   4312 
   4313                      assign(t12, binop(Iop_CmpNE32,
   4314                                       unop(Iop_64HIto32,
   4315                                            mkexpr(t9)),
   4316                                       mkU32(0xffffffff)));
   4317                      assign(t13, binop(Iop_CmpNE32,
   4318                                       binop(Iop_And32,
   4319                                             unop(Iop_64to32,
   4320                                                  mkexpr(t9)),
   4321                                             mkU32(0x80000000)),
   4322                                       mkU32(0x80000000)));
   4323 
   4324                      assign(t14, binop(Iop_And32,
   4325                                       binop(Iop_Or32,
   4326                                             unop(Iop_1Sto32, mkexpr(t10)),
   4327                                             unop(Iop_1Sto32, mkexpr(t11))),
   4328                                       binop(Iop_Or32,
   4329                                             unop(Iop_1Sto32, mkexpr(t12)),
   4330                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4331                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4332                                                     mkexpr(t14),
   4333                                                     mkU32(0)),
   4334                                               binop(Iop_Or32,
   4335                                                     getDSPControl(),
   4336                                                     mkU32(0x00800000)),
   4337                                               getDSPControl()));
   4338 
   4339                      assign(t16, binop(Iop_And32,
   4340                                        unop(Iop_64HIto32,
   4341                                             mkexpr(t9)),
   4342                                        mkU32(0x80000000)));
   4343                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4344                                                   mkexpr(t14),
   4345                                                   mkU32(0)),
   4346                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4347                                                              mkexpr(t16),
   4348                                                              mkU32(0)),
   4349                                                        mkU32(0x7fffffff),
   4350                                                        mkU32(0x80000000)),
   4351                                             unop(Iop_64to32, mkexpr(t9))));
   4352                      break;
   4353                   }
   4354                   case 0xA: {  /* EXTPDP */
   4355                      DIP("extpdp r%u, ac%u, %u", rt, ac, rs);
   4356                      vassert(!mode64);
   4357                      t0 = newTemp(Ity_I64);
   4358                      t1 = newTemp(Ity_I32);
   4359                      t2 = newTemp(Ity_I1);
   4360                      t3 = newTemp(Ity_I1);
   4361                      t4 = newTemp(Ity_I8);
   4362                      t5 = newTemp(Ity_I64);
   4363                      t6 = newTemp(Ity_I64);
   4364                      t7 = newTemp(Ity_I32);
   4365                      t8 = newTemp(Ity_I32);
   4366 
   4367                      assign(t0, getAcc(ac));
   4368                      /* Extract pos field of DSPControl register. */
   4369                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4370 
   4371                      /* Check if (pos - size) >= 0 [size <= pos]
   4372                         if (pos < size)
   4373                            put 1 to EFI field of DSPControl register
   4374                         else
   4375                            extract bits from acc and put 0 to EFI field of
   4376                            DSPCtrl */
   4377                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   4378 
   4379                      assign(t8, binop(Iop_Or32,
   4380                                       binop(Iop_And32,
   4381                                             getDSPControl(),
   4382                                             mkU32(0xffffbfc0)),
   4383                                       binop(Iop_And32,
   4384                                             binop(Iop_Sub32,
   4385                                                   binop(Iop_And32,
   4386                                                         getDSPControl(),
   4387                                                         mkU32(0x3f)),
   4388                                                   mkU32(rs+1)),
   4389                                             mkU32(0x3f))));
   4390                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4391                                               binop(Iop_Or32,
   4392                                                      binop(Iop_And32,
   4393                                                            getDSPControl(),
   4394                                                            mkU32(0xffffbfff)),
   4395                                                      mkU32(0x4000)),
   4396                                               mkexpr(t8)));
   4397 
   4398                      /* If pos <= 31, shift right the value from the acc
   4399                         (pos-size) times and take (size+1) bits from the least
   4400                         significant positions. Otherwise, shift left the value
   4401                         (63-pos) times, take (size+1) bits from the most
   4402                         significant positions and shift right (31-size) times.
   4403                      */
   4404                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4405 
   4406                      assign(t4,
   4407                             IRExpr_ITE(mkexpr(t3),
   4408                                        unop(Iop_32to8,
   4409                                             binop(Iop_Sub32,
   4410                                                   mkexpr(t1), mkU32(rs))),
   4411                                        unop(Iop_32to8,
   4412                                             binop(Iop_Sub32,
   4413                                                   mkU32(63), mkexpr(t1)))));
   4414 
   4415                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4416                                            binop(Iop_Shr64,
   4417                                                  mkexpr(t0), mkexpr(t4)),
   4418                                            binop(Iop_Shl64,
   4419                                                  mkexpr(t0), mkexpr(t4))));
   4420 
   4421                      /* t6 holds a mask for bit extraction. */
   4422                      assign(t6,
   4423                             IRExpr_ITE(mkexpr(t3),
   4424                                        unop(Iop_Not64,
   4425                                             binop(Iop_Shl64,
   4426                                                   mkU64(0xffffffffffffffffULL),
   4427                                                   mkU8(rs+1))),
   4428                                        unop(Iop_Not64,
   4429                                             binop(Iop_Shr64,
   4430                                                   mkU64(0xffffffffffffffffULL),
   4431                                                   mkU8(rs+1)))));
   4432 
   4433                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4434                                            unop(Iop_64to32,
   4435                                                 binop(Iop_And64,
   4436                                                       mkexpr(t5),
   4437                                                       mkexpr(t6))),
   4438                                            binop(Iop_Shr32,
   4439                                                  unop(Iop_64HIto32,
   4440                                                       binop(Iop_And64,
   4441                                                             mkexpr(t5),
   4442                                                             mkexpr(t6))),
   4443                                                  mkU8(31-rs))));
   4444 
   4445                      putIReg(rt, mkexpr(t7));
   4446                      break;
   4447                   }
   4448                   case 0xB: {  /* EXTPDPV */
   4449                      DIP("extpdpv r%u, ac%u, r%u", rt, ac, rs);
   4450                      vassert(!mode64);
   4451                      t0 = newTemp(Ity_I64);
   4452                      t1 = newTemp(Ity_I32);
   4453                      t2 = newTemp(Ity_I1);
   4454                      t3 = newTemp(Ity_I1);
   4455                      t4 = newTemp(Ity_I8);
   4456                      t5 = newTemp(Ity_I64);
   4457                      t6 = newTemp(Ity_I64);
   4458                      t7 = newTemp(Ity_I32);
   4459                      t8 = newTemp(Ity_I32);
   4460                      t9 = newTemp(Ity_I32);
   4461 
   4462                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   4463                      assign(t0, getAcc(ac));
   4464                      /* Extract pos field of DSPControl register. */
   4465                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4466 
   4467                      /* Check if (pos - size) >= 0 [size <= pos]
   4468                         if (pos < size)
   4469                            put 1 to EFI field of DSPControl register
   4470                         else
   4471                            extract bits from acc and put 0 to EFI field of
   4472                            DSPCtrl */
   4473                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   4474 
   4475                      assign(t9, binop(Iop_Or32,
   4476                                       binop(Iop_And32,
   4477                                             getDSPControl(),
   4478                                             mkU32(0xffffbfc0)),
   4479                                       binop(Iop_And32,
   4480                                             binop(Iop_Sub32,
   4481                                                   binop(Iop_And32,
   4482                                                         getDSPControl(),
   4483                                                         mkU32(0x3f)),
   4484                                                   binop(Iop_Add32,
   4485                                                         mkexpr(t8),
   4486                                                         mkU32(0x1))),
   4487                                             mkU32(0x3f))));
   4488                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4489                                               binop(Iop_Or32,
   4490                                                     binop(Iop_And32,
   4491                                                           getDSPControl(),
   4492                                                           mkU32(0xffffbfff)),
   4493                                                     mkU32(0x4000)),
   4494                                               mkexpr(t9)));
   4495 
   4496                      /* If pos <= 31, shift right the value from the acc
   4497                         (pos-size) times and take (size+1) bits from the least
   4498                         significant positions. Otherwise, shift left the value
   4499                         (63-pos) times, take (size+1) bits from the most
   4500                         significant positions and shift right (31-size) times.
   4501                      */
   4502                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4503 
   4504                      assign(t4,
   4505                             IRExpr_ITE(mkexpr(t3),
   4506                                       unop(Iop_32to8,
   4507                                            binop(Iop_Sub32,
   4508                                                  mkexpr(t1), mkexpr(t8))),
   4509                                       unop(Iop_32to8,
   4510                                            binop(Iop_Sub32,
   4511                                                  mkU32(63), mkexpr(t1)))));
   4512 
   4513                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4514                                            binop(Iop_Shr64,
   4515                                                  mkexpr(t0), mkexpr(t4)),
   4516                                            binop(Iop_Shl64,
   4517                                                  mkexpr(t0), mkexpr(t4))));
   4518 
   4519                      /* t6 holds a mask for bit extraction. */
   4520                      assign(t6,
   4521                             IRExpr_ITE(mkexpr(t3),
   4522                                        unop(Iop_Not64,
   4523                                             binop(Iop_Shl64,
   4524                                                   mkU64(0xffffffffffffffffULL),
   4525                                                   unop(Iop_32to8,
   4526                                                        binop(Iop_Add32,
   4527                                                              mkexpr(t8),
   4528                                                              mkU32(1))))),
   4529                                        unop(Iop_Not64,
   4530                                             binop(Iop_Shr64,
   4531                                                   mkU64(0xffffffffffffffffULL),
   4532                                                   unop(Iop_32to8,
   4533                                                        binop(Iop_Add32,
   4534                                                              mkexpr(t8),
   4535                                                              mkU32(1)))))));
   4536 
   4537                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4538                                            unop(Iop_64to32,
   4539                                                 binop(Iop_And64,
   4540                                                       mkexpr(t5),
   4541                                                       mkexpr(t6))),
   4542                                            binop(Iop_Shr32,
   4543                                                  unop(Iop_64HIto32,
   4544                                                       binop(Iop_And64,
   4545                                                             mkexpr(t5),
   4546                                                             mkexpr(t6))),
   4547                                                  unop(Iop_32to8,
   4548                                                       binop(Iop_Sub32,
   4549                                                             mkU32(31),
   4550                                                             mkexpr(t8))))));
   4551 
   4552                      putIReg(rt, mkexpr(t7));
   4553                      break;
   4554                   }
   4555                   case 0xE: {  /* EXTR_S.H */
   4556                      DIP("extr_s.h r%u, ac%u, %u", rt, ac, rs);
   4557                      vassert(!mode64);
   4558                      t0 = newTemp(Ity_I64);
   4559                      t1 = newTemp(Ity_I64);
   4560                      t2 = newTemp(Ity_I32);
   4561                      t3 = newTemp(Ity_I64);
   4562                      t4 = newTemp(Ity_I32);
   4563                      t5 = newTemp(Ity_I32);
   4564                      t6 = newTemp(Ity_I64);
   4565                      t7 = newTemp(Ity_I32);
   4566                      t9 = newTemp(Ity_I32);
   4567 
   4568                      assign(t0, getAcc(ac));
   4569 
   4570                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4571 
   4572                      assign(t2, binop(Iop_Or32,
   4573                                       getDSPControl(), mkU32(0x00800000)));
   4574 
   4575                      assign(t9, binop(Iop_And32,
   4576                                       unop(Iop_64to32,
   4577                                            mkexpr(t1)),
   4578                                       mkU32(0x80000000)));
   4579                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4580                                                     mkexpr(t9),
   4581                                                     binop(Iop_And32,
   4582                                                           unop(Iop_64HIto32,
   4583                                                                mkexpr(t0)),
   4584                                                           mkU32(0x80000000))),
   4585                                               mkexpr(t2),
   4586                                               getDSPControl()));
   4587 
   4588                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4589                         1. subtract 0x7fff from t1
   4590                         2. if the resulting number is positive (sign bit = 0)
   4591                            and any of the other bits is 1, the value is > 0. */
   4592                      assign(t3, binop(Iop_Sub64,
   4593                                       mkexpr(t1),
   4594                                       mkU64(0x0000000000007fffULL)));
   4595                      assign(t4, binop(Iop_And32,
   4596                                        binop(Iop_Or32,
   4597                                             unop(Iop_1Sto32,
   4598                                                  binop(Iop_CmpNE32,
   4599                                                        mkU32(0),
   4600                                                        binop(Iop_And32,
   4601                                                              unop(Iop_64HIto32,
   4602                                                                   mkexpr(t3)),
   4603                                                              mkU32(0x7fffffff)))),
   4604                                             unop(Iop_1Sto32,
   4605                                                  binop(Iop_CmpNE32,
   4606                                                        mkU32(0),
   4607                                                        unop(Iop_64to32,
   4608                                                             mkexpr(t3))))),
   4609                                        unop(Iop_1Sto32,
   4610                                             binop(Iop_CmpEQ32,
   4611                                                   binop(Iop_And32,
   4612                                                         unop(Iop_64HIto32,
   4613                                                                   mkexpr(t3)),
   4614                                                              mkU32(0x80000000)),
   4615                                                   mkU32(0)))));
   4616                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4617                                                     mkU32(0),
   4618                                                     mkexpr(t4)),
   4619                                               binop(Iop_Or32,
   4620                                                     getDSPControl(),
   4621                                                     mkU32(0x00800000)),
   4622                                               getDSPControl()));
   4623                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4624                         1. subtract t1 from 0xffffffffffff8000
   4625                         2. if the resulting number is positive (sign bit = 0)
   4626                             and any of the other bits is 1, the value is > 0 */
   4627                      assign(t6, binop(Iop_Sub64,
   4628                                        mkU64(0xffffffffffff8000ULL),
   4629                                        mkexpr(t1)));
   4630                      assign(t7, binop(Iop_And32,
   4631                                       binop(Iop_Or32,
   4632                                             unop(Iop_1Sto32,
   4633                                                  binop(Iop_CmpNE32,
   4634                                                        mkU32(0),
   4635                                                        binop(Iop_And32,
   4636                                                              unop(Iop_64HIto32,
   4637                                                                   mkexpr(t6)),
   4638                                                              mkU32(0x7fffffff)))),
   4639                                             unop(Iop_1Sto32,
   4640                                                  binop(Iop_CmpNE32,
   4641                                                        mkU32(0),
   4642                                                        unop(Iop_64to32,
   4643                                                             mkexpr(t6))))),
   4644                                       unop(Iop_1Sto32,
   4645                                             binop(Iop_CmpEQ32,
   4646                                                   binop(Iop_And32,
   4647                                                         unop(Iop_64HIto32,
   4648                                                                   mkexpr(t6)),
   4649                                                              mkU32(0x80000000)),
   4650                                                   mkU32(0)))));
   4651                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4652                                                     mkU32(0),
   4653                                                     mkexpr(t7)),
   4654                                               binop(Iop_Or32,
   4655                                                     getDSPControl(),
   4656                                                     mkU32(0x00800000)),
   4657                                               getDSPControl()));
   4658                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4659                                                     mkU32(0),
   4660                                                     mkexpr(t4)),
   4661                                             mkU32(0x00007fff),
   4662                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4663                                                              mkU32(0),
   4664                                                              mkexpr(t7)),
   4665                                                        mkU32(0xffff8000),
   4666                                                        unop(Iop_64to32,
   4667                                                             mkexpr(t1)))));
   4668                      break;
   4669                   }
   4670                   case 0xF: {  /* EXTRV_S.H */
   4671                      DIP("extrv_s.h r%u, ac%u, %u", rt, ac, rs);
   4672                      vassert(!mode64);
   4673                      t0 = newTemp(Ity_I64);
   4674                      t1 = newTemp(Ity_I64);
   4675                      t2 = newTemp(Ity_I32);
   4676                      t3 = newTemp(Ity_I64);
   4677                      t4 = newTemp(Ity_I32);
   4678                      t5 = newTemp(Ity_I32);
   4679                      t6 = newTemp(Ity_I64);
   4680                      t7 = newTemp(Ity_I32);
   4681                      t9 = newTemp(Ity_I32);
   4682 
   4683                      assign(t0, getAcc(ac));
   4684 
   4685                      assign(t1, binop(Iop_Sar64,
   4686                                       mkexpr(t0),
   4687                                       unop(Iop_32to8,
   4688                                            binop(Iop_And32,
   4689                                                  getIReg(rs),
   4690                                                  mkU32(0x1f)))));
   4691 
   4692                      assign(t2, binop(Iop_Or32,
   4693                                       getDSPControl(), mkU32(0x00800000)));
   4694 
   4695                      assign(t9, binop(Iop_And32,
   4696                                       unop(Iop_64to32,
   4697                                            mkexpr(t1)),
   4698                                       mkU32(0x80000000)));
   4699                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4700                                                     mkexpr(t9),
   4701                                                     binop(Iop_And32,
   4702                                                           unop(Iop_64HIto32,
   4703                                                                mkexpr(t0)),
   4704                                                           mkU32(0x80000000))),
   4705                                               mkexpr(t2),
   4706                                               getDSPControl()));
   4707 
   4708                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4709                         1. subtract 0x7fff from t1
   4710                         2. if the resulting number is positive (sign bit = 0)
   4711                            and any of the other bits is 1, the value is > 0. */
   4712                      assign(t3, binop(Iop_Sub64,
   4713                                       mkexpr(t1),
   4714                                       mkU64(0x0000000000007fffULL)));
   4715                      assign(t4, binop(Iop_And32,
   4716                                        binop(Iop_Or32,
   4717                                             unop(Iop_1Sto32,
   4718                                                  binop(Iop_CmpNE32,
   4719                                                        mkU32(0),
   4720                                                        binop(Iop_And32,
   4721                                                              unop(Iop_64HIto32,
   4722                                                                   mkexpr(t3)),
   4723                                                              mkU32(0x7fffffff)))),
   4724                                             unop(Iop_1Sto32,
   4725                                                  binop(Iop_CmpNE32,
   4726                                                        mkU32(0),
   4727                                                        unop(Iop_64to32,
   4728                                                             mkexpr(t3))))),
   4729                                        unop(Iop_1Sto32,
   4730                                             binop(Iop_CmpEQ32,
   4731                                                   binop(Iop_And32,
   4732                                                         unop(Iop_64HIto32,
   4733                                                                   mkexpr(t3)),
   4734                                                              mkU32(0x80000000)),
   4735                                                   mkU32(0)))));
   4736                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4737                                                     mkU32(0),
   4738                                                     mkexpr(t4)),
   4739                                               binop(Iop_Or32,
   4740                                                     getDSPControl(),
   4741                                                     mkU32(0x00800000)),
   4742                                               getDSPControl()));
   4743                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4744                         1. subtract t1 from 0xffffffffffff8000
   4745                         2. if the resulting number is positive (sign bit = 0)
   4746                             and any of the other bits is 1, the value is > 0 */
   4747                      assign(t6, binop(Iop_Sub64,
   4748                                        mkU64(0xffffffffffff8000ULL),
   4749                                        mkexpr(t1)));
   4750                      assign(t7, binop(Iop_And32,
   4751                                       binop(Iop_Or32,
   4752                                             unop(Iop_1Sto32,
   4753                                                  binop(Iop_CmpNE32,
   4754                                                        mkU32(0),
   4755                                                        binop(Iop_And32,
   4756                                                              unop(Iop_64HIto32,
   4757                                                                   mkexpr(t6)),
   4758                                                              mkU32(0x7fffffff)))),
   4759                                             unop(Iop_1Sto32,
   4760                                                  binop(Iop_CmpNE32,
   4761                                                        mkU32(0),
   4762                                                        unop(Iop_64to32,
   4763                                                             mkexpr(t6))))),
   4764                                       unop(Iop_1Sto32,
   4765                                             binop(Iop_CmpEQ32,
   4766                                                   binop(Iop_And32,
   4767                                                         unop(Iop_64HIto32,
   4768                                                                   mkexpr(t6)),
   4769                                                              mkU32(0x80000000)),
   4770                                                   mkU32(0)))));
   4771                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4772                                                     mkU32(0),
   4773                                                     mkexpr(t7)),
   4774                                               binop(Iop_Or32,
   4775                                                     getDSPControl(),
   4776                                                     mkU32(0x00800000)),
   4777                                               getDSPControl()));
   4778                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4779                                                     mkU32(0),
   4780                                                     mkexpr(t4)),
   4781                                             mkU32(0x00007fff),
   4782                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4783                                                              mkU32(0),
   4784                                                              mkexpr(t7)),
   4785                                                        mkU32(0xffff8000),
   4786                                                        unop(Iop_64to32,
   4787                                                             mkexpr(t1)))));
   4788                      break;
   4789                   }
   4790                   case 0x12: {  /* RDDSP*/
   4791                      DIP("rddsp r%u, mask 0x%x", rd, rddsp_mask);
   4792                      vassert(!mode64);
   4793 
   4794                      putIReg(rd, mkU32(0x0));
   4795 
   4796                      if ((rddsp_mask & 0x1) == 0x1) {
   4797                         /* Read pos field (bits 5-0) of DSPControl register. */
   4798                         putIReg(rd, binop(Iop_Or32,
   4799                                           getIReg(rd),
   4800                                           binop(Iop_And32,
   4801                                                 getDSPControl(),
   4802                                                 mkU32(0x0000003F))));
   4803                      }
   4804 
   4805                      if ((rddsp_mask & 0x2) == 0x2) {
   4806                         /* Read scount field (bits 12-7) of DSPControl
   4807                            register. */
   4808                         putIReg(rd, binop(Iop_Or32,
   4809                                           getIReg(rd),
   4810                                           binop(Iop_And32,
   4811                                                 getDSPControl(),
   4812                                                 mkU32(0x00001F80))));
   4813                      }
   4814 
   4815                      if ((rddsp_mask & 0x4) == 0x4) {
   4816                         /* Read C field (bit 13) of DSPControl register. */
   4817                         putIReg(rd, binop(Iop_Or32,
   4818                                           getIReg(rd),
   4819                                           binop(Iop_And32,
   4820                                                 getDSPControl(),
   4821                                                 mkU32(0x00002000))));
   4822                      }
   4823 
   4824                      if ((rddsp_mask & 0x8) == 0x8) {
   4825                         /* Read outflag field (bit s 23-16) of DSPControl
   4826                            register. */
   4827                         putIReg(rd, binop(Iop_Or32,
   4828                                           getIReg(rd),
   4829                                           binop(Iop_And32,
   4830                                                 getDSPControl(),
   4831                                                 mkU32(0x00FF0000))));
   4832                      }
   4833 
   4834                      if ((rddsp_mask & 0x10) == 0x10) {
   4835                         /* Read ccond field (bits 31-24) of DSPControl
   4836                            register. */
   4837                         putIReg(rd, binop(Iop_Or32,
   4838                                           getIReg(rd),
   4839                                           binop(Iop_And32,
   4840                                                 getDSPControl(),
   4841                                                 mkU32(0xFF000000))));
   4842                      }
   4843 
   4844                      if ((rddsp_mask & 0x20) == 0x20) {
   4845                         /* Read EFI field (bit 14) of DSPControl register. */
   4846                         putIReg(rd, binop(Iop_Or32,
   4847                                           getIReg(rd),
   4848                                           binop(Iop_And32,
   4849                                                 getDSPControl(),
   4850                                                 mkU32(0x00004000))));
   4851                      }
   4852 
   4853                      if ((rddsp_mask & 0x3f) == 0x3f) {
   4854                         /* Read all fields of DSPControl register. */
   4855                         putIReg(rd, getDSPControl());
   4856                      }
   4857                      break;
   4858                   }
   4859                   case 0x13: {  /* WRDSP */
   4860                      DIP("wrdsp r%u, mask 0x%x", rs, wrdsp_mask);
   4861                      vassert(!mode64);
   4862 
   4863                      if ((wrdsp_mask & 0x3f) == 0x3f) {
   4864                         /* If mips64 put all fields of rs, except bit 15 and bit
   4865                            6, to DSPControl register, otherwise put all except
   4866                            bits 15, 6 and bits 31..28. */
   4867                         putDSPControl(mode64 ?
   4868                                       binop(Iop_And32,
   4869                                             getIReg(rs),
   4870                                             mkU32(0xffff7fbf)) :
   4871                                       binop(Iop_And32,
   4872                                             getIReg(rs),
   4873                                             mkU32(0x0fff7fbf)));
   4874                      } else {
   4875                         if ((wrdsp_mask & 0x1) == 0x1) {
   4876                            /* Put bits 5-0 of rs to DSPControl register pos
   4877                               field. */
   4878                            putDSPControl(binop(Iop_Or32,
   4879                                                binop(Iop_And32,
   4880                                                      getDSPControl(),
   4881                                                      mkU32(0xFFFF7F40)),
   4882                                                binop(Iop_And32,
   4883                                                      getIReg(rs),
   4884                                                      mkU32(0x0000003F))));
   4885                         }
   4886 
   4887                         if ((wrdsp_mask & 0x2) == 0x2) {
   4888                            /* Put bits 12-7 of rs to DSPControl scount field. */
   4889                            putDSPControl(binop(Iop_Or32,
   4890                                                binop(Iop_And32,
   4891                                                      getDSPControl(),
   4892                                                      mkU32(0xFFFFE03F)),
   4893                                                binop(Iop_And32,
   4894                                                      getIReg(rs),
   4895                                                      mkU32(0x00001F80))));
   4896                         }
   4897 
   4898                         if ((wrdsp_mask & 0x4) == 0x4) {
   4899                            /* Put bit 13 of rs to DSPControl register C
   4900                               field. */
   4901                            putDSPControl(binop(Iop_Or32,
   4902                                                binop(Iop_And32,
   4903                                                      getDSPControl(),
   4904                                                      mkU32(0xFFFF5FBF)),
   4905                                                binop(Iop_And32,
   4906                                                      getIReg(rs),
   4907                                                      mkU32(0x00002000))));
   4908                         }
   4909 
   4910                         if ((wrdsp_mask & 0x8) == 0x8) {
   4911                            /* Put bits 23-16 of rs to DSPControl reg outflag
   4912                               field. */
   4913                            putDSPControl(binop(Iop_Or32,
   4914                                                binop(Iop_And32,
   4915                                                      getDSPControl(),
   4916                                                      mkU32(0xFF007FBF)),
   4917                                                binop(Iop_And32,
   4918                                                      getIReg(rs),
   4919                                                      mkU32(0x00FF0000))));
   4920                         }
   4921 
   4922                         if ((wrdsp_mask & 0x10) == 0x10) {
   4923                            /* Put bits 31-24 of rs to DSPControl reg ccond
   4924                               field. */
   4925                            putDSPControl(binop(Iop_Or32,
   4926                                                binop(Iop_And32,
   4927                                                      getDSPControl(),
   4928                                                      mkU32(0x00FF7FBF)),
   4929                                                binop(Iop_And32,
   4930                                                      getIReg(rs),
   4931                                                      mode64 ? mkU32(0xFF000000)
   4932                                                             : mkU32(0x0F000000))
   4933                                                )
   4934                                         );
   4935                         }
   4936 
   4937                         if ((wrdsp_mask & 0x20) == 0x20) {
   4938                            /* Put bit 14 of rs to DSPControl register EFI
   4939                               field. */
   4940                            putDSPControl(binop(Iop_Or32,
   4941                                                binop(Iop_And32,
   4942                                                      getDSPControl(),
   4943                                                      mkU32(0xFFFF3FBF)),
   4944                                                binop(Iop_And32,
   4945                                                      getIReg(rs),
   4946                                                      mkU32(0x00004000))));
   4947                         }
   4948                      }
   4949                      break;
   4950                   }
   4951                   case 0x1A: {  /* SHILO */
   4952                      DIP("shilo ac%u, %u", ac, shift);
   4953                      vassert(!mode64);
   4954                      t0 = newTemp(Ity_I64);
   4955                      t1 = newTemp(Ity_I64);
   4956 
   4957                      assign(t0, getAcc(ac));
   4958 
   4959                      putAcc(ac, mkexpr(t0));
   4960 
   4961                      if (0x20 == (shift & 0x3f)) {
   4962                         putAcc(ac, binop(Iop_32HLto64,
   4963                                          unop(Iop_64to32, mkexpr(t0)),
   4964                                          mkU32(0x0)));
   4965                      } else if (0x20 == (shift & 0x20)) {
   4966                         assign(t1, binop(Iop_Shl64,
   4967                                          mkexpr(t0),
   4968                                          unop(Iop_32to8,
   4969                                               binop(Iop_Add32,
   4970                                                     unop(Iop_Not32,
   4971                                                          mkU32(shift)),
   4972                                                     mkU32(0x1)))));
   4973 
   4974                         putAcc(ac, mkexpr(t1));
   4975                      } else {
   4976                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
   4977 
   4978                         putAcc(ac, mkexpr(t1));
   4979                      }
   4980                      break;
   4981                   }
   4982                   case 0x1B: {  /* SHILOV */
   4983                      DIP("shilov ac%u, r%u", ac, rs);
   4984                      vassert(!mode64);
   4985                      t0 = newTemp(Ity_I64);
   4986                      t1 = newTemp(Ity_I32);
   4987                      t2 = newTemp(Ity_I1);
   4988                      t3 = newTemp(Ity_I64);
   4989                      t4 = newTemp(Ity_I64);
   4990 
   4991                      assign(t0, getAcc(ac));
   4992                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
   4993                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
   4994                      assign(t3, binop(Iop_Shl64,
   4995                                       mkexpr(t0),
   4996                                       unop(Iop_32to8,
   4997                                            binop(Iop_Add32,
   4998                                                  unop(Iop_Not32,
   4999                                                       mkexpr(t1)),
   5000                                                  mkU32(0x1)))));
   5001                      assign(t4, binop(Iop_Shr64,
   5002                                       mkexpr(t0),
   5003                                       unop(Iop_32to8,
   5004                                            mkexpr(t1))));
   5005 
   5006                      putAcc(ac,
   5007                             IRExpr_ITE(mkexpr(t2),
   5008                                        binop(Iop_32HLto64,
   5009                                              unop(Iop_64to32, mkexpr(t0)),
   5010                                              mkU32(0x0)),
   5011                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   5012                                                         binop(Iop_And32,
   5013                                                               mkexpr(t1),
   5014                                                               mkU32(0x20)),
   5015                                                         mkU32(0x20)),
   5016                                                   mkexpr(t3),
   5017                                                   mkexpr(t4))));
   5018                      break;
   5019                   }
   5020                   case 0x1F: {  /* MTHLIP */
   5021                      DIP("mthlip r%u, ac%u", rs, ac);
   5022                      vassert(!mode64);
   5023                      t0 = newTemp(Ity_I64);
   5024                      t1 = newTemp(Ity_I32);
   5025                      t2 = newTemp(Ity_I32);
   5026                      t3 = newTemp(Ity_I1);
   5027 
   5028                      assign(t0, getAcc(ac));
   5029                      putAcc(ac, binop(Iop_32HLto64,
   5030                                       unop(Iop_64to32, mkexpr(t0)),
   5031                                       getIReg(rs)));
   5032                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5033                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
   5034                                                     mkU32(32),
   5035                                                     mkexpr(t1)),
   5036                                               binop(Iop_Or32,
   5037                                                     binop(Iop_Sub32,
   5038                                                           mkexpr(t1),
   5039                                                           mkU32(32)),
   5040                                                    binop(Iop_And32,
   5041                                                          getDSPControl(),
   5042                                                          mkU32(0xffffffc0))),
   5043                                               binop(Iop_Or32,
   5044                                                     binop(Iop_Add32,
   5045                                                           mkexpr(t1),
   5046                                                           mkU32(32)),
   5047                                                     binop(Iop_And32,
   5048                                                           getDSPControl(),
   5049                                                           mkU32(0xffffffc0)))));
   5050                      break;
   5051                   }
   5052                   default:
   5053                      return -1;
   5054                }
   5055                break;  /* end of EXTR.W */
   5056             }
   5057             case 0xA: {  /* LX */
   5058                switch(sa) {
   5059                   case 0x0: {  /* LWX */
   5060                      DIP("lwx r%u, r%u(r%u)", rd, rt, rs);
   5061                      vassert(!mode64);
   5062                      t0 = newTemp(Ity_I32);
   5063 
   5064                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5065 
   5066                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
   5067                      break;
   5068                   }
   5069                   case 0x4: {  /* LHX */
   5070                      DIP("lhx r%u, r%u(r%u)", rd, rt, rs);
   5071                      vassert(!mode64);
   5072                      t0 = newTemp(Ity_I32);
   5073 
   5074                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5075 
   5076                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
   5077                      break;
   5078                   }
   5079                   case 0x6: {  /* LBUX */
   5080                      DIP("lbux r%u, r%u(r%u)", rd, rt, rs);
   5081                      vassert(!mode64);
   5082                      t0 = newTemp(Ity_I32);
   5083 
   5084                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5085 
   5086                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
   5087                      break;
   5088                   }
   5089                   default:
   5090                      return -1;
   5091                }
   5092                break;  /* end of LX */
   5093             }
   5094             case 0xC: {  /* INSV */
   5095                switch(sa) {
   5096                   case 0x0: {  /* INSV */
   5097                      DIP("insv r%u, r%u", rt, rs);
   5098                      vassert(!mode64);
   5099 
   5100                      t0 = newTemp(Ity_I32);
   5101                      t1 = newTemp(Ity_I32);
   5102                      t2 = newTemp(Ity_I8);
   5103                      t3 = newTemp(Ity_I8);
   5104                      t4 = newTemp(Ity_I32);
   5105                      t5 = newTemp(Ity_I1);
   5106                      t6 = newTemp(Ity_I32);
   5107                      t7 = newTemp(Ity_I32);
   5108                      t8 = newTemp(Ity_I32);
   5109                      t9 = newTemp(Ity_I32);
   5110 
   5111                      /* t0 <- pos field of DSPControl register. */
   5112                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5113                      /* t1 <- scount field of DSPControl register. */
   5114                      assign(t1, binop(Iop_Shr32,
   5115                                       binop(Iop_And32,
   5116                                             getDSPControl(),
   5117                                             mkU32(0x1f80)),
   5118                                       mkU8(7)));
   5119 
   5120                      assign(t2, unop(Iop_32to8,
   5121                                      binop(Iop_Add32,
   5122                                            mkexpr(t1),
   5123                                            mkexpr(t0))));
   5124 
   5125                      /* 32-(pos+size) most significant bits of rt. */
   5126                      assign(t6, binop(Iop_Shl32,
   5127                                       binop(Iop_Shr32,
   5128                                             getIReg(rt),
   5129                                             mkexpr(t2)),
   5130                                       mkexpr(t2)));
   5131 
   5132                      assign(t3, unop(Iop_32to8,
   5133                                      binop(Iop_Sub32,
   5134                                            mkU32(32),
   5135                                            mkexpr(t0))));
   5136                      /* Pos least significant bits of rt. */
   5137                      assign(t7, binop(Iop_Shr32,
   5138                                       binop(Iop_Shl32,
   5139                                             getIReg(rt),
   5140                                             mkexpr(t3)),
   5141                                       mkexpr(t3)));
   5142 
   5143                      /* Size least significant bits of rs,
   5144                         shifted to appropriate position. */
   5145                      assign(t8, binop(Iop_Shl32,
   5146                                       binop(Iop_And32,
   5147                                             getIReg(rs),
   5148                                             unop(Iop_Not32,
   5149                                                  binop(Iop_Shl32,
   5150                                                        mkU32(0xffffffff),
   5151                                                        unop(Iop_32to8,
   5152                                                             mkexpr(t1))))),
   5153                                       unop(Iop_32to8,
   5154                                            mkexpr(t0))));
   5155 
   5156                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   5157                                                   mkexpr(t0),
   5158                                                   mkU32(0)),
   5159                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5160                                                              mkexpr(t1),
   5161                                                              mkU32(32)),
   5162                                                        getIReg(rs),
   5163                                                        binop(Iop_Or32,
   5164                                                              mkexpr(t6),
   5165                                                              mkexpr(t8))),
   5166                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5167                                                              unop(Iop_8Uto32,
   5168                                                                   mkexpr(t2)),
   5169                                                              mkU32(32)),
   5170                                                        binop(Iop_Or32,
   5171                                                              mkexpr(t7),
   5172                                                              mkexpr(t8)),
   5173                                                        binop(Iop_Or32,
   5174                                                              binop(Iop_Or32,
   5175                                                                    mkexpr(t6),
   5176                                                                    mkexpr(t7)),
   5177                                                              mkexpr(t8)))));
   5178                      break;
   5179                   }
   5180                   default:
   5181                      return -1;
   5182                }
   5183                break;  /* enf of INSV */
   5184             }
   5185             case 0x10: {  /* ADDU.QB */
   5186                switch(sa) {
   5187                   case 0x00: {  /* ADDU.QB */
   5188                      DIP("addu.qb r%u, r%u, r%u", rd, rs, rt);
   5189                      vassert(!mode64);
   5190                      t0 = newTemp(Ity_I32);
   5191                      t1 = newTemp(Ity_I1);
   5192                      t2 = newTemp(Ity_I32);
   5193                      t3 = newTemp(Ity_I1);
   5194                      t4 = newTemp(Ity_I32);
   5195                      t5 = newTemp(Ity_I1);
   5196                      t6 = newTemp(Ity_I32);
   5197                      t7 = newTemp(Ity_I1);
   5198                      t8 = newTemp(Ity_I32);
   5199 
   5200                      /* Add rightmost bytes of rs and rt. */
   5201                      assign(t0,
   5202                             binop(Iop_Add32,
   5203                                   unop(Iop_8Uto32,
   5204                                        unop(Iop_16to8,
   5205                                             unop(Iop_32to16, getIReg(rs)))),
   5206                                   unop(Iop_8Uto32,
   5207                                        unop(Iop_16to8,
   5208                                             unop(Iop_32to16, getIReg(rt))))));
   5209                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5210                      assign(t1, binop(Iop_CmpEQ32,
   5211                                       binop(Iop_And32,
   5212                                             mkexpr(t0),
   5213                                             mkU32(0x00000100)),
   5214                                       mkU32(0x00000100)));
   5215 
   5216                      /* Add bits 15-8 of rs and rt. */
   5217                      assign(t2,
   5218                             binop(Iop_Add32,
   5219                                   unop(Iop_8Uto32,
   5220                                        unop(Iop_16HIto8,
   5221                                             unop(Iop_32to16, getIReg(rs)))),
   5222                                   unop(Iop_8Uto32,
   5223                                        unop(Iop_16HIto8,
   5224                                             unop(Iop_32to16, getIReg(rt))))));
   5225                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5226                      assign(t3, binop(Iop_CmpEQ32,
   5227                                       binop(Iop_And32,
   5228                                             mkexpr(t2),
   5229                                             mkU32(0x00000100)),
   5230                                       mkU32(0x00000100)));
   5231 
   5232                      /* Add bits 15-8 of rs and rt. */
   5233                      assign(t4,
   5234                             binop(Iop_Add32,
   5235                                   unop(Iop_8Uto32,
   5236                                        unop(Iop_16to8,
   5237                                             unop(Iop_32HIto16, getIReg(rs)))),
   5238                                   unop(Iop_8Uto32,
   5239                                        unop(Iop_16to8,
   5240                                             unop(Iop_32HIto16, getIReg(rt))))));
   5241                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5242                      assign(t5, binop(Iop_CmpEQ32,
   5243                                       binop(Iop_And32,
   5244                                             mkexpr(t4),
   5245                                             mkU32(0x00000100)),
   5246                                       mkU32(0x00000100)));
   5247 
   5248                      /* Add bits 15-8 of rs and rt. */
   5249                      assign(t6,
   5250                             binop(Iop_Add32,
   5251                                   unop(Iop_8Uto32,
   5252                                        unop(Iop_16HIto8,
   5253                                             unop(Iop_32HIto16, getIReg(rs)))),
   5254                                   unop(Iop_8Uto32,
   5255                                        unop(Iop_16HIto8,
   5256                                             unop(Iop_32HIto16, getIReg(rt))))));
   5257                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5258                      assign(t7, binop(Iop_CmpEQ32,
   5259                                       binop(Iop_And32,
   5260                                             mkexpr(t6),
   5261                                             mkU32(0x00000100)),
   5262                                       mkU32(0x00000100)));
   5263 
   5264                      assign(t8,
   5265                             binop(Iop_Or32,
   5266                                   binop(Iop_Or32,
   5267                                         binop(Iop_Or32,
   5268                                               unop(Iop_1Sto32, mkexpr(t7)),
   5269                                               unop(Iop_1Sto32,  mkexpr(t5))),
   5270                                         unop(Iop_1Sto32, mkexpr(t3))),
   5271                                   unop(Iop_1Sto32, mkexpr(t1))));
   5272 
   5273                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5274                                                     mkexpr(t8),
   5275                                                     mkU32(0x0)),
   5276                                               getDSPControl(),
   5277                                               binop(Iop_Or32,
   5278                                                     getDSPControl(),
   5279                                                     mkU32(0x00100000))));
   5280 
   5281                      putIReg(rd, binop(Iop_16HLto32,
   5282                                        binop(Iop_8HLto16,
   5283                                              unop(Iop_32to8, mkexpr(t6)),
   5284                                              unop(Iop_32to8, mkexpr(t4))),
   5285                                        binop(Iop_8HLto16,
   5286                                              unop(Iop_32to8, mkexpr(t2)),
   5287                                              unop(Iop_32to8, mkexpr(t0)))));
   5288                      break;
   5289                   }
   5290                   case 0x1: {  /* SUBU.QB */
   5291                      DIP("subu.qb r%u, r%u, r%u", rd, rs, rt);
   5292                      vassert(!mode64);
   5293                      t0 = newTemp(Ity_I32);
   5294                      t1 = newTemp(Ity_I1);
   5295                      t2 = newTemp(Ity_I32);
   5296                      t3 = newTemp(Ity_I1);
   5297                      t4 = newTemp(Ity_I32);
   5298                      t5 = newTemp(Ity_I1);
   5299                      t6 = newTemp(Ity_I32);
   5300                      t7 = newTemp(Ity_I1);
   5301                      t8 = newTemp(Ity_I32);
   5302 
   5303                      /* Subtract rightmost bytes of rs and rt. */
   5304                      assign(t0,
   5305                             binop(Iop_Sub32,
   5306                                   unop(Iop_8Uto32,
   5307                                        unop(Iop_16to8,
   5308                                             unop(Iop_32to16, getIReg(rs)))),
   5309                                   unop(Iop_8Uto32,
   5310                                        unop(Iop_16to8,
   5311                                             unop(Iop_32to16, getIReg(rt))))));
   5312                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5313                      assign(t1, binop(Iop_CmpEQ32,
   5314                                       binop(Iop_And32,
   5315                                             mkexpr(t0),
   5316                                             mkU32(0x00000100)),
   5317                                       mkU32(0x00000100)));
   5318 
   5319                      /* Subtract bits 15-8 of rs and rt. */
   5320                      assign(t2,
   5321                             binop(Iop_Sub32,
   5322                                   unop(Iop_8Uto32,
   5323                                        unop(Iop_16HIto8,
   5324                                             unop(Iop_32to16, getIReg(rs)))),
   5325                                   unop(Iop_8Uto32,
   5326                                        unop(Iop_16HIto8,
   5327                                             unop(Iop_32to16, getIReg(rt))))));
   5328                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5329                      assign(t3, binop(Iop_CmpEQ32,
   5330                                       binop(Iop_And32,
   5331                                             mkexpr(t2),
   5332                                             mkU32(0x00000100)),
   5333                                       mkU32(0x00000100)));
   5334 
   5335                      /* Subtract bits 15-8 of rs and rt. */
   5336                      assign(t4,
   5337                             binop(Iop_Sub32,
   5338                                   unop(Iop_8Uto32,
   5339                                        unop(Iop_16to8,
   5340                                             unop(Iop_32HIto16, getIReg(rs)))),
   5341                                   unop(Iop_8Uto32,
   5342                                        unop(Iop_16to8,
   5343                                             unop(Iop_32HIto16, getIReg(rt))))));
   5344                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5345                      assign(t5, binop(Iop_CmpEQ32,
   5346                                       binop(Iop_And32,
   5347                                             mkexpr(t4),
   5348                                             mkU32(0x00000100)),
   5349                                       mkU32(0x00000100)));
   5350 
   5351                      /* Subtract bits 15-8 of rs and rt. */
   5352                      assign(t6,
   5353                             binop(Iop_Sub32,
   5354                                   unop(Iop_8Uto32,
   5355                                        unop(Iop_16HIto8,
   5356                                             unop(Iop_32HIto16, getIReg(rs)))),
   5357                                   unop(Iop_8Uto32,
   5358                                        unop(Iop_16HIto8,
   5359                                             unop(Iop_32HIto16, getIReg(rt))))));
   5360                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5361                      assign(t7, binop(Iop_CmpEQ32,
   5362                                       binop(Iop_And32,
   5363                                             mkexpr(t6),
   5364                                             mkU32(0x00000100)),
   5365                                       mkU32(0x00000100)));
   5366 
   5367                      assign(t8, binop(Iop_Or32,
   5368                                       binop(Iop_Or32,
   5369                                             binop(Iop_Or32,
   5370                                                   unop(Iop_1Sto32, mkexpr(t7)),
   5371                                                   unop(Iop_1Sto32, mkexpr(t5))),
   5372                                             unop(Iop_1Sto32, mkexpr(t3))),
   5373                                       unop(Iop_1Sto32, mkexpr(t1))));
   5374 
   5375                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5376                                                      mkexpr(t8),
   5377                                                      mkU32(0x0)),
   5378                                               getDSPControl(),
   5379                                               binop(Iop_Or32,
   5380                                                     getDSPControl(),
   5381                                                     mkU32(0x00100000))));
   5382 
   5383                      putIReg(rd, binop(Iop_16HLto32,
   5384                                        binop(Iop_8HLto16,
   5385                                              unop(Iop_32to8, mkexpr(t6)),
   5386                                              unop(Iop_32to8, mkexpr(t4))),
   5387                                        binop(Iop_8HLto16,
   5388                                              unop(Iop_32to8, mkexpr(t2)),
   5389                                              unop(Iop_32to8, mkexpr(t0)))));
   5390                      break;
   5391                   }
   5392                   case 0x04: {  /* ADDU_S.QB */
   5393                      DIP("addu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5394                      vassert(!mode64);
   5395                      t0 = newTemp(Ity_I32);
   5396                      t1 = newTemp(Ity_I1);
   5397                      t2 = newTemp(Ity_I8);
   5398                      t3 = newTemp(Ity_I32);
   5399                      t4 = newTemp(Ity_I1);
   5400                      t5 = newTemp(Ity_I8);
   5401                      t6 = newTemp(Ity_I32);
   5402                      t7 = newTemp(Ity_I1);
   5403                      t8 = newTemp(Ity_I8);
   5404                      t9 = newTemp(Ity_I32);
   5405                      t10 = newTemp(Ity_I1);
   5406                      t11 = newTemp(Ity_I8);
   5407                      t12 = newTemp(Ity_I32);
   5408 
   5409                      /* Add rightmost bytes of rs and rt. */
   5410                      assign(t0,
   5411                             binop(Iop_Add32,
   5412                                   unop(Iop_8Uto32,
   5413                                        unop(Iop_16to8,
   5414                                             unop(Iop_32to16, getIReg(rs)))),
   5415                                   unop(Iop_8Uto32,
   5416                                        unop(Iop_16to8,
   5417                                             unop(Iop_32to16, getIReg(rt))))));
   5418                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5419                      assign(t1, binop(Iop_CmpEQ32,
   5420                                       binop(Iop_And32,
   5421                                             mkexpr(t0),
   5422                                             mkU32(0x00000100)),
   5423                                       mkU32(0x00000100)));
   5424                      /* Saturate if necessary. */
   5425                      assign(t2, IRExpr_ITE(mkexpr(t1),
   5426                                            mkU8(0xff),
   5427                                            unop(Iop_32to8, mkexpr(t0))));
   5428 
   5429                      /* Add bits 15-8 of rs and rt. */
   5430                      assign(t3,
   5431                             binop(Iop_Add32,
   5432                                   unop(Iop_8Uto32,
   5433                                        unop(Iop_16HIto8,
   5434                                             unop(Iop_32to16, getIReg(rs)))),
   5435                                   unop(Iop_8Uto32,
   5436                                        unop(Iop_16HIto8,
   5437                                             unop(Iop_32to16, getIReg(rt))))));
   5438                      /* t4 will be 1 if there is overflow, 0 otherwise. */
   5439                      assign(t4, binop(Iop_CmpEQ32,
   5440                                       binop(Iop_And32,
   5441                                             mkexpr(t3),
   5442                                             mkU32(0x00000100)),
   5443                                       mkU32(0x00000100)));
   5444                      /* Saturate if necessary. */
   5445                      assign(t5, IRExpr_ITE(mkexpr(t4),
   5446                                            mkU8(0xff),
   5447                                            unop(Iop_32to8, mkexpr(t3))));
   5448 
   5449                      /* Add bits 15-8 of rs and rt. */
   5450                      assign(t6,
   5451                             binop(Iop_Add32,
   5452                                   unop(Iop_8Uto32,
   5453                                        unop(Iop_16to8,
   5454                                             unop(Iop_32HIto16, getIReg(rs)))),
   5455                                   unop(Iop_8Uto32,
   5456                                        unop(Iop_16to8,
   5457                                             unop(Iop_32HIto16, getIReg(rt))))));
   5458                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5459                      assign(t7, binop(Iop_CmpEQ32,
   5460                                       binop(Iop_And32,
   5461                                             mkexpr(t6),
   5462                                             mkU32(0x00000100)),
   5463                                       mkU32(0x00000100)));
   5464                      /* Saturate if necessary. */
   5465                      assign(t8, IRExpr_ITE(mkexpr(t7),
   5466                                            mkU8(0xff),
   5467                                            unop(Iop_32to8, mkexpr(t6))));
   5468 
   5469                      /* Add bits 15-8 of rs and rt. */
   5470                      assign(t9,
   5471                             binop(Iop_Add32,
   5472                                   unop(Iop_8Uto32,
   5473                                        unop(Iop_16HIto8,
   5474                                             unop(Iop_32HIto16, getIReg(rs)))),
   5475                                   unop(Iop_8Uto32,
   5476                                        unop(Iop_16HIto8,
   5477                                             unop(Iop_32HIto16, getIReg(rt))))));
   5478                      /* t10 will be 1 if there is overflow, 0 otherwise. */
   5479                      assign(t10, binop(Iop_CmpEQ32,
   5480                                        binop(Iop_And32,
   5481                                              mkexpr(t9),
   5482                                              mkU32(0x00000100)),
   5483                                        mkU32(0x00000100)));
   5484                      /* Saturate if necessary. */
   5485                      assign(t11, IRExpr_ITE(mkexpr(t10),
   5486                                             mkU8(0xff),
   5487                                             unop(Iop_32to8, mkexpr(t9))));
   5488 
   5489                      assign(t12,
   5490                             binop(Iop_Or32,
   5491                                   binop(Iop_Or32,
   5492                                         binop(Iop_Or32,
   5493                                               unop(Iop_1Sto32, mkexpr(t10)),
   5494                                               unop(Iop_1Sto32, mkexpr(t7))),
   5495                                         unop(Iop_1Sto32, mkexpr(t4))),
   5496                                   unop(Iop_1Sto32, mkexpr(t1))));
   5497 
   5498                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5499                                                     mkexpr(t12),
   5500                                                     mkU32(0x0)),
   5501                                               getDSPControl(),
   5502                                               binop(Iop_Or32,
   5503                                                     getDSPControl(),
   5504                                                     mkU32(0x00100000))));
   5505 
   5506                      putIReg(rd,
   5507                              binop(Iop_16HLto32,
   5508                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
   5509                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
   5510                      break;
   5511                   }
   5512                   case 0x05: {  /* SUBU_S.QB */
   5513                      DIP("subu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5514                      vassert(!mode64);
   5515                      t1 = newTemp(Ity_I32);
   5516                      t2 = newTemp(Ity_I1);
   5517                      t3 = newTemp(Ity_I1);
   5518                      t4 = newTemp(Ity_I1);
   5519                      t5 = newTemp(Ity_I1);
   5520                      t6 = newTemp(Ity_I32);
   5521                      t7 = newTemp(Ity_I32);
   5522                      t8 = newTemp(Ity_I32);
   5523                      t9 = newTemp(Ity_I32);
   5524 
   5525                      /* Use C function to easily calculate the result
   5526                         and write it in the register more conveniently
   5527                         Underflow is checked using step by step subtraction. */
   5528                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
   5529 
   5530                      /* Subtract each byte of rs and rt. */
   5531                      assign(t6,
   5532                             binop(Iop_Sub32,
   5533                                   unop(Iop_8Uto32,
   5534                                        unop(Iop_16to8,
   5535                                             unop(Iop_32to16, getIReg(rs)))),
   5536                                   unop(Iop_8Uto32,
   5537                                        unop(Iop_16to8,
   5538                                             unop(Iop_32to16, getIReg(rt))))));
   5539                      assign(t7,
   5540                             binop(Iop_Sub32,
   5541                                   unop(Iop_8Uto32,
   5542                                        unop(Iop_16HIto8,
   5543                                             unop(Iop_32to16, getIReg(rs)))),
   5544                                   unop(Iop_8Uto32,
   5545                                        unop(Iop_16HIto8,
   5546                                             unop(Iop_32to16, getIReg(rt))))));
   5547                      assign(t8,
   5548                             binop(Iop_Sub32,
   5549                                   unop(Iop_8Uto32,
   5550                                        unop(Iop_16to8,
   5551                                             unop(Iop_32HIto16, getIReg(rs)))),
   5552                                   unop(Iop_8Uto32,
   5553                                        unop(Iop_16to8,
   5554                                             unop(Iop_32HIto16, getIReg(rt))))));
   5555                      assign(t9,
   5556                             binop(Iop_Sub32,
   5557                                   unop(Iop_8Uto32,
   5558                                        unop(Iop_16HIto8,
   5559                                             unop(Iop_32HIto16, getIReg(rs)))),
   5560                                   unop(Iop_8Uto32,
   5561                                        unop(Iop_16HIto8,
   5562                                             unop(Iop_32HIto16, getIReg(rt))))));
   5563 
   5564                      /* Put 1 to bit 20 in DSPControl if there is underflow
   5565                         in either byte. */
   5566                      assign(t2, binop(Iop_CmpEQ32,
   5567                                       binop(Iop_And32,
   5568                                             mkexpr(t6),
   5569                                             mkU32(0x00000100)),
   5570                                       mkU32(0x00000100)));
   5571                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5572                                               binop(Iop_Or32,
   5573                                                     getDSPControl(),
   5574                                                     mkU32(0x00100000)),
   5575                                               getDSPControl()));
   5576                      assign(t3, binop(Iop_CmpEQ32,
   5577                                       binop(Iop_And32,
   5578                                             mkexpr(t7),
   5579                                             mkU32(0x00000100)),
   5580                                       mkU32(0x00000100)));
   5581                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5582                                               binop(Iop_Or32,
   5583                                                     getDSPControl(),
   5584                                                     mkU32(0x00100000)),
   5585                                               getDSPControl()));
   5586                      assign(t4, binop(Iop_CmpEQ32,
   5587                                       binop(Iop_And32,
   5588                                             mkexpr(t8),
   5589                                             mkU32(0x00000100)),
   5590                                       mkU32(0x00000100)));
   5591                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5592                                               binop(Iop_Or32,
   5593                                                     getDSPControl(),
   5594                                                     mkU32(0x00100000)),
   5595                                               getDSPControl()));
   5596                      assign(t5, binop(Iop_CmpEQ32,
   5597                                       binop(Iop_And32,
   5598                                             mkexpr(t9),
   5599                                             mkU32(0x00000100)),
   5600                                       mkU32(0x00000100)));
   5601                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   5602                                               binop(Iop_Or32,
   5603                                                     getDSPControl(),
   5604                                                     mkU32(0x00100000)),
   5605                                               getDSPControl()));
   5606                      putIReg(rd, mkexpr(t1));
   5607                      break;
   5608                   }
   5609                   case 0x6: {  /* MULEU_S.PH.QBL */
   5610                      DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd, rs, rt);
   5611                      vassert(!mode64);
   5612                      t0 = newTemp(Ity_I32);
   5613                      t1 = newTemp(Ity_I32);
   5614                      t2 = newTemp(Ity_I1);
   5615                      t3 = newTemp(Ity_I1);
   5616 
   5617                      assign(t0,
   5618                             unop(Iop_64to32,
   5619                                  binop(Iop_MullU32,
   5620                                        unop(Iop_8Uto32,
   5621                                             unop(Iop_16HIto8,
   5622                                                  unop(Iop_32HIto16,
   5623                                                       getIReg(rs)))),
   5624                                        unop(Iop_16Uto32,
   5625                                             unop(Iop_32HIto16, getIReg(rt))))));
   5626                      assign(t1,
   5627                             unop(Iop_64to32,
   5628                                  binop(Iop_MullU32,
   5629                                        unop(Iop_8Uto32,
   5630                                             unop(Iop_16to8,
   5631                                                  unop(Iop_32HIto16,
   5632                                                       getIReg(rs)))),
   5633                                        unop(Iop_16Uto32,
   5634                                             unop(Iop_32to16, getIReg(rt))))));
   5635 
   5636                      assign(t2, binop(Iop_CmpNE32,
   5637                                       mkU32(0x0),
   5638                                       binop(Iop_And32,
   5639                                             mkexpr(t0),
   5640                                             mkU32(0x03ff0000))));
   5641                      assign(t3, binop(Iop_CmpNE32,
   5642                                       mkU32(0x0),
   5643                                       binop(Iop_And32,
   5644                                             mkexpr(t1),
   5645                                             mkU32(0x03ff0000))));
   5646                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5647                                               binop(Iop_Or32,
   5648                                                     getDSPControl(),
   5649                                                     mkU32(0x200000)),
   5650                                               IRExpr_ITE(mkexpr(t3),
   5651                                                          binop(Iop_Or32,
   5652                                                                getDSPControl(),
   5653                                                                mkU32(0x200000)),
   5654                                                          getDSPControl())));
   5655                      putIReg(rd,
   5656                              binop(Iop_16HLto32,
   5657                                    IRExpr_ITE(mkexpr(t2),
   5658                                               mkU16(0xffff),
   5659                                               unop(Iop_32to16, mkexpr(t0))),
   5660                                    IRExpr_ITE(mkexpr(t3),
   5661                                               mkU16(0xffff),
   5662                                               unop(Iop_32to16, mkexpr(t1)))));
   5663                      break;
   5664                   }
   5665                   case 0x7: {  /* MULEU_S.PH.QBR */
   5666                      DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd, rs, rt);
   5667                      vassert(!mode64);
   5668                      t0 = newTemp(Ity_I32);
   5669                      t1 = newTemp(Ity_I32);
   5670                      t2 = newTemp(Ity_I1);
   5671                      t3 = newTemp(Ity_I1);
   5672 
   5673                      assign(t0, unop(Iop_64to32,
   5674                                      binop(Iop_MullU32,
   5675                                            unop(Iop_8Uto32,
   5676                                                 unop(Iop_16HIto8,
   5677                                                      unop(Iop_32to16,
   5678                                                           getIReg(rs)))),
   5679                                            unop(Iop_16Uto32,
   5680                                                 unop(Iop_32HIto16,
   5681                                                      getIReg(rt))))));
   5682                      assign(t1, unop(Iop_64to32,
   5683                                      binop(Iop_MullU32,
   5684                                            unop(Iop_8Uto32,
   5685                                                 unop(Iop_16to8,
   5686                                                      unop(Iop_32to16,
   5687                                                           getIReg(rs)))),
   5688                                            unop(Iop_16Uto32,
   5689                                                 unop(Iop_32to16,
   5690                                                      getIReg(rt))))));
   5691 
   5692                      assign(t2, binop(Iop_CmpNE32,
   5693                                       mkU32(0x0),
   5694                                       binop(Iop_And32,
   5695                                             mkexpr(t0),
   5696                                             mkU32(0x03ff0000))));
   5697                      assign(t3, binop(Iop_CmpNE32,
   5698                                       mkU32(0x0),
   5699                                       binop(Iop_And32,
   5700                                             mkexpr(t1),
   5701                                             mkU32(0x03ff0000))));
   5702                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5703                                               binop(Iop_Or32,
   5704                                                     getDSPControl(),
   5705                                                     mkU32(0x200000)),
   5706                                               IRExpr_ITE(mkexpr(t3),
   5707                                                          binop(Iop_Or32,
   5708                                                                getDSPControl(),
   5709                                                                mkU32(0x200000)),
   5710                                                          getDSPControl())));
   5711                      putIReg(rd, binop(Iop_16HLto32,
   5712                                        IRExpr_ITE(mkexpr(t2),
   5713                                                   mkU16(0xffff),
   5714                                                   unop(Iop_32to16,
   5715                                                        mkexpr(t0))),
   5716                                        IRExpr_ITE(mkexpr(t3),
   5717                                                   mkU16(0xffff),
   5718                                                   unop(Iop_32to16,
   5719                                                        mkexpr(t1)))));
   5720                      break;
   5721                   }
   5722                   case 0x08: {  /* ADDU.PH */
   5723                      DIP("addu.ph r%u, r%u, r%u", rd, rs, rt);
   5724                      vassert(!mode64);
   5725                      t0 = newTemp(Ity_I32);
   5726                      t1 = newTemp(Ity_I1);
   5727                      t2 = newTemp(Ity_I32);
   5728                      t3 = newTemp(Ity_I1);
   5729 
   5730                      /* Add lower halves. */
   5731                      assign(t0, binop(Iop_Add32,
   5732                                       unop(Iop_16Uto32,
   5733                                            unop(Iop_32to16, getIReg(rs))),
   5734                                       unop(Iop_16Uto32,
   5735                                            unop(Iop_32to16, getIReg(rt)))));
   5736 
   5737                      /* Detect overflow. */
   5738                      assign(t1, binop(Iop_CmpLT32U,
   5739                                       unop(Iop_16Uto32,
   5740                                            unop(Iop_32to16, mkexpr(t0))),
   5741                                       unop(Iop_16Uto32,
   5742                                            unop(Iop_32to16, getIReg(rs)))));
   5743 
   5744                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5745                                               binop(Iop_Or32,
   5746                                                     getDSPControl(),
   5747                                                     mkU32(0x00100000)),
   5748                                               getDSPControl()));
   5749 
   5750                      /* Add higher halves. */
   5751                      assign(t2, binop(Iop_Add32,
   5752                                       unop(Iop_16Uto32,
   5753                                            unop(Iop_32HIto16, getIReg(rs))),
   5754                                       unop(Iop_16Uto32,
   5755                                            unop(Iop_32HIto16, getIReg(rt)))));
   5756 
   5757                      /* Detect overflow. */
   5758                      assign(t3, binop(Iop_CmpLT32U,
   5759                                       unop(Iop_16Uto32,
   5760                                            unop(Iop_32to16, mkexpr(t2))),
   5761                                       unop(Iop_16Uto32,
   5762                                            unop(Iop_32HIto16,
   5763                                                 getIReg(rs)))));
   5764 
   5765                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5766                                               binop(Iop_Or32,
   5767                                                     getDSPControl(),
   5768                                                     mkU32(0x00100000)),
   5769                                               getDSPControl()));
   5770 
   5771                      putIReg(rd, binop(Iop_16HLto32,
   5772                                        unop(Iop_32to16, mkexpr(t2)),
   5773                                        unop(Iop_32to16, mkexpr(t0))));
   5774                      break;
   5775                   }
   5776                   case 0x9: {  /* SUBU.PH */
   5777                      DIP("subu.ph r%u, r%u, r%u", rd, rs, rt);
   5778                      vassert(!mode64);
   5779                      t0 = newTemp(Ity_I32);
   5780                      t1 = newTemp(Ity_I1);
   5781                      t2 = newTemp(Ity_I32);
   5782                      t3 = newTemp(Ity_I1);
   5783 
   5784                      /* Substract lower halves. */
   5785                      assign(t0, binop(Iop_Sub32,
   5786                                       unop(Iop_16Uto32,
   5787                                            unop(Iop_32to16, getIReg(rs))),
   5788                                       unop(Iop_16Uto32,
   5789                                            unop(Iop_32to16, getIReg(rt)))));
   5790 
   5791                      /* Detect underflow. */
   5792                      assign(t1, binop(Iop_CmpNE32,
   5793                                       binop(Iop_And32,
   5794                                             mkexpr(t0),
   5795                                             mkU32(0x00010000)),
   5796                                       mkU32(0x0)));
   5797 
   5798                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5799                                               binop(Iop_Or32,
   5800                                                     getDSPControl(),
   5801                                                     mkU32(0x00100000)),
   5802                                               getDSPControl()));
   5803 
   5804                      /* Subtract higher halves. */
   5805                      assign(t2, binop(Iop_Sub32,
   5806                                       unop(Iop_16Uto32,
   5807                                            unop(Iop_32HIto16, getIReg(rs))),
   5808                                       unop(Iop_16Uto32,
   5809                                            unop(Iop_32HIto16, getIReg(rt)))));
   5810 
   5811                      /* Detect underflow. */
   5812                      assign(t3, binop(Iop_CmpNE32,
   5813                                       binop(Iop_And32,
   5814                                             mkexpr(t2),
   5815                                             mkU32(0x00010000)),
   5816                                       mkU32(0x0)));
   5817 
   5818                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5819                                               binop(Iop_Or32,
   5820                                                     getDSPControl(),
   5821                                                     mkU32(0x00100000)),
   5822                                               getDSPControl()));
   5823 
   5824                      putIReg(rd, binop(Iop_16HLto32,
   5825                                        unop(Iop_32to16, mkexpr(t2)),
   5826                                        unop(Iop_32to16, mkexpr(t0))));
   5827                      break;
   5828                   }
   5829                   case 0xA: {  /* ADDQ.PH */
   5830                      DIP("addq.ph r%u, r%u, r%u", rd, rs, rt);
   5831                      vassert(!mode64);
   5832                      t0 = newTemp(Ity_I32);
   5833                      t1 = newTemp(Ity_I1);
   5834                      t2 = newTemp(Ity_I32);
   5835                      t3 = newTemp(Ity_I1);
   5836                      t6 = newTemp(Ity_I32);
   5837                      t7 = newTemp(Ity_I32);
   5838 
   5839                      /* Add lower halves. */
   5840                      assign(t0, binop(Iop_Add32,
   5841                                       unop(Iop_16Sto32,
   5842                                            unop(Iop_32to16, getIReg(rs))),
   5843                                       unop(Iop_16Sto32,
   5844                                            unop(Iop_32to16, getIReg(rt)))));
   5845 
   5846                      /* Bit 16 of the result. */
   5847                      assign(t6, binop(Iop_And32,
   5848                                       unop(Iop_16Uto32,
   5849                                            unop(Iop_32HIto16, mkexpr(t0))),
   5850                                       mkU32(0x1)));
   5851                      /* Detect overflow. */
   5852                      assign(t1, binop(Iop_CmpNE32,
   5853                                       binop(Iop_Shr32,
   5854                                             binop(Iop_And32,
   5855                                                   mkexpr(t0),
   5856                                                   mkU32(0x8000)),
   5857                                             mkU8(15)),
   5858                                       mkexpr(t6)));
   5859 
   5860                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5861                                               binop(Iop_Or32,
   5862                                                     getDSPControl(),
   5863                                                     mkU32(0x00100000)),
   5864                                               getDSPControl()));
   5865 
   5866                      /* Add higher halves. */
   5867                      assign(t2, binop(Iop_Add32,
   5868                                       unop(Iop_16Sto32,
   5869                                            unop(Iop_32HIto16, getIReg(rs))),
   5870                                       unop(Iop_16Sto32,
   5871                                            unop(Iop_32HIto16, getIReg(rt)))));
   5872 
   5873                      /* Bit 16 of the result. */
   5874                      assign(t7, binop(Iop_And32,
   5875                                       unop(Iop_16Uto32,
   5876                                            unop(Iop_32HIto16, mkexpr(t2))),
   5877                                       mkU32(0x1)));
   5878                      /* Detect overflow. */
   5879                      assign(t3, binop(Iop_CmpNE32,
   5880                                       binop(Iop_Shr32,
   5881                                             binop(Iop_And32,
   5882                                                   mkexpr(t2),
   5883                                                   mkU32(0x00008000)),
   5884                                             mkU8(15)),
   5885                                       mkexpr(t7)));
   5886 
   5887                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5888                                               binop(Iop_Or32,
   5889                                                     getDSPControl(),
   5890                                                     mkU32(0x00100000)),
   5891                                               getDSPControl()));
   5892 
   5893                      putIReg(rd, binop(Iop_16HLto32,
   5894                                        unop(Iop_32to16, mkexpr(t2)),
   5895                                        unop(Iop_32to16, mkexpr(t0))));
   5896                      break;
   5897                   }
   5898                   case 0xB: {  /* SUBQ.PH */
   5899                      DIP("subq.ph r%u, r%u, r%u", rd, rs, rt);
   5900                      vassert(!mode64);
   5901                      t0 = newTemp(Ity_I32);
   5902                      t1 = newTemp(Ity_I1);
   5903                      t2 = newTemp(Ity_I32);
   5904                      t3 = newTemp(Ity_I1);
   5905                      t6 = newTemp(Ity_I32);
   5906                      t7 = newTemp(Ity_I32);
   5907 
   5908                      /* Subtract lower halves. */
   5909                      assign(t0, binop(Iop_Sub32,
   5910                                       unop(Iop_16Sto32,
   5911                                            unop(Iop_32to16, getIReg(rs))),
   5912                                       unop(Iop_16Sto32,
   5913                                            unop(Iop_32to16, getIReg(rt)))));
   5914 
   5915                      /* Bit 16 of the result. */
   5916                      assign(t6, binop(Iop_And32,
   5917                                       unop(Iop_16Uto32,
   5918                                            unop(Iop_32HIto16, mkexpr(t0))),
   5919                                       mkU32(0x1)));
   5920                      /* Compare the signs of input value and the result. */
   5921                      assign(t1, binop(Iop_CmpNE32,
   5922                                       binop(Iop_Shr32,
   5923                                             binop(Iop_And32,
   5924                                                   mkexpr(t0),
   5925                                                   mkU32(0x8000)),
   5926                                             mkU8(15)),
   5927                                       mkexpr(t6)));
   5928 
   5929                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5930                                               binop(Iop_Or32,
   5931                                                     getDSPControl(),
   5932                                                     mkU32(0x00100000)),
   5933                                               getDSPControl()));
   5934 
   5935                      /* Subtract higher halves. */
   5936                      assign(t2, binop(Iop_Sub32,
   5937                                       unop(Iop_16Sto32,
   5938                                            unop(Iop_32HIto16, getIReg(rs))),
   5939                                       unop(Iop_16Sto32,
   5940                                            unop(Iop_32HIto16, getIReg(rt)))));
   5941 
   5942                      /* Bit 16 of the result. */
   5943                      assign(t7, binop(Iop_And32,
   5944                                       unop(Iop_16Uto32,
   5945                                            unop(Iop_32HIto16, mkexpr(t2))),
   5946                                       mkU32(0x1)));
   5947                      /* Compare the signs of input value and the result. */
   5948                      assign(t3, binop(Iop_CmpNE32,
   5949                                       binop(Iop_Shr32,
   5950                                             binop(Iop_And32,
   5951                                                   mkexpr(t2),
   5952                                                   mkU32(0x00008000)),
   5953                                             mkU8(15)),
   5954                                       mkexpr(t7)));
   5955 
   5956                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5957                                               binop(Iop_Or32,
   5958                                                     getDSPControl(),
   5959                                                     mkU32(0x00100000)),
   5960                                               getDSPControl()));
   5961 
   5962                      putIReg(rd, binop(Iop_16HLto32,
   5963                                        unop(Iop_32to16, mkexpr(t2)),
   5964                                        unop(Iop_32to16, mkexpr(t0))));
   5965                      break;
   5966                   }
   5967                   case 0xC: {  /* ADDU_S.PH */
   5968                      DIP("addu_s.ph r%u, r%u, r%u", rd, rs, rt);
   5969                      vassert(!mode64);
   5970                      t0 = newTemp(Ity_I32);
   5971                      t1 = newTemp(Ity_I1);
   5972                      t2 = newTemp(Ity_I32);
   5973                      t3 = newTemp(Ity_I1);
   5974 
   5975                      /* Add lower halves. */
   5976                      assign(t0, binop(Iop_Add32,
   5977                                       unop(Iop_16Uto32,
   5978                                            unop(Iop_32to16, getIReg(rs))),
   5979                                       unop(Iop_16Uto32,
   5980                                            unop(Iop_32to16, getIReg(rt)))));
   5981 
   5982                      /* Detect overflow. */
   5983                      assign(t1, binop(Iop_CmpLT32U,
   5984                                       unop(Iop_16Uto32,
   5985                                            unop(Iop_32to16, mkexpr(t0))),
   5986                                       unop(Iop_16Uto32,
   5987                                            unop(Iop_32to16, getIReg(rs)))));
   5988 
   5989                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5990                                               binop(Iop_Or32,
   5991                                                     getDSPControl(),
   5992                                                     mkU32(0x00100000)),
   5993                                               getDSPControl()));
   5994 
   5995                      /* Add higher halves. */
   5996                      assign(t2, binop(Iop_Add32,
   5997                                       unop(Iop_16Uto32,
   5998                                            unop(Iop_32HIto16, getIReg(rs))),
   5999                                       unop(Iop_16Uto32,
   6000                                            unop(Iop_32HIto16, getIReg(rt)))));
   6001 
   6002                      /* Detect overflow. */
   6003                      assign(t3, binop(Iop_CmpLT32U,
   6004                                       unop(Iop_16Uto32,
   6005                                            unop(Iop_32to16, mkexpr(t2))),
   6006                                       unop(Iop_16Uto32,
   6007                                            unop(Iop_32HIto16, getIReg(rs)))));
   6008 
   6009                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6010                                               binop(Iop_Or32,
   6011                                                     getDSPControl(),
   6012                                                     mkU32(0x00100000)),
   6013                                               getDSPControl()));
   6014 
   6015                      putIReg(rd, binop(Iop_16HLto32,
   6016                                        IRExpr_ITE(mkexpr(t3),
   6017                                                   mkU16(0xffff),
   6018                                                   unop(Iop_32to16,
   6019                                                        mkexpr(t2))),
   6020                                        IRExpr_ITE(mkexpr(t1),
   6021                                                   mkU16(0xffff),
   6022                                                   unop(Iop_32to16,
   6023                                                        mkexpr(t0)))));
   6024                      break;
   6025                   }
   6026                   case 0xD: {  /* SUBU_S.PH */
   6027                      DIP("subu_s.ph r%u, r%u, r%u", rd, rs, rt);
   6028                      vassert(!mode64);
   6029                      t0 = newTemp(Ity_I32);
   6030                      t1 = newTemp(Ity_I1);
   6031                      t2 = newTemp(Ity_I32);
   6032                      t3 = newTemp(Ity_I1);
   6033 
   6034                      /* Subtract lower halves. */
   6035                      assign(t0, binop(Iop_Sub32,
   6036                                       unop(Iop_16Uto32,
   6037                                            unop(Iop_32to16, getIReg(rs))),
   6038                                       unop(Iop_16Uto32,
   6039                                            unop(Iop_32to16, getIReg(rt)))));
   6040 
   6041                      /* Detect underflow. */
   6042                      assign(t1, binop(Iop_CmpNE32,
   6043                                       binop(Iop_And32,
   6044                                             mkexpr(t0), mkU32(0x00010000)),
   6045                                       mkU32(0x0)));
   6046 
   6047                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6048                                               binop(Iop_Or32,
   6049                                                     getDSPControl(),
   6050                                                     mkU32(0x00100000)),
   6051                                               getDSPControl()));
   6052 
   6053                      /* Subtract higher halves. */
   6054                      assign(t2, binop(Iop_Sub32,
   6055                                       unop(Iop_16Uto32,
   6056                                            unop(Iop_32HIto16, getIReg(rs))),
   6057                                       unop(Iop_16Uto32,
   6058                                            unop(Iop_32HIto16, getIReg(rt)))));
   6059 
   6060                      /* Detect underflow. */
   6061                      assign(t3, binop(Iop_CmpNE32,
   6062                                       binop(Iop_And32,
   6063                                             mkexpr(t2), mkU32(0x00010000)),
   6064                                       mkU32(0x0)));
   6065 
   6066                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6067                                               binop(Iop_Or32,
   6068                                                     getDSPControl(),
   6069                                                     mkU32(0x00100000)),
   6070                                               getDSPControl()));
   6071 
   6072                      putIReg(rd,
   6073                              binop(Iop_16HLto32,
   6074                                    IRExpr_ITE(mkexpr(t3),
   6075                                               mkU16(0x0000),
   6076                                               unop(Iop_32to16, mkexpr(t2))),
   6077                                    IRExpr_ITE(mkexpr(t1),
   6078                                               mkU16(0x0000),
   6079                                               unop(Iop_32to16, mkexpr(t0)))));
   6080                      break;
   6081                   }
   6082                   case 0xE: {  /* ADDQ_S.PH */
   6083                      DIP("addq_s.ph r%u r%u, r%u", rd, rs, rt);
   6084                      vassert(!mode64);
   6085                      t0 = newTemp(Ity_I32);
   6086                      t1 = newTemp(Ity_I1);
   6087                      t2 = newTemp(Ity_I32);
   6088                      t3 = newTemp(Ity_I1);
   6089                      t4 = newTemp(Ity_I16);
   6090                      t5 = newTemp(Ity_I16);
   6091                      t6 = newTemp(Ity_I32);
   6092                      t7 = newTemp(Ity_I32);
   6093 
   6094                      /* Add lower halves. */
   6095                      assign(t0, binop(Iop_Add32,
   6096                                       unop(Iop_16Sto32,
   6097                                            unop(Iop_32to16, getIReg(rs))),
   6098                                       unop(Iop_16Sto32,
   6099                                            unop(Iop_32to16, getIReg(rt)))));
   6100 
   6101                      /* Bit 16 of the result. */
   6102                      assign(t6, binop(Iop_And32,
   6103                                       unop(Iop_16Uto32,
   6104                                            unop(Iop_32HIto16, mkexpr(t0))),
   6105                                       mkU32(0x1)));
   6106                      /* Detect overflow. */
   6107                      assign(t1, binop(Iop_CmpNE32,
   6108                                       binop(Iop_Shr32,
   6109                                             binop(Iop_And32,
   6110                                                   mkexpr(t0),
   6111                                                   mkU32(0x8000)),
   6112                                             mkU8(15)),
   6113                                       mkexpr(t6)));
   6114 
   6115                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6116                                               binop(Iop_Or32,
   6117                                                     getDSPControl(),
   6118                                                     mkU32(0x00100000)),
   6119                                               getDSPControl()));
   6120                      /* Saturate if needed. */
   6121                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6122                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6123                                                             mkexpr(t6),
   6124                                                             mkU32(0x0)),
   6125                                                       mkU16(0x7fff),
   6126                                                       mkU16(0x8000)),
   6127                                            unop(Iop_32to16, mkexpr(t0))));
   6128 
   6129                      /* Add higher halves. */
   6130                      assign(t2, binop(Iop_Add32,
   6131                                       unop(Iop_16Sto32,
   6132                                            unop(Iop_32HIto16, getIReg(rs))),
   6133                                       unop(Iop_16Sto32,
   6134                                            unop(Iop_32HIto16, getIReg(rt)))));
   6135 
   6136                      /* Bit 16 of the result. */
   6137                      assign(t7, binop(Iop_And32,
   6138                                       unop(Iop_16Uto32,
   6139                                            unop(Iop_32HIto16, mkexpr(t2))),
   6140                                       mkU32(0x1)));
   6141                      /* Detect overflow. */
   6142                      assign(t3, binop(Iop_CmpNE32,
   6143                                       binop(Iop_Shr32,
   6144                                             binop(Iop_And32,
   6145                                                   mkexpr(t2),
   6146                                                   mkU32(0x00008000)),
   6147                                             mkU8(15)),
   6148                                       mkexpr(t7)));
   6149 
   6150                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6151                                               binop(Iop_Or32,
   6152                                                     getDSPControl(),
   6153                                                     mkU32(0x00100000)),
   6154                                               getDSPControl()));
   6155                      /* Saturate if needed. */
   6156                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6157                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6158                                                             mkexpr(t7),
   6159                                                             mkU32(0x0)),
   6160                                                       mkU16(0x7fff),
   6161                                                       mkU16(0x8000)),
   6162                                            unop(Iop_32to16, mkexpr(t2))));
   6163 
   6164                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6165                      break;
   6166                   }
   6167                   case 0xF: {  /* SUBQ_S.PH */
   6168                      DIP("subq_s.ph r%u r%u, r%u", rd, rs, rt);
   6169                      vassert(!mode64);
   6170                      t0 = newTemp(Ity_I32);
   6171                      t1 = newTemp(Ity_I1);
   6172                      t2 = newTemp(Ity_I32);
   6173                      t3 = newTemp(Ity_I1);
   6174                      t4 = newTemp(Ity_I16);
   6175                      t5 = newTemp(Ity_I16);
   6176                      t6 = newTemp(Ity_I32);
   6177                      t7 = newTemp(Ity_I32);
   6178 
   6179                      /* Subtract lower halves. */
   6180                      assign(t0, binop(Iop_Sub32,
   6181                                       unop(Iop_16Sto32,
   6182                                            unop(Iop_32to16, getIReg(rs))),
   6183                                       unop(Iop_16Sto32,
   6184                                            unop(Iop_32to16, getIReg(rt)))));
   6185 
   6186                      /* Bit 16 of the result. */
   6187                      assign(t6, binop(Iop_And32,
   6188                                       unop(Iop_16Uto32,
   6189                                            unop(Iop_32HIto16, mkexpr(t0))),
   6190                                       mkU32(0x1)));
   6191                      /* Detect overflow or underflow. */
   6192                      assign(t1, binop(Iop_CmpNE32,
   6193                                       binop(Iop_Shr32,
   6194                                             binop(Iop_And32,
   6195                                                   mkexpr(t0),
   6196                                                   mkU32(0x8000)),
   6197                                             mkU8(15)),
   6198                                       mkexpr(t6)));
   6199 
   6200                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6201                                               binop(Iop_Or32,
   6202                                                     getDSPControl(),
   6203                                                     mkU32(0x00100000)),
   6204                                               getDSPControl()));
   6205                      /* Saturate if needed. */
   6206                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6207                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6208                                                             mkexpr(t6),
   6209                                                             mkU32(0x0)),
   6210                                                       mkU16(0x7fff),
   6211                                                       mkU16(0x8000)),
   6212                                            unop(Iop_32to16, mkexpr(t0))));
   6213 
   6214                      /* Subtract higher halves. */
   6215                      assign(t2, binop(Iop_Sub32,
   6216                                       unop(Iop_16Sto32,
   6217                                            unop(Iop_32HIto16, getIReg(rs))),
   6218                                       unop(Iop_16Sto32,
   6219                                            unop(Iop_32HIto16, getIReg(rt)))));
   6220 
   6221                      /* Bit 16 of the result. */
   6222                      assign(t7, binop(Iop_And32,
   6223                                       unop(Iop_16Uto32,
   6224                                            unop(Iop_32HIto16, mkexpr(t2))),
   6225                                       mkU32(0x1)));
   6226                      /* Detect overflow or underflow. */
   6227                      assign(t3, binop(Iop_CmpNE32,
   6228                                       binop(Iop_Shr32,
   6229                                             binop(Iop_And32,
   6230                                                   mkexpr(t2),
   6231                                                   mkU32(0x00008000)),
   6232                                             mkU8(15)),
   6233                                       mkexpr(t7)));
   6234 
   6235                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6236                                               binop(Iop_Or32,
   6237                                                     getDSPControl(),
   6238                                                     mkU32(0x00100000)),
   6239                                               getDSPControl()));
   6240                      /* Saturate if needed. */
   6241                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6242                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6243                                                             mkexpr(t7),
   6244                                                             mkU32(0x0)),
   6245                                                       mkU16(0x7fff),
   6246                                                       mkU16(0x8000)),
   6247                                            unop(Iop_32to16, mkexpr(t2))));
   6248 
   6249                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6250                      break;
   6251                   }
   6252                   case 0x10: {  /* ADDSC */
   6253                      DIP("addsc r%u, r%u, r%u", rd, rs, rt);
   6254                      vassert(!mode64);
   6255                      t0 = newTemp(Ity_I64);
   6256                      t1 = newTemp(Ity_I1);
   6257 
   6258                      /* The carry bit result out of the addition operation is
   6259                         written to bit 13(the c field) of the DSPControl reg. */
   6260                      assign(t0, binop(Iop_Add64,
   6261                                       unop(Iop_32Uto64, getIReg(rs)),
   6262                                       unop(Iop_32Uto64, getIReg(rt))));
   6263 
   6264                      assign(t1, binop(Iop_CmpEQ32,
   6265                                       binop(Iop_And32,
   6266                                             unop(Iop_64HIto32, mkexpr(t0)),
   6267                                             mkU32(0x1)),
   6268                                       mkU32(0x1)));
   6269                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6270                                               binop(Iop_Or32,
   6271                                                     getDSPControl(),
   6272                                                     mkU32(0x2000)),
   6273                                               binop(Iop_And32,
   6274                                                     getDSPControl(),
   6275                                                     mkU32(0xffffdfff))));
   6276 
   6277                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
   6278                      break;
   6279                   }
   6280                   case 0x11: {  /* ADDWC */
   6281                      DIP("addwc r%u, r%u, r%u", rd, rs, rt);
   6282                      vassert(!mode64);
   6283                      t0 = newTemp(Ity_I32);
   6284                      t1 = newTemp(Ity_I64);
   6285                      t2 = newTemp(Ity_I32);
   6286                      t3 = newTemp(Ity_I32);
   6287                      t4 = newTemp(Ity_I1);
   6288 
   6289                      /* Get carry bit from DSPControl register. */
   6290                      assign(t0, binop(Iop_Shr32,
   6291                                        binop(Iop_And32,
   6292                                              getDSPControl(),
   6293                                              mkU32(0x2000)),
   6294                                        mkU8(0xd)));
   6295                      assign(t1, binop(Iop_Add64,
   6296                                       unop(Iop_32Sto64, getIReg(rs)),
   6297                                       unop(Iop_32Sto64,
   6298                                            binop(Iop_Add32,
   6299                                                  getIReg(rt),
   6300                                                  mkexpr(t0)))));
   6301 
   6302                      /* Extract bits 32 and 31. */
   6303                      assign(t2, binop(Iop_And32,
   6304                                       unop(Iop_64HIto32, mkexpr(t1)),
   6305                                       mkU32(0x1)));
   6306                      assign(t3, binop(Iop_Shr32,
   6307                                       binop(Iop_And32,
   6308                                             unop(Iop_64to32, mkexpr(t1)),
   6309                                             mkU32(0x80000000)),
   6310                                       mkU8(31)));
   6311                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
   6312 
   6313                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6314                                               binop(Iop_Or32,
   6315                                                     getDSPControl(),
   6316                                                     mkU32(0x00100000)),
   6317                                               getDSPControl()));
   6318                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
   6319                      break;
   6320                   }
   6321                   case 0x12: {  /* MODSUB */
   6322                      DIP("modsub r%u, r%u, r%u", rd, rs, rt);
   6323                      vassert(!mode64);
   6324                      t0 = newTemp(Ity_I32);
   6325                      t1 = newTemp(Ity_I32);
   6326                      t2 = newTemp(Ity_I32);
   6327 
   6328                      /* decr_7..0 */
   6329                      assign(t0,
   6330                             unop(Iop_8Uto32,
   6331                                  unop(Iop_16to8,
   6332                                       unop(Iop_32to16, getIReg(rt)))));
   6333 
   6334                      /* lastindex_15..0 */
   6335                      assign(t1,
   6336                             unop(Iop_16Uto32,
   6337                                  binop(Iop_8HLto16,
   6338                                        unop(Iop_16to8,
   6339                                             unop(Iop_32HIto16, getIReg(rt))),
   6340                                        unop(Iop_16HIto8,
   6341                                             unop(Iop_32to16, getIReg(rt))))));
   6342                      /* temp_15..0 */
   6343                      assign(t2,
   6344                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6345                                              getIReg(rs),
   6346                                              mkU32(0x00000000)),
   6347                                        mkexpr(t1),
   6348                                        binop(Iop_Sub32,
   6349                                              getIReg(rs), mkexpr(t0))));
   6350                      putIReg(rd, mkexpr(t2));
   6351                      break;
   6352                   }
   6353                   case 0x14: {  /* RADDU.W.QB */
   6354                      DIP("raddu.w.qb r%u, r%u", rd, rs);
   6355                      vassert(!mode64);
   6356                      putIReg(rd, binop(Iop_Add32,
   6357                                        binop(Iop_Add32,
   6358                                              unop(Iop_8Uto32,
   6359                                                   unop(Iop_16to8,
   6360                                                        unop(Iop_32to16,
   6361                                                             getIReg(rs)))),
   6362                                              unop(Iop_8Uto32,
   6363                                                   unop(Iop_16HIto8,
   6364                                                        unop(Iop_32to16,
   6365                                                             getIReg(rs))))),
   6366                                        binop(Iop_Add32,
   6367                                              unop(Iop_8Uto32,
   6368                                                   unop(Iop_16to8,
   6369                                                        unop(Iop_32HIto16,
   6370                                                             getIReg(rs)))),
   6371                                              unop(Iop_8Uto32,
   6372                                                   unop(Iop_16HIto8,
   6373                                                        unop(Iop_32HIto16,
   6374                                                             getIReg(rs)))))));
   6375                      break;
   6376                   }
   6377                   case 0x16: {  /* ADDQ_S.W */
   6378                      DIP("addq_s.w r%u, r%u, r%u", rd, rs, rt);
   6379                      vassert(!mode64);
   6380                      t0 = newTemp(Ity_I64);
   6381                      t1 = newTemp(Ity_I1);
   6382                      t2 = newTemp(Ity_I32);
   6383                      t3 = newTemp(Ity_I32);
   6384 
   6385                      assign(t0, binop(Iop_Add64,
   6386                                       unop(Iop_32Sto64, getIReg(rs)),
   6387                                       unop(Iop_32Sto64, getIReg(rt))));
   6388 
   6389                      assign(t3, binop(Iop_And32,
   6390                                       unop(Iop_64HIto32, mkexpr(t0)),
   6391                                       mkU32(0x1)));
   6392                      assign(t1, binop(Iop_CmpNE32,
   6393                                       binop(Iop_Shr32,
   6394                                             binop(Iop_And32,
   6395                                                   unop(Iop_64to32, mkexpr(t0)),
   6396                                                   mkU32(0x80000000)),
   6397                                             mkU8(31)),
   6398                                       mkexpr(t3)));
   6399 
   6400                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6401                                               binop(Iop_Or32,
   6402                                                     getDSPControl(),
   6403                                                     mkU32(0x00100000)),
   6404                                               getDSPControl()));
   6405 
   6406                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6407                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6408                                                              mkexpr(t3),
   6409                                                              mkU32(0x0)),
   6410                                                        mkU32(0x7fffffff),
   6411                                                        mkU32(0x80000000)),
   6412                                             unop(Iop_64to32, mkexpr(t0))));
   6413                      break;
   6414                   }
   6415                   case 0x17: {  /* SUBQ_S.W */
   6416                      DIP("subq_s.w r%u, r%u, r%u", rd, rs, rt);
   6417                      vassert(!mode64);
   6418                      t0 = newTemp(Ity_I64);
   6419                      t1 = newTemp(Ity_I1);
   6420                      t2 = newTemp(Ity_I32);
   6421                      t3 = newTemp(Ity_I32);
   6422 
   6423                      assign(t0, binop(Iop_Sub64,
   6424                                       unop(Iop_32Sto64, getIReg(rs)),
   6425                                       unop(Iop_32Sto64, getIReg(rt))));
   6426 
   6427                      assign(t3, binop(Iop_And32,
   6428                                       unop(Iop_64HIto32, mkexpr(t0)),
   6429                                       mkU32(0x1)));
   6430                      assign(t1, binop(Iop_CmpNE32,
   6431                                       binop(Iop_Shr32,
   6432                                             binop(Iop_And32,
   6433                                                   unop(Iop_64to32, mkexpr(t0)),
   6434                                                   mkU32(0x80000000)),
   6435                                             mkU8(31)),
   6436                                       mkexpr(t3)));
   6437 
   6438                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6439                                               binop(Iop_Or32,
   6440                                                     getDSPControl(),
   6441                                                     mkU32(0x00100000)),
   6442                                               getDSPControl()));
   6443 
   6444                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6445                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6446                                                              mkexpr(t3),
   6447                                                              mkU32(0x0)),
   6448                                                        mkU32(0x7fffffff),
   6449                                                        mkU32(0x80000000)),
   6450                                             unop(Iop_64to32, mkexpr(t0))));
   6451                      break;
   6452                   }
   6453                   case 0x1C: {  /* MULEQ_S.W.PHL */
   6454                      DIP("muleq_s.w.phl r%u, r%u, r%u", rd, rs, rt);
   6455                      vassert(!mode64);
   6456                      t0 = newTemp(Ity_I32);
   6457                      t1 = newTemp(Ity_I1);
   6458                      t2 = newTemp(Ity_I1);
   6459                      t3 = newTemp(Ity_I32);
   6460 
   6461                      assign(t0,
   6462                             binop(Iop_Shl32,
   6463                                   binop(Iop_Mul32,
   6464                                         unop(Iop_16Sto32,
   6465                                              unop(Iop_32HIto16, getIReg(rt))),
   6466                                         unop(Iop_16Sto32,
   6467                                              unop(Iop_32HIto16, getIReg(rs)))),
   6468                                   mkU8(0x1)));
   6469                      assign(t1, binop(Iop_CmpEQ32,
   6470                                       binop(Iop_And32,
   6471                                             getIReg(rt),
   6472                                             mkU32(0xffff0000)),
   6473                                       mkU32(0x80000000)));
   6474                      assign(t2, binop(Iop_CmpEQ32,
   6475                                       binop(Iop_And32,
   6476                                             getIReg(rs),
   6477                                             mkU32(0xffff0000)),
   6478                                       mkU32(0x80000000)));
   6479                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6480                                            IRExpr_ITE(mkexpr(t2),
   6481                                                       binop(Iop_Or32,
   6482                                                             getDSPControl(),
   6483                                                             mkU32(0x00200000)),
   6484                                                       getDSPControl()),
   6485                                            getDSPControl()));
   6486                      putDSPControl(mkexpr(t3));
   6487 
   6488                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6489                                             IRExpr_ITE(mkexpr(t2),
   6490                                                        mkU32(0x7fffffff),
   6491                                                        mkexpr(t0)),
   6492                                             mkexpr(t0)));
   6493                      break;
   6494                   }
   6495                   case 0x1D: {  /* MULEQ_S.W.PHR */
   6496                      DIP("muleq_s.w.phr r%u, r%u, r%u", rd, rs, rt);
   6497                      vassert(!mode64);
   6498                      t0 = newTemp(Ity_I32);
   6499                      t1 = newTemp(Ity_I1);
   6500                      t2 = newTemp(Ity_I1);
   6501 
   6502                      assign(t0,
   6503                             binop(Iop_Shl32,
   6504                                   binop(Iop_Mul32,
   6505                                         unop(Iop_16Sto32,
   6506                                              unop(Iop_32to16, getIReg(rt))),
   6507                                         unop(Iop_16Sto32,
   6508                                              unop(Iop_32to16, getIReg(rs)))),
   6509                                   mkU8(0x1)));
   6510                      assign(t1, binop(Iop_CmpEQ32,
   6511                                       binop(Iop_And32,
   6512                                             getIReg(rt),
   6513                                             mkU32(0xffff)),
   6514                                       mkU32(0x8000)));
   6515                      assign(t2, binop(Iop_CmpEQ32,
   6516                                       binop(Iop_And32,
   6517                                             getIReg(rs),
   6518                                             mkU32(0xffff)),
   6519                                       mkU32(0x8000)));
   6520                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6521                                               IRExpr_ITE(mkexpr(t2),
   6522                                                          binop(Iop_Or32,
   6523                                                                getDSPControl(),
   6524                                                                mkU32(0x00200000)
   6525                                                               ),
   6526                                                          getDSPControl()),
   6527                                               getDSPControl()));
   6528                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6529                                             IRExpr_ITE(mkexpr(t2),
   6530                                                        mkU32(0x7fffffff),
   6531                                                        mkexpr(t0)),
   6532                                             mkexpr(t0)));
   6533                      break;
   6534                   }
   6535                   case 0x1E: {  /* MULQ_S.PH */
   6536                      DIP("mulq_s.ph r%u, r%u, r%u", rd, rs, rt);
   6537                      vassert(!mode64);
   6538                      t0 = newTemp(Ity_I32);
   6539                      t1 = newTemp(Ity_I32);
   6540                      t2 = newTemp(Ity_I16);
   6541                      t3 = newTemp(Ity_I16);
   6542                      t5 = newTemp(Ity_I32);
   6543                      t6 = newTemp(Ity_I32);
   6544                      t7 = newTemp(Ity_I32);
   6545                      t8 = newTemp(Ity_I32);
   6546 
   6547                      assign(t5,
   6548                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
   6549                      assign(t6,
   6550                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   6551 
   6552                      assign(t7,
   6553                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
   6554                      assign(t8,
   6555                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
   6556 
   6557                      assign(t0, binop(Iop_And32,
   6558                                       unop(Iop_1Sto32,
   6559                                            binop(Iop_CmpEQ32,
   6560                                                  binop(Iop_And32,
   6561                                                        mkexpr(t5),
   6562                                                        mkU32(0xffff)),
   6563                                                  mkU32(0x8000))),
   6564                                       unop(Iop_1Sto32,
   6565                                            binop(Iop_CmpEQ32,
   6566                                                  binop(Iop_And32,
   6567                                                        mkexpr(t6),
   6568                                                        mkU32(0xffff)),
   6569                                                  mkU32(0x8000)))));
   6570                      assign(t1, binop(Iop_And32,
   6571                                       unop(Iop_1Sto32,
   6572                                            binop(Iop_CmpEQ32,
   6573                                                  binop(Iop_And32,
   6574                                                        mkexpr(t7),
   6575                                                        mkU32(0xffff)),
   6576                                                  mkU32(0x8000))),
   6577                                       unop(Iop_1Sto32,
   6578                                            binop(Iop_CmpEQ32,
   6579                                                  binop(Iop_And32,
   6580                                                        mkexpr(t8),
   6581                                                        mkU32(0xffff)),
   6582                                                  mkU32(0x8000)))));
   6583 
   6584                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   6585                                                     binop(Iop_Or32,
   6586                                                           mkexpr(t0),
   6587                                                           mkexpr(t1)),
   6588                                                     mkU32(0x0)),
   6589                                               getDSPControl(),
   6590                                               binop(Iop_Or32,
   6591                                                     getDSPControl(),
   6592                                                     mkU32(0x200000))));
   6593 
   6594                      assign(t2, unop(Iop_32HIto16,
   6595                                      binop(Iop_Shl32,
   6596                                            unop(Iop_64to32,
   6597                                                 binop(Iop_MullS32,
   6598                                                       mkexpr(t7),
   6599                                                       mkexpr(t8))),
   6600                                            mkU8(0x1))));
   6601                      assign(t3, unop(Iop_32HIto16,
   6602                                      binop(Iop_Shl32,
   6603                                            unop(Iop_64to32,
   6604                                                 binop(Iop_MullS32,
   6605                                                       mkexpr(t5),
   6606                                                       mkexpr(t6))),
   6607                                            mkU8(0x1))));
   6608                      putIReg(rd, binop(Iop_16HLto32,
   6609                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6610                                                         mkexpr(t1),
   6611                                                         mkU32(0x0)),
   6612                                                   mkexpr(t2),
   6613                                                   mkU16(0x7fff)),
   6614                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6615                                                         mkexpr(t0),
   6616                                                         mkU32(0x0)),
   6617                                                   mkexpr(t3),
   6618                                                   mkU16(0x7fff))));
   6619                      break;
   6620                   }
   6621                   case 0x1F: {  /* MULQ_RS.PH */
   6622                      DIP("mulq_rs.ph r%u, r%u, r%u", rd, rs, rt);
   6623                      vassert(!mode64);
   6624                      t0 = newTemp(Ity_I32);
   6625                      t1 = newTemp(Ity_I1);
   6626                      t2 = newTemp(Ity_I1);
   6627                      t3 = newTemp(Ity_I16);
   6628                      t4 = newTemp(Ity_I32);
   6629                      t5 = newTemp(Ity_I1);
   6630                      t6 = newTemp(Ity_I1);
   6631                      t7 = newTemp(Ity_I16);
   6632 
   6633                      /* Multiply and round lower halfwords. */
   6634                      assign(t0, binop(Iop_Add32,
   6635                                       binop(Iop_Shl32,
   6636                                             binop(Iop_Mul32,
   6637                                                   unop(Iop_16Sto32,
   6638                                                        unop(Iop_32to16,
   6639                                                             getIReg(rt))),
   6640                                                   unop(Iop_16Sto32,
   6641                                                        unop(Iop_32to16,
   6642                                                             getIReg(rs)))),
   6643                                             mkU8(0x1)),
   6644                                       mkU32(0x00008000)));
   6645                      assign(t1, binop(Iop_CmpEQ32,
   6646                                       binop(Iop_And32,
   6647                                             getIReg(rt), mkU32(0xffff)),
   6648                                       mkU32(0x8000)));
   6649                      assign(t2, binop(Iop_CmpEQ32,
   6650                                       binop(Iop_And32,
   6651                                             getIReg(rs), mkU32(0xffff)),
   6652                                       mkU32(0x8000)));
   6653                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6654                                               IRExpr_ITE(mkexpr(t2),
   6655                                                          binop(Iop_Or32,
   6656                                                                getDSPControl(),
   6657                                                                mkU32(0x00200000)
   6658                                                               ),
   6659                                                          getDSPControl()),
   6660                                               getDSPControl()));
   6661                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6662                                            IRExpr_ITE(mkexpr(t2),
   6663                                                       mkU16(0x7fff),
   6664                                                       unop(Iop_32HIto16,
   6665                                                            mkexpr(t0))),
   6666                                            unop(Iop_32HIto16, mkexpr(t0))));
   6667 
   6668                      /* Multiply and round higher halfwords. */
   6669                      assign(t4, binop(Iop_Add32,
   6670                                       binop(Iop_Shl32,
   6671                                             binop(Iop_Mul32,
   6672                                                   unop(Iop_16Sto32,
   6673                                                        unop(Iop_32HIto16,
   6674                                                             getIReg(rt))),
   6675                                                   unop(Iop_16Sto32,
   6676                                                        unop(Iop_32HIto16,
   6677                                                             getIReg(rs)))),
   6678                                             mkU8(0x1)),
   6679                                       mkU32(0x00008000)));
   6680                      assign(t5, binop(Iop_CmpEQ32,
   6681                                       binop(Iop_And32,
   6682                                             getIReg(rt),
   6683                                             mkU32(0xffff0000)),
   6684                                       mkU32(0x80000000)));
   6685                      assign(t6, binop(Iop_CmpEQ32,
   6686                                       binop(Iop_And32,
   6687                                             getIReg(rs),
   6688                                             mkU32(0xffff0000)),
   6689                                       mkU32(0x80000000)));
   6690                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   6691                                              IRExpr_ITE(mkexpr(t6),
   6692                                                         binop(Iop_Or32,
   6693                                                              getDSPControl(),
   6694                                                              mkU32(0x00200000)),
   6695                                                         getDSPControl()),
   6696                                              getDSPControl()));
   6697                      assign(t7, IRExpr_ITE(mkexpr(t5),
   6698                                            IRExpr_ITE(mkexpr(t6),
   6699                                                       mkU16(0x7fff),
   6700                                                       unop(Iop_32HIto16,
   6701                                                            mkexpr(t4))),
   6702                                            unop(Iop_32HIto16, mkexpr(t4))));
   6703 
   6704                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   6705                      break;
   6706                   }
   6707                   default:
   6708                      return -1;
   6709                }
   6710                break;  /* end of ADDU.QB */
   6711             }
   6712             case 0x11: {  /* CMPU.EQ.QB */
   6713                switch(sa) {
   6714                   case 0x0: {  /* CMPU.EQ.QB */
   6715                      DIP("cmpu.eq.qb r%u, r%u", rs, rt);
   6716                      vassert(!mode64);
   6717                      t1 = newTemp(Ity_I1);
   6718                      t2 = newTemp(Ity_I1);
   6719                      t3 = newTemp(Ity_I1);
   6720                      t4 = newTemp(Ity_I1);
   6721 
   6722                      assign(t1,
   6723                             binop(Iop_CmpEQ32,
   6724                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
   6725                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   6726                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6727                                               binop(Iop_Or32,
   6728                                                     getDSPControl(),
   6729                                                     mkU32(0x01000000)),
   6730                                               binop(Iop_And32,
   6731                                                     getDSPControl(),
   6732                                                     mkU32(0xfeffffff))));
   6733 
   6734                      assign(t2, binop(Iop_CmpEQ32,
   6735                                       unop(Iop_8Uto32,
   6736                                            unop(Iop_16HIto8,
   6737                                                 unop(Iop_32to16,
   6738                                                      getIReg(rs)))),
   6739                                       unop(Iop_8Uto32,
   6740                                            unop(Iop_16HIto8,
   6741                                                 unop(Iop_32to16,
   6742                                                      getIReg(rt))))));
   6743                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6744                                               binop(Iop_Or32,
   6745                                                     getDSPControl(),
   6746                                                     mkU32(0x02000000)),
   6747                                               binop(Iop_And32,
   6748                                                     getDSPControl(),
   6749                                                     mkU32(0xfdffffff))));
   6750 
   6751                      assign(t3, binop(Iop_CmpEQ32,
   6752                                       unop(Iop_8Uto32,
   6753                                            unop(Iop_16to8,
   6754                                                 unop(Iop_32HIto16,
   6755                                                      getIReg(rs)))),
   6756                                       unop(Iop_8Uto32,
   6757                                            unop(Iop_16to8,
   6758                                                 unop(Iop_32HIto16,
   6759                                                      getIReg(rt))))));
   6760                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6761                                               binop(Iop_Or32,
   6762                                                     getDSPControl(),
   6763                                                     mkU32(0x04000000)),
   6764                                               binop(Iop_And32,
   6765                                                     getDSPControl(),
   6766                                                     mkU32(0xfbffffff))));
   6767 
   6768                      assign(t4, binop(Iop_CmpEQ32,
   6769                                       unop(Iop_8Uto32,
   6770                                            unop(Iop_16HIto8,
   6771                                                 unop(Iop_32HIto16,
   6772                                                      getIReg(rs)))),
   6773                                       unop(Iop_8Uto32,
   6774                                            unop(Iop_16HIto8,
   6775                                                 unop(Iop_32HIto16,
   6776                                                      getIReg(rt))))));
   6777                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6778                                               binop(Iop_Or32,
   6779                                                     getDSPControl(),
   6780                                                     mkU32(0x08000000)),
   6781                                               binop(Iop_And32,
   6782                                                     getDSPControl(),
   6783                                                     mkU32(0xf7ffffff))));
   6784                      break;
   6785                   }
   6786                   case 0x1: {  /* CMPU.LT.QB */
   6787                      DIP("cmpu.lt.qb r%u, r%u", rs, rt);
   6788                      vassert(!mode64);
   6789                      t1 = newTemp(Ity_I1);
   6790                      t2 = newTemp(Ity_I1);
   6791                      t3 = newTemp(Ity_I1);
   6792                      t4 = newTemp(Ity_I1);
   6793 
   6794                      assign(t1, binop(Iop_CmpLT32U,
   6795                                       unop(Iop_8Uto32,
   6796                                            unop(Iop_16to8,
   6797                                                 unop(Iop_32to16,
   6798                                                      getIReg(rs)))),
   6799                                       unop(Iop_8Uto32,
   6800                                            unop(Iop_16to8,
   6801                                                 unop(Iop_32to16,
   6802                                                      getIReg(rt))))));
   6803                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6804                                               binop(Iop_Or32,
   6805                                                     getDSPControl(),
   6806                                                     mkU32(0x01000000)),
   6807                                               binop(Iop_And32,
   6808                                                     getDSPControl(),
   6809                                                     mkU32(0xfeffffff))));
   6810 
   6811                      assign(t2, binop(Iop_CmpLT32U,
   6812                                       unop(Iop_8Uto32,
   6813                                            unop(Iop_16HIto8,
   6814                                                 unop(Iop_32to16,
   6815                                                      getIReg(rs)))),
   6816                                       unop(Iop_8Uto32,
   6817                                            unop(Iop_16HIto8,
   6818                                                 unop(Iop_32to16,
   6819                                                      getIReg(rt))))));
   6820                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6821                                               binop(Iop_Or32,
   6822                                                     getDSPControl(),
   6823                                                     mkU32(0x02000000)),
   6824                                               binop(Iop_And32,
   6825                                                     getDSPControl(),
   6826                                                     mkU32(0xfdffffff))));
   6827 
   6828                      assign(t3, binop(Iop_CmpLT32U,
   6829                                       unop(Iop_8Uto32,
   6830                                            unop(Iop_16to8,
   6831                                                 unop(Iop_32HIto16,
   6832                                                      getIReg(rs)))),
   6833                                       unop(Iop_8Uto32,
   6834                                            unop(Iop_16to8,
   6835                                                 unop(Iop_32HIto16,
   6836                                                      getIReg(rt))))));
   6837                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6838                                               binop(Iop_Or32,
   6839                                                     getDSPControl(),
   6840                                                     mkU32(0x04000000)),
   6841                                               binop(Iop_And32,
   6842                                                     getDSPControl(),
   6843                                                     mkU32(0xfbffffff))));
   6844 
   6845                      assign(t4, binop(Iop_CmpLT32U,
   6846                                       unop(Iop_8Uto32,
   6847                                            unop(Iop_16HIto8,
   6848                                                 unop(Iop_32HIto16,
   6849                                                      getIReg(rs)))),
   6850                                       unop(Iop_8Uto32,
   6851                                            unop(Iop_16HIto8,
   6852                                                 unop(Iop_32HIto16,
   6853                                                      getIReg(rt))))));
   6854                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6855                                               binop(Iop_Or32,
   6856                                                     getDSPControl(),
   6857                                                     mkU32(0x08000000)),
   6858                                               binop(Iop_And32,
   6859                                                     getDSPControl(),
   6860                                                     mkU32(0xf7ffffff))));
   6861                      break;
   6862                   }
   6863                   case 0x2: {  /* CMPU.LE.QB */
   6864                      DIP("cmpu.le.qb r%u, r%u", rs, rt);
   6865                      vassert(!mode64);
   6866                      t1 = newTemp(Ity_I1);
   6867                      t2 = newTemp(Ity_I1);
   6868                      t3 = newTemp(Ity_I1);
   6869                      t4 = newTemp(Ity_I1);
   6870 
   6871                      assign(t1, binop(Iop_CmpLE32U,
   6872                                       unop(Iop_8Uto32,
   6873                                            unop(Iop_16to8,
   6874                                                 unop(Iop_32to16,
   6875                                                      getIReg(rs)))),
   6876                                       unop(Iop_8Uto32,
   6877                                            unop(Iop_16to8,
   6878                                                 unop(Iop_32to16,
   6879                                                      getIReg(rt))))));
   6880                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6881                                               binop(Iop_Or32,
   6882                                                     getDSPControl(),
   6883                                                     mkU32(0x01000000)),
   6884                                               binop(Iop_And32,
   6885                                                     getDSPControl(),
   6886                                                     mkU32(0xfeffffff))));
   6887 
   6888                      assign(t2, binop(Iop_CmpLE32U,
   6889                                       unop(Iop_8Uto32,
   6890                                            unop(Iop_16HIto8,
   6891                                                 unop(Iop_32to16,
   6892                                                      getIReg(rs)))),
   6893                                       unop(Iop_8Uto32,
   6894                                            unop(Iop_16HIto8,
   6895                                                 unop(Iop_32to16,
   6896                                                      getIReg(rt))))));
   6897                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6898                                               binop(Iop_Or32,
   6899                                                     getDSPControl(),
   6900                                                     mkU32(0x02000000)),
   6901                                               binop(Iop_And32,
   6902                                                     getDSPControl(),
   6903                                                     mkU32(0xfdffffff))));
   6904 
   6905                      assign(t3, binop(Iop_CmpLE32U,
   6906                                       unop(Iop_8Uto32,
   6907                                            unop(Iop_16to8,
   6908                                                 unop(Iop_32HIto16,
   6909                                                      getIReg(rs)))),
   6910                                       unop(Iop_8Uto32,
   6911                                            unop(Iop_16to8,
   6912                                                 unop(Iop_32HIto16,
   6913                                                      getIReg(rt))))));
   6914                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6915                                               binop(Iop_Or32,
   6916                                                     getDSPControl(),
   6917                                                     mkU32(0x04000000)),
   6918                                               binop(Iop_And32,
   6919                                                     getDSPControl(),
   6920                                                     mkU32(0xfbffffff))));
   6921 
   6922                      assign(t4, binop(Iop_CmpLE32U,
   6923                                       unop(Iop_8Uto32,
   6924                                            unop(Iop_16HIto8,
   6925                                                 unop(Iop_32HIto16,
   6926                                                      getIReg(rs)))),
   6927                                       unop(Iop_8Uto32,
   6928                                            unop(Iop_16HIto8,
   6929                                                 unop(Iop_32HIto16,
   6930                                                      getIReg(rt))))));
   6931                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6932                                               binop(Iop_Or32,
   6933                                                     getDSPControl(),
   6934                                                     mkU32(0x08000000)),
   6935                                               binop(Iop_And32,
   6936                                                     getDSPControl(),
   6937                                                     mkU32(0xf7ffffff))));
   6938                      break;
   6939                   }
   6940                   case 0x3: {  /* PICK.QB */
   6941                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   6942                      vassert(!mode64);
   6943                      t0 = newTemp(Ity_I32);
   6944                      t1 = newTemp(Ity_I8);
   6945                      t2 = newTemp(Ity_I8);
   6946                      t3 = newTemp(Ity_I8);
   6947                      t4 = newTemp(Ity_I8);
   6948 
   6949                      assign(t0, getDSPControl());
   6950                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   6951                                                  binop(Iop_And32,
   6952                                                        mkexpr(t0),
   6953                                                        mkU32(0x01000000)),
   6954                                                  mkU32(0x0)),
   6955                                            unop(Iop_16to8,
   6956                                                  unop(Iop_32to16,
   6957                                                       getIReg(rs))),
   6958                                            unop(Iop_16to8,
   6959                                                 unop(Iop_32to16,
   6960                                                      getIReg(rt)))));
   6961                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   6962                                                  binop(Iop_And32,
   6963                                                        mkexpr(t0),
   6964                                                        mkU32(0x02000000)),
   6965                                                  mkU32(0x0)),
   6966                                            unop(Iop_16HIto8,
   6967                                                 unop(Iop_32to16, getIReg(rs))),
   6968                                            unop(Iop_16HIto8,
   6969                                                 unop(Iop_32to16,
   6970                                                      getIReg(rt)))));
   6971                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
   6972                                                  binop(Iop_And32,
   6973                                                        mkexpr(t0),
   6974                                                        mkU32(0x04000000)),
   6975                                                  mkU32(0x0)),
   6976                                            unop(Iop_16to8,
   6977                                                 unop(Iop_32HIto16,
   6978                                                      getIReg(rs))),
   6979                                            unop(Iop_16to8,
   6980                                                 unop(Iop_32HIto16,
   6981                                                      getIReg(rt)))));
   6982                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   6983                                                  binop(Iop_And32,
   6984                                                        mkexpr(t0),
   6985                                                        mkU32(0x08000000)),
   6986                                                  mkU32(0x0)),
   6987                                            unop(Iop_16HIto8,
   6988                                                 unop(Iop_32HIto16,
   6989                                                      getIReg(rs))),
   6990                                            unop(Iop_16HIto8,
   6991                                                 unop(Iop_32HIto16,
   6992                                                      getIReg(rt)))));
   6993                      putIReg(rd,
   6994                              binop(Iop_16HLto32,
   6995                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
   6996                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
   6997                      break;
   6998                   }
   6999                   case 0x4: {  /* CMPGU.EQ.QB */
   7000                      DIP("cmpgu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7001                      vassert(!mode64);
   7002                      t1 = newTemp(Ity_I1);
   7003                      t2 = newTemp(Ity_I1);
   7004                      t3 = newTemp(Ity_I1);
   7005                      t4 = newTemp(Ity_I1);
   7006                      t5 = newTemp(Ity_I32);
   7007                      t6 = newTemp(Ity_I32);
   7008                      t7 = newTemp(Ity_I32);
   7009                      t8 = newTemp(Ity_I32);
   7010 
   7011                      assign(t1, binop(Iop_CmpEQ32,
   7012                                       unop(Iop_8Uto32,
   7013                                            unop(Iop_16to8,
   7014                                                 unop(Iop_32to16, getIReg(rs)))),
   7015                                       unop(Iop_8Uto32,
   7016                                            unop(Iop_16to8,
   7017                                                 unop(Iop_32to16,
   7018                                                      getIReg(rt))))));
   7019                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7020                                            mkU32(0x00000001), mkU32(0)));
   7021 
   7022                      assign(t2, binop(Iop_CmpEQ32,
   7023                                       unop(Iop_8Uto32,
   7024                                            unop(Iop_16HIto8,
   7025                                                 unop(Iop_32to16, getIReg(rs)))),
   7026                                       unop(Iop_8Uto32,
   7027                                            unop(Iop_16HIto8,
   7028                                                 unop(Iop_32to16,
   7029                                                      getIReg(rt))))));
   7030                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7031                                            mkU32(0x00000002), mkU32(0)));
   7032 
   7033                      assign(t3, binop(Iop_CmpEQ32,
   7034                                       unop(Iop_8Uto32,
   7035                                            unop(Iop_16to8,
   7036                                                 unop(Iop_32HIto16,
   7037                                                      getIReg(rs)))),
   7038                                       unop(Iop_8Uto32,
   7039                                            unop(Iop_16to8,
   7040                                                 unop(Iop_32HIto16,
   7041                                                      getIReg(rt))))));
   7042                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7043                                            mkU32(0x00000004), mkU32(0)));
   7044 
   7045                      assign(t4, binop(Iop_CmpEQ32,
   7046                                       unop(Iop_8Uto32,
   7047                                            unop(Iop_16HIto8,
   7048                                                 unop(Iop_32HIto16,
   7049                                                      getIReg(rs)))),
   7050                                       unop(Iop_8Uto32,
   7051                                            unop(Iop_16HIto8,
   7052                                                 unop(Iop_32HIto16,
   7053                                                      getIReg(rt))))));
   7054                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7055                                            mkU32(0x00000008), mkU32(0)));
   7056 
   7057                      putIReg(rd, binop(Iop_Or32,
   7058                                        binop(Iop_Or32,
   7059                                              binop(Iop_Or32,
   7060                                                    mkexpr(t5), mkexpr(t6)),
   7061                                              mkexpr(t7)),
   7062                                        mkexpr(t8)));
   7063                      break;
   7064                   }
   7065                   case 0x5: {  /* CMPGU.LT.QB */
   7066                      DIP("cmpgu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7067                      vassert(!mode64);
   7068                      t1 = newTemp(Ity_I1);
   7069                      t2 = newTemp(Ity_I1);
   7070                      t3 = newTemp(Ity_I1);
   7071                      t4 = newTemp(Ity_I1);
   7072                      t5 = newTemp(Ity_I32);
   7073                      t6 = newTemp(Ity_I32);
   7074                      t7 = newTemp(Ity_I32);
   7075                      t8 = newTemp(Ity_I32);
   7076 
   7077                      assign(t1, binop(Iop_CmpLT32U,
   7078                                       unop(Iop_8Uto32,
   7079                                            unop(Iop_16to8,
   7080                                                 unop(Iop_32to16, getIReg(rs)))),
   7081                                       unop(Iop_8Uto32,
   7082                                            unop(Iop_16to8,
   7083                                                 unop(Iop_32to16,
   7084                                                      getIReg(rt))))));
   7085                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7086                                            mkU32(0x00000001), mkU32(0)));
   7087 
   7088                      assign(t2, binop(Iop_CmpLT32U,
   7089                                       unop(Iop_8Uto32,
   7090                                            unop(Iop_16HIto8,
   7091                                                 unop(Iop_32to16, getIReg(rs)))),
   7092                                       unop(Iop_8Uto32,
   7093                                            unop(Iop_16HIto8,
   7094                                                 unop(Iop_32to16,
   7095                                                      getIReg(rt))))));
   7096                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7097                                            mkU32(0x00000002), mkU32(0)));
   7098 
   7099                      assign(t3, binop(Iop_CmpLT32U,
   7100                                       unop(Iop_8Uto32,
   7101                                            unop(Iop_16to8,
   7102                                                 unop(Iop_32HIto16,
   7103                                                      getIReg(rs)))),
   7104                                       unop(Iop_8Uto32,
   7105                                            unop(Iop_16to8,
   7106                                                 unop(Iop_32HIto16,
   7107                                                      getIReg(rt))))));
   7108                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7109                                            mkU32(0x00000004), mkU32(0)));
   7110 
   7111                      assign(t4, binop(Iop_CmpLT32U,
   7112                                       unop(Iop_8Uto32,
   7113                                            unop(Iop_16HIto8,
   7114                                                 unop(Iop_32HIto16,
   7115                                                      getIReg(rs)))),
   7116                                       unop(Iop_8Uto32,
   7117                                            unop(Iop_16HIto8,
   7118                                                 unop(Iop_32HIto16,
   7119                                                      getIReg(rt))))));
   7120                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7121                                            mkU32(0x00000008), mkU32(0)));
   7122                      putIReg(rd, binop(Iop_Or32,
   7123                                        binop(Iop_Or32,
   7124                                              binop(Iop_Or32,
   7125                                                    mkexpr(t5), mkexpr(t6)),
   7126                                              mkexpr(t7)),
   7127                                        mkexpr(t8)));
   7128                      break;
   7129                   }
   7130                   case 0x6: {  /* CMPGU.LE.QB */
   7131                      DIP("cmpgu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7132                      vassert(!mode64);
   7133                      t1 = newTemp(Ity_I1);
   7134                      t2 = newTemp(Ity_I1);
   7135                      t3 = newTemp(Ity_I1);
   7136                      t4 = newTemp(Ity_I1);
   7137                      t5 = newTemp(Ity_I32);
   7138                      t6 = newTemp(Ity_I32);
   7139                      t7 = newTemp(Ity_I32);
   7140                      t8 = newTemp(Ity_I32);
   7141 
   7142                      assign(t1, binop(Iop_CmpLE32U,
   7143                                       unop(Iop_8Uto32,
   7144                                            unop(Iop_16to8,
   7145                                                 unop(Iop_32to16, getIReg(rs)))),
   7146                                       unop(Iop_8Uto32,
   7147                                            unop(Iop_16to8,
   7148                                                 unop(Iop_32to16,
   7149                                                      getIReg(rt))))));
   7150                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7151                                            mkU32(0x00000001), mkU32(0)));
   7152 
   7153                      assign(t2, binop(Iop_CmpLE32U,
   7154                                       unop(Iop_8Uto32,
   7155                                            unop(Iop_16HIto8,
   7156                                                 unop(Iop_32to16, getIReg(rs)))),
   7157                                       unop(Iop_8Uto32,
   7158                                            unop(Iop_16HIto8,
   7159                                                 unop(Iop_32to16,
   7160                                                      getIReg(rt))))));
   7161                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7162                                            mkU32(0x00000002), mkU32(0)));
   7163 
   7164                      assign(t3, binop(Iop_CmpLE32U,
   7165                                       unop(Iop_8Uto32,
   7166                                            unop(Iop_16to8,
   7167                                                 unop(Iop_32HIto16,
   7168                                                      getIReg(rs)))),
   7169                                       unop(Iop_8Uto32,
   7170                                            unop(Iop_16to8,
   7171                                                 unop(Iop_32HIto16,
   7172                                                      getIReg(rt))))));
   7173                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7174                                            mkU32(0x00000004), mkU32(0)));
   7175 
   7176                      assign(t4, binop(Iop_CmpLE32U,
   7177                                       unop(Iop_8Uto32,
   7178                                            unop(Iop_16HIto8,
   7179                                                 unop(Iop_32HIto16,
   7180                                                      getIReg(rs)))),
   7181                                       unop(Iop_8Uto32,
   7182                                            unop(Iop_16HIto8,
   7183                                                 unop(Iop_32HIto16,
   7184                                                      getIReg(rt))))));
   7185                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7186                                            mkU32(0x00000008), mkU32(0)));
   7187                      putIReg(rd, binop(Iop_Or32,
   7188                                        binop(Iop_Or32,
   7189                                              binop(Iop_Or32,
   7190                                                    mkexpr(t5), mkexpr(t6)),
   7191                                              mkexpr(t7)),
   7192                                        mkexpr(t8)));
   7193                      break;
   7194                   }
   7195                   case 0x8: {  /* CMP.EQ.PH */
   7196                      DIP("cmp.eq.ph r%u, r%u", rs, rt);
   7197                      vassert(!mode64);
   7198                      t1 = newTemp(Ity_I1);
   7199                      t2 = newTemp(Ity_I1);
   7200 
   7201                      assign(t1, binop(Iop_CmpEQ16,
   7202                                       unop(Iop_32to16, getIReg(rs)),
   7203                                       unop(Iop_32to16, getIReg(rt))));
   7204                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7205                                               binop(Iop_Or32,
   7206                                                     getDSPControl(),
   7207                                                     mkU32(0x01000000)),
   7208                                               binop(Iop_And32,
   7209                                                     getDSPControl(),
   7210                                                     mkU32(0xfeffffff))));
   7211                      assign(t2, binop(Iop_CmpEQ16,
   7212                                       unop(Iop_32HIto16, getIReg(rs)),
   7213                                       unop(Iop_32HIto16, getIReg(rt))));
   7214                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7215                                               binop(Iop_Or32,
   7216                                                     getDSPControl(),
   7217                                                     mkU32(0x02000000)),
   7218                                               binop(Iop_And32,
   7219                                                     getDSPControl(),
   7220                                                     mkU32(0xfdffffff))));
   7221                      break;
   7222                   }
   7223                   case 0x9: {  /* CMP.LT.PH */
   7224                      DIP("cmp.lt.ph r%u, r%u", rs, rt);
   7225                      vassert(!mode64);
   7226                      t1 = newTemp(Ity_I1);
   7227                      t2 = newTemp(Ity_I1);
   7228 
   7229                      assign(t1, binop(Iop_CmpLT32S,
   7230                                       unop(Iop_16Sto32,
   7231                                            unop(Iop_32to16, getIReg(rs))),
   7232                                       unop(Iop_16Sto32,
   7233                                            unop(Iop_32to16, getIReg(rt)))));
   7234                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7235                                               binop(Iop_Or32,
   7236                                                     getDSPControl(),
   7237                                                     mkU32(0x01000000)),
   7238                                               binop(Iop_And32,
   7239                                                     getDSPControl(),
   7240                                                     mkU32(0xfeffffff))));
   7241 
   7242                      assign(t2, binop(Iop_CmpLT32S,
   7243                                       unop(Iop_16Sto32,
   7244                                            unop(Iop_32HIto16, getIReg(rs))),
   7245                                       unop(Iop_16Sto32,
   7246                                            unop(Iop_32HIto16, getIReg(rt)))));
   7247                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7248                                               binop(Iop_Or32,
   7249                                                     getDSPControl(),
   7250                                                     mkU32(0x02000000)),
   7251                                               binop(Iop_And32,
   7252                                                     getDSPControl(),
   7253                                                     mkU32(0xfdffffff))));
   7254                      break;
   7255                   }
   7256                   case 0xA: {  /* CMP.LE.PH */
   7257                      DIP("cmp.le.ph r%u, r%u", rs, rt);
   7258                      vassert(!mode64);
   7259                      t1 = newTemp(Ity_I1);
   7260                      t2 = newTemp(Ity_I1);
   7261 
   7262                      assign(t1, binop(Iop_CmpLE32S,
   7263                                       unop(Iop_16Sto32,
   7264                                            unop(Iop_32to16, getIReg(rs))),
   7265                                       unop(Iop_16Sto32,
   7266                                            unop(Iop_32to16, getIReg(rt)))));
   7267                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7268                                               binop(Iop_Or32,
   7269                                                     getDSPControl(),
   7270                                                     mkU32(0x01000000)),
   7271                                               binop(Iop_And32,
   7272                                                     getDSPControl(),
   7273                                                     mkU32(0xfeffffff))));
   7274 
   7275                      assign(t2, binop(Iop_CmpLE32S,
   7276                                       unop(Iop_16Sto32,
   7277                                            unop(Iop_32HIto16, getIReg(rs))),
   7278                                       unop(Iop_16Sto32,
   7279                                            unop(Iop_32HIto16, getIReg(rt)))));
   7280                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7281                                               binop(Iop_Or32,
   7282                                                     getDSPControl(),
   7283                                                     mkU32(0x02000000)),
   7284                                               binop(Iop_And32,
   7285                                                     getDSPControl(),
   7286                                                     mkU32(0xfdffffff))));
   7287                      break;
   7288                   }
   7289                   case 0xB: {  /* PICK.PH */
   7290                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   7291                      vassert(!mode64);
   7292                      t0 = newTemp(Ity_I32);
   7293                      t1 = newTemp(Ity_I16);
   7294                      t2 = newTemp(Ity_I16);
   7295 
   7296                      assign(t0, getDSPControl());
   7297 
   7298                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   7299                                                  binop(Iop_And32,
   7300                                                        mkexpr(t0),
   7301                                                        mkU32(0x01000000)),
   7302                                                  mkU32(0x0)),
   7303                                            unop(Iop_32to16, getIReg(rs)),
   7304                                            unop(Iop_32to16, getIReg(rt))));
   7305 
   7306                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   7307                                                  binop(Iop_And32,
   7308                                                        mkexpr(t0),
   7309                                                        mkU32(0x02000000)),
   7310                                                  mkU32(0x0)),
   7311                                            unop(Iop_32HIto16, getIReg(rs)),
   7312                                            unop(Iop_32HIto16, getIReg(rt))));
   7313 
   7314                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
   7315                      break;
   7316                   }
   7317                   case 0xC: {  /* PRECRQ.QB.PH */
   7318                      DIP("precrq.qb.ph r%u, r%u, %u", rd, rs, rt);
   7319                      vassert(!mode64);
   7320                      putIReg(rd,
   7321                              binop(Iop_16HLto32,
   7322                                    binop(Iop_8HLto16,
   7323                                          unop(Iop_16HIto8,
   7324                                               unop(Iop_32HIto16, getIReg(rs))),
   7325                                          unop(Iop_16HIto8,
   7326                                               unop(Iop_32to16, getIReg(rs)))),
   7327                                    binop(Iop_8HLto16,
   7328                                          unop(Iop_16HIto8,
   7329                                               unop(Iop_32HIto16, getIReg(rt))),
   7330                                          unop(Iop_16HIto8,
   7331                                               unop(Iop_32to16, getIReg(rt))))));
   7332                      break;
   7333                   }
   7334                   case 0xD: {  /* PRECR.QB.PH */
   7335                      DIP("precr.qb.ph r%u, r%u, r%u", rd, rs, rt);
   7336                      vassert(!mode64);
   7337 
   7338                      putIReg(rd,
   7339                              binop(Iop_16HLto32,
   7340                                    binop(Iop_8HLto16,
   7341                                          unop(Iop_16to8,
   7342                                               unop(Iop_32HIto16, getIReg(rs))),
   7343                                          unop(Iop_16to8,
   7344                                               unop(Iop_32to16, getIReg(rs)))),
   7345                                    binop(Iop_8HLto16,
   7346                                          unop(Iop_16to8,
   7347                                               unop(Iop_32HIto16, getIReg(rt))),
   7348                                          unop(Iop_16to8,
   7349                                               unop(Iop_32to16, getIReg(rt))))));
   7350                      break;
   7351                   }
   7352                   case 0xF: {  /* PRECRQU_S.QB.PH */
   7353                      DIP("precrqu_s.qb.ph r%u, r%u, %u", rd, rs, rt);
   7354                      vassert(!mode64);
   7355                      t0 = newTemp(Ity_I8);
   7356                      t1 = newTemp(Ity_I8);
   7357                      t2 = newTemp(Ity_I8);
   7358                      t3 = newTemp(Ity_I8);
   7359                      t4 = newTemp(Ity_I8);
   7360                      t5 = newTemp(Ity_I32);
   7361                      t6 = newTemp(Ity_I1);
   7362                      t7 = newTemp(Ity_I8);
   7363                      t8 = newTemp(Ity_I1);
   7364                      t9 = newTemp(Ity_I32);
   7365                      t10 = newTemp(Ity_I8);
   7366                      t11 = newTemp(Ity_I1);
   7367                      t12 = newTemp(Ity_I32);
   7368                      t13 = newTemp(Ity_I8);
   7369                      t14 = newTemp(Ity_I1);
   7370                      t15 = newTemp(Ity_I32);
   7371 
   7372                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
   7373                                                  mkU32(0x7f80),
   7374                                                  binop(Iop_And32,
   7375                                                        unop(Iop_16Uto32,
   7376                                                             unop(Iop_32to16,
   7377                                                             getIReg(rs))),
   7378                                                        mkU32(0x7fff))),
   7379                                            mkU8(0xff),
   7380                                            unop(Iop_16HIto8,
   7381                                                 unop(Iop_32to16,
   7382                                                      binop(Iop_Shl32,
   7383                                                            getIReg(rs),
   7384                                                            mkU8(1))))));
   7385                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
   7386                                                  binop(Iop_And32,
   7387                                                        unop(Iop_16Uto32,
   7388                                                             unop(Iop_32to16,
   7389                                                                  getIReg(rs))),
   7390                                                        mkU32(0x00008000)),
   7391                                                  mkU32(0x0)),
   7392                                            mkexpr(t4),
   7393                                            mkU8(0x0)));
   7394                      assign(t5, binop(Iop_And32,
   7395                                       unop(Iop_16Uto32,
   7396                                             unop(Iop_32to16,
   7397                                                  getIReg(rs))),
   7398                                       mkU32(0x00008000)));
   7399                      assign(t6, binop(Iop_CmpLT32U,
   7400                                       mkU32(0x7f80),
   7401                                       binop(Iop_And32,
   7402                                             unop(Iop_16Uto32,
   7403                                                  unop(Iop_32to16,
   7404                                                  getIReg(rs))),
   7405                                             mkU32(0x7fff))));
   7406                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   7407                                                     mkexpr(t5),
   7408                                                     mkU32(0x0)),
   7409                                               IRExpr_ITE(mkexpr(t6),
   7410                                                          binop(Iop_Or32,
   7411                                                                getDSPControl(),
   7412                                                                mkU32(0x00400000)
   7413                                                               ),
   7414                                                          getDSPControl()),
   7415                                               binop(Iop_Or32,
   7416                                                     getDSPControl(),
   7417                                                     mkU32(0x00400000))));
   7418 
   7419                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
   7420                                                  mkU32(0x7f80),
   7421                                                  binop(Iop_And32,
   7422                                                        unop(Iop_16Uto32,
   7423                                                             unop(Iop_32HIto16,
   7424                                                                  getIReg(rs))),
   7425                                                        mkU32(0x7fff))),
   7426                                            mkU8(0xff),
   7427                                            unop(Iop_16HIto8,
   7428                                                 unop(Iop_32HIto16,
   7429                                                      binop(Iop_Shl32,
   7430                                                            getIReg(rs),
   7431                                                            mkU8(1))))));
   7432                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   7433                                                  binop(Iop_And32,
   7434                                                        unop(Iop_16Uto32,
   7435                                                             unop(Iop_32HIto16,
   7436                                                                  getIReg(rs))),
   7437                                                        mkU32(0x00008000)),
   7438                                                  mkU32(0x0)),
   7439                                            mkexpr(t7),
   7440                                            mkU8(0x0)));
   7441                      assign(t8, binop(Iop_CmpEQ32,
   7442                                       binop(Iop_And32,
   7443                                             unop(Iop_16Uto32,
   7444                                                  unop(Iop_32HIto16,
   7445                                                       getIReg(rs))),
   7446                                             mkU32(0x00008000)),
   7447                                       mkU32(0x0)));
   7448                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
   7449                                                  mkU32(0x7f80),
   7450                                                  binop(Iop_And32,
   7451                                                        unop(Iop_16Uto32,
   7452                                                             unop(Iop_32HIto16,
   7453                                                                  getIReg(rs))),
   7454                                                        mkU32(0x7fff))),
   7455                                            binop(Iop_Or32,
   7456                                                  getDSPControl(),
   7457                                                  mkU32(0x00400000)),
   7458                                            getDSPControl()));
   7459                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   7460                                               mkexpr(t9),
   7461                                               binop(Iop_Or32,
   7462                                                     getDSPControl(),
   7463                                                     mkU32(0x00400000))));
   7464 
   7465                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
   7466                                                   mkU32(0x7f80),
   7467                                                   binop(Iop_And32,
   7468                                                         unop(Iop_16Uto32,
   7469                                                              unop(Iop_32to16,
   7470                                                              getIReg(rt))),
   7471                                                         mkU32(0x7fff))),
   7472                                             mkU8(0xff),
   7473                                             unop(Iop_16HIto8,
   7474                                                  unop(Iop_32to16,
   7475                                                       binop(Iop_Shl32,
   7476                                                             getIReg(rt),
   7477                                                             mkU8(1))))));
   7478                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
   7479                                                  binop(Iop_And32,
   7480                                                        unop(Iop_16Uto32,
   7481                                                             unop(Iop_32to16,
   7482                                                                  getIReg(rt))),
   7483                                                        mkU32(0x00008000)),
   7484                                                  mkU32(0x0)),
   7485                                            mkexpr(t10),
   7486                                            mkU8(0x0)));
   7487                      assign(t11, binop(Iop_CmpEQ32,
   7488                                        binop(Iop_And32,
   7489                                              unop(Iop_16Uto32,
   7490                                                   unop(Iop_32to16,
   7491                                                        getIReg(rt))),
   7492                                              mkU32(0x00008000)),
   7493                                        mkU32(0x0)));
   7494                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
   7495                                                   mkU32(0x7f80),
   7496                                                   binop(Iop_And32,
   7497                                                         unop(Iop_16Uto32,
   7498                                                              unop(Iop_32to16,
   7499                                                              getIReg(rt))),
   7500                                                         mkU32(0x7fff))),
   7501                                             binop(Iop_Or32,
   7502                                                   getDSPControl(),
   7503                                                   mkU32(0x00400000)),
   7504                                             getDSPControl()));
   7505                      putDSPControl(IRExpr_ITE(mkexpr(t11),
   7506                                               mkexpr(t12),
   7507                                               binop(Iop_Or32,
   7508                                                     getDSPControl(),
   7509                                                     mkU32(0x00400000))));
   7510 
   7511                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
   7512                                                   mkU32(0x7f80),
   7513                                                   binop(Iop_And32,
   7514                                                         unop(Iop_16Uto32,
   7515                                                              unop(Iop_32HIto16,
   7516                                                                   getIReg(rt))),
   7517                                                         mkU32(0x7fff))),
   7518                                             mkU8(0xff),
   7519                                             unop(Iop_16HIto8,
   7520                                                  unop(Iop_32HIto16,
   7521                                                       binop(Iop_Shl32,
   7522                                                             getIReg(rt),
   7523                                                             mkU8(1))))));
   7524                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   7525                                                  binop(Iop_And32,
   7526                                                        unop(Iop_16Uto32,
   7527                                                             unop(Iop_32HIto16,
   7528                                                                  getIReg(rt))),
   7529                                                        mkU32(0x00008000)),
   7530                                                  mkU32(0x0)),
   7531                                            mkexpr(t13),
   7532                                            mkU8(0x0)));
   7533                      assign(t14, binop(Iop_CmpEQ32,
   7534                                        binop(Iop_And32,
   7535                                              unop(Iop_16Uto32,
   7536                                                   unop(Iop_32HIto16,
   7537                                                        getIReg(rt))),
   7538                                              mkU32(0x00008000)),
   7539                                        mkU32(0x0)));
   7540                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
   7541                                                   mkU32(0x7f80),
   7542                                                   binop(Iop_And32,
   7543                                                         unop(Iop_16Uto32,
   7544                                                              unop(Iop_32HIto16,
   7545                                                                   getIReg(rt))),
   7546                                                         mkU32(0x7fff))),
   7547                                             binop(Iop_Or32,
   7548                                                   getDSPControl(),
   7549                                                   mkU32(0x00400000)),
   7550                                             getDSPControl()));
   7551                      putDSPControl(IRExpr_ITE(mkexpr(t14),
   7552                                               mkexpr(t15),
   7553                                               binop(Iop_Or32,
   7554                                                     getDSPControl(),
   7555                                                     mkU32(0x00400000))));
   7556 
   7557                      putIReg(rd, binop(Iop_16HLto32,
   7558                                        binop(Iop_8HLto16,
   7559                                              mkexpr(t1), mkexpr(t0)),
   7560                                        binop(Iop_8HLto16,
   7561                                              mkexpr(t3), mkexpr(t2))));
   7562                      break;
   7563                   }
   7564                   case 0x14: {  /* PRECRQ.PH.W */
   7565                      DIP("precrq.ph.w r%u, r%u, %u", rd, rs, rt);
   7566                      vassert(!mode64);
   7567                      putIReg(rd, binop(Iop_16HLto32,
   7568                                        unop(Iop_32HIto16, getIReg(rs)),
   7569                                        unop(Iop_32HIto16, getIReg(rt))));
   7570                      break;
   7571                   }
   7572                   case 0x15: {  /* PRECRQ_RS.PH.W */
   7573                      DIP("precrq_rs.ph.w r%u, r%u, %u", rd, rs, rt);
   7574                      vassert(!mode64);
   7575                      t0 = newTemp(Ity_I64);
   7576                      t1 = newTemp(Ity_I1);
   7577                      t2 = newTemp(Ity_I32);
   7578                      t3 = newTemp(Ity_I64);
   7579                      t4 = newTemp(Ity_I1);
   7580                      t5 = newTemp(Ity_I32);
   7581 
   7582                      assign(t0, binop(Iop_Add64,
   7583                                       binop(Iop_32HLto64,
   7584                                             binop(Iop_Shr32,
   7585                                                   binop(Iop_And32,
   7586                                                         getIReg(rs),
   7587                                                         mkU32(0x80000000)),
   7588                                                   mkU8(31)),
   7589                                             getIReg(rs)),
   7590                                       mkU64(0x0000000000008000ULL)));
   7591                      assign(t1, binop(Iop_CmpNE32,
   7592                                       binop(Iop_And32,
   7593                                             unop(Iop_64HIto32, mkexpr(t0)),
   7594                                             mkU32(0x1)),
   7595                                       binop(Iop_And32,
   7596                                             binop(Iop_Shr32,
   7597                                                   unop(Iop_64to32, mkexpr(t0)),
   7598                                                   mkU8(31)),
   7599                                             mkU32(0x1))));
   7600                      assign(t2, IRExpr_ITE(mkexpr(t1),
   7601                                            mkU32(0x7fffffff),
   7602                                            unop(Iop_64to32, mkexpr(t0))));
   7603                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7604                                               binop(Iop_Or32,
   7605                                                     getDSPControl(),
   7606                                                     mkU32(0x400000)),
   7607                                               getDSPControl()));
   7608                      assign(t3, binop(Iop_Add64,
   7609                                       binop(Iop_32HLto64,
   7610                                             binop(Iop_Shr32,
   7611                                                   binop(Iop_And32,
   7612                                                         getIReg(rt),
   7613                                                         mkU32(0x80000000)),
   7614                                                   mkU8(31)),
   7615                                             getIReg(rt)),
   7616                                       mkU64(0x0000000000008000ULL)));
   7617                      assign(t4, binop(Iop_CmpNE32,
   7618                                       binop(Iop_And32,
   7619                                             unop(Iop_64HIto32, mkexpr(t3)),
   7620                                             mkU32(0x1)),
   7621                                       binop(Iop_And32,
   7622                                             binop(Iop_Shr32,
   7623                                                   unop(Iop_64to32, mkexpr(t3)),
   7624                                                   mkU8(31)),
   7625                                             mkU32(0x1))));
   7626                      assign(t5, IRExpr_ITE(mkexpr(t4),
   7627                                            mkU32(0x7fffffff),
   7628                                            unop(Iop_64to32, mkexpr(t3))));
   7629                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7630                                               binop(Iop_Or32,
   7631                                                     getDSPControl(),
   7632                                                     mkU32(0x400000)),
   7633                                               getDSPControl()));
   7634                      putIReg(rd, binop(Iop_16HLto32,
   7635                                        unop(Iop_32HIto16, mkexpr(t2)),
   7636                                        unop(Iop_32HIto16, mkexpr(t5))));
   7637                      break;
   7638                   }
   7639                   case 0x1E: {  /* PRECR_SRA.PH.W */
   7640                      DIP("precr_sra.ph.w r%u, r%u, %u", rt, rs, rd);
   7641                      vassert(!mode64);
   7642 
   7643                      if (0 == rd) {
   7644                         putIReg(rt, binop(Iop_16HLto32,
   7645                                           unop(Iop_32to16, getIReg(rt)),
   7646                                           unop(Iop_32to16, getIReg(rs))));
   7647                      } else {
   7648                         putIReg(rt, binop(Iop_16HLto32,
   7649                                           unop(Iop_32to16, binop(Iop_Sar32,
   7650                                                                  getIReg(rt),
   7651                                                                  mkU8(rd))),
   7652                                           unop(Iop_32to16, binop(Iop_Sar32,
   7653                                                                  getIReg(rs),
   7654                                                                  mkU8(rd)))));
   7655                      }
   7656                      break;
   7657                   }
   7658                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
   7659                      DIP("precr_sra_r.ph.w r%u, r%u, %u", rt, rs, rd);
   7660                      vassert(!mode64);
   7661 
   7662                      t0 = newTemp(Ity_I32);
   7663                      t1 = newTemp(Ity_I32);
   7664 
   7665                      if (0 == rd) {
   7666                         putIReg(rt, binop(Iop_16HLto32,
   7667                                           unop(Iop_32to16, getIReg(rt)),
   7668                                           unop(Iop_32to16, getIReg(rs))));
   7669                      } else {
   7670                         assign(t0, binop(Iop_Shr32,
   7671                                          binop(Iop_Add32,
   7672                                                binop(Iop_Sar32,
   7673                                                      getIReg(rt),
   7674                                                      mkU8(rd-1)),
   7675                                                mkU32(0x1)),
   7676                                          mkU8(0x1)));
   7677                         assign(t1, binop(Iop_Shr32,
   7678                                          binop(Iop_Add32,
   7679                                                binop(Iop_Sar32,
   7680                                                      getIReg(rs),
   7681                                                      mkU8(rd-1)),
   7682                                                mkU32(0x1)),
   7683                                          mkU8(0x1)));
   7684                         putIReg(rt, binop(Iop_16HLto32,
   7685                                           unop(Iop_32to16, mkexpr(t0)),
   7686                                           unop(Iop_32to16, mkexpr(t1))));
   7687                      };
   7688                      break;
   7689                   }
   7690                   case 0xE: {  /* PACKRL.PH */
   7691                      DIP("packrl.ph r%u, r%u, r%u", rd, rs, rt);
   7692                      vassert(!mode64);
   7693 
   7694                      putIReg(rd, binop(Iop_16HLto32,
   7695                                        unop(Iop_32to16, getIReg(rs)),
   7696                                        unop(Iop_32HIto16, getIReg(rt))));
   7697                      break;
   7698                   }
   7699                   case 0x18: {  /* CMPGDU.EQ.QB */
   7700                      DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7701                      vassert(!mode64);
   7702                      t1 = newTemp(Ity_I1);
   7703                      t2 = newTemp(Ity_I1);
   7704                      t3 = newTemp(Ity_I1);
   7705                      t4 = newTemp(Ity_I1);
   7706                      t5 = newTemp(Ity_I32);
   7707                      t6 = newTemp(Ity_I32);
   7708                      t7 = newTemp(Ity_I32);
   7709                      t8 = newTemp(Ity_I32);
   7710 
   7711                      assign(t1,
   7712                             binop(Iop_CmpEQ32,
   7713                                   unop(Iop_8Uto32,
   7714                                        unop(Iop_16to8,
   7715                                             unop(Iop_32to16, getIReg(rs)))),
   7716                                   unop(Iop_8Uto32,
   7717                                        unop(Iop_16to8,
   7718                                             unop(Iop_32to16, getIReg(rt))))));
   7719                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7720                                            mkU32(0x00000001), mkU32(0)));
   7721                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7722                                               binop(Iop_Or32,
   7723                                                     getDSPControl(),
   7724                                                     mkU32(0x01000000)),
   7725                                               binop(Iop_And32,
   7726                                                     getDSPControl(),
   7727                                                     mkU32(0xfeffffff))));
   7728 
   7729                      assign(t2, binop(Iop_CmpEQ32,
   7730                                       unop(Iop_8Uto32,
   7731                                            unop(Iop_16HIto8,
   7732                                                 unop(Iop_32to16, getIReg(rs)))),
   7733                                       unop(Iop_8Uto32,
   7734                                            unop(Iop_16HIto8,
   7735                                                 unop(Iop_32to16,
   7736                                                      getIReg(rt))))));
   7737                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7738                                            mkU32(0x00000002), mkU32(0)));
   7739                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7740                                               binop(Iop_Or32,
   7741                                                     getDSPControl(),
   7742                                                     mkU32(0x02000000)),
   7743                                               binop(Iop_And32,
   7744                                                     getDSPControl(),
   7745                                                     mkU32(0xfdffffff))));
   7746 
   7747                      assign(t3, binop(Iop_CmpEQ32,
   7748                                       unop(Iop_8Uto32,
   7749                                            unop(Iop_16to8,
   7750                                                 unop(Iop_32HIto16,
   7751                                                      getIReg(rs)))),
   7752                                       unop(Iop_8Uto32,
   7753                                            unop(Iop_16to8,
   7754                                                 unop(Iop_32HIto16,
   7755                                                      getIReg(rt))))));
   7756                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7757                                            mkU32(0x00000004), mkU32(0)));
   7758                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7759                                               binop(Iop_Or32,
   7760                                                     getDSPControl(),
   7761                                                     mkU32(0x04000000)),
   7762                                               binop(Iop_And32,
   7763                                                     getDSPControl(),
   7764                                                     mkU32(0xfbffffff))));
   7765 
   7766                      assign(t4, binop(Iop_CmpEQ32,
   7767                                       unop(Iop_8Uto32,
   7768                                            unop(Iop_16HIto8,
   7769                                                 unop(Iop_32HIto16,
   7770                                                      getIReg(rs)))),
   7771                                       unop(Iop_8Uto32,
   7772                                            unop(Iop_16HIto8,
   7773                                                 unop(Iop_32HIto16,
   7774                                                      getIReg(rt))))));
   7775                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7776                                            mkU32(0x00000008), mkU32(0)));
   7777                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7778                                               binop(Iop_Or32,
   7779                                                     getDSPControl(),
   7780                                                     mkU32(0x08000000)),
   7781                                               binop(Iop_And32,
   7782                                                     getDSPControl(),
   7783                                                     mkU32(0xf7ffffff))));
   7784 
   7785                      putIReg(rd, binop(Iop_Or32,
   7786                                        binop(Iop_Or32,
   7787                                              binop(Iop_Or32,
   7788                                                    mkexpr(t5), mkexpr(t6)),
   7789                                              mkexpr(t7)),
   7790                                        mkexpr(t8)));
   7791                      break;
   7792                   }
   7793                   case 0x19: {  /* CMPGDU.LT.QB */
   7794                      DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7795                      vassert(!mode64);
   7796                      t1 = newTemp(Ity_I1);
   7797                      t2 = newTemp(Ity_I1);
   7798                      t3 = newTemp(Ity_I1);
   7799                      t4 = newTemp(Ity_I1);
   7800                      t5 = newTemp(Ity_I32);
   7801                      t6 = newTemp(Ity_I32);
   7802                      t7 = newTemp(Ity_I32);
   7803                      t8 = newTemp(Ity_I32);
   7804 
   7805                      assign(t1, binop(Iop_CmpLT32U,
   7806                                       unop(Iop_8Uto32,
   7807                                            unop(Iop_16to8,
   7808                                                 unop(Iop_32to16, getIReg(rs)))),
   7809                                       unop(Iop_8Uto32,
   7810                                            unop(Iop_16to8,
   7811                                                 unop(Iop_32to16,
   7812                                                      getIReg(rt))))));
   7813                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7814                                            mkU32(0x00000001), mkU32(0)));
   7815                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7816                                               binop(Iop_Or32,
   7817                                                     getDSPControl(),
   7818                                                     mkU32(0x01000000)),
   7819                                               binop(Iop_And32,
   7820                                                     getDSPControl(),
   7821                                                     mkU32(0xfeffffff))));
   7822 
   7823                      assign(t2, binop(Iop_CmpLT32U,
   7824                                       unop(Iop_8Uto32,
   7825                                            unop(Iop_16HIto8,
   7826                                                 unop(Iop_32to16, getIReg(rs)))),
   7827                                       unop(Iop_8Uto32,
   7828                                            unop(Iop_16HIto8,
   7829                                                 unop(Iop_32to16,
   7830                                                      getIReg(rt))))));
   7831                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7832                                            mkU32(0x00000002), mkU32(0)));
   7833                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7834                                               binop(Iop_Or32,
   7835                                                     getDSPControl(),
   7836                                                     mkU32(0x02000000)),
   7837                                               binop(Iop_And32,
   7838                                                     getDSPControl(),
   7839                                                     mkU32(0xfdffffff))));
   7840 
   7841                      assign(t3, binop(Iop_CmpLT32U,
   7842                                       unop(Iop_8Uto32,
   7843                                            unop(Iop_16to8,
   7844                                                 unop(Iop_32HIto16,
   7845                                                      getIReg(rs)))),
   7846                                       unop(Iop_8Uto32,
   7847                                            unop(Iop_16to8,
   7848                                                 unop(Iop_32HIto16,
   7849                                                      getIReg(rt))))));
   7850                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7851                                            mkU32(0x00000004), mkU32(0)));
   7852                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7853                                               binop(Iop_Or32,
   7854                                                     getDSPControl(),
   7855                                                     mkU32(0x04000000)),
   7856                                               binop(Iop_And32,
   7857                                                     getDSPControl(),
   7858                                                     mkU32(0xfbffffff))));
   7859 
   7860                      assign(t4, binop(Iop_CmpLT32U,
   7861                                       unop(Iop_8Uto32,
   7862                                            unop(Iop_16HIto8,
   7863                                                 unop(Iop_32HIto16,
   7864                                                      getIReg(rs)))),
   7865                                       unop(Iop_8Uto32,
   7866                                            unop(Iop_16HIto8,
   7867                                                 unop(Iop_32HIto16,
   7868                                                      getIReg(rt))))));
   7869                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7870                                            mkU32(0x00000008), mkU32(0)));
   7871                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7872                                               binop(Iop_Or32,
   7873                                                     getDSPControl(),
   7874                                                     mkU32(0x08000000)),
   7875                                               binop(Iop_And32,
   7876                                                     getDSPControl(),
   7877                                                     mkU32(0xf7ffffff))));
   7878 
   7879                      putIReg(rd, binop(Iop_Or32,
   7880                                        binop(Iop_Or32,
   7881                                              binop(Iop_Or32,
   7882                                                    mkexpr(t5), mkexpr(t6)),
   7883                                              mkexpr(t7)),
   7884                                        mkexpr(t8)));
   7885                      break;
   7886                   }
   7887                   case 0x1A: {  /* CMPGDU.LE.QB */
   7888                      DIP("cmpgdu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7889                      vassert(!mode64);
   7890                      t1 = newTemp(Ity_I1);
   7891                      t2 = newTemp(Ity_I1);
   7892                      t3 = newTemp(Ity_I1);
   7893                      t4 = newTemp(Ity_I1);
   7894                      t5 = newTemp(Ity_I32);
   7895                      t6 = newTemp(Ity_I32);
   7896                      t7 = newTemp(Ity_I32);
   7897                      t8 = newTemp(Ity_I32);
   7898 
   7899                      assign(t1, binop(Iop_CmpLE32U,
   7900                                       unop(Iop_8Uto32,
   7901                                            unop(Iop_16to8,
   7902                                                 unop(Iop_32to16, getIReg(rs)))),
   7903                                       unop(Iop_8Uto32,
   7904                                            unop(Iop_16to8,
   7905                                                 unop(Iop_32to16,
   7906                                                      getIReg(rt))))));
   7907                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7908                                            mkU32(0x00000001),
   7909                                            mkU32(0)));
   7910                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7911                                               binop(Iop_Or32,
   7912                                                     getDSPControl(),
   7913                                                     mkU32(0x01000000)),
   7914                                               binop(Iop_And32,
   7915                                                     getDSPControl(),
   7916                                                     mkU32(0xfeffffff))));
   7917 
   7918                      assign(t2, binop(Iop_CmpLE32U,
   7919                                       unop(Iop_8Uto32,
   7920                                            unop(Iop_16HIto8,
   7921                                                 unop(Iop_32to16, getIReg(rs)))),
   7922                                       unop(Iop_8Uto32,
   7923                                            unop(Iop_16HIto8,
   7924                                                 unop(Iop_32to16,
   7925                                                      getIReg(rt))))));
   7926                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7927                                            mkU32(0x00000002), mkU32(0)));
   7928                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7929                                               binop(Iop_Or32,
   7930                                                     getDSPControl(),
   7931                                                     mkU32(0x02000000)),
   7932                                               binop(Iop_And32,
   7933                                                     getDSPControl(),
   7934                                                     mkU32(0xfdffffff))));
   7935 
   7936                      assign(t3, binop(Iop_CmpLE32U,
   7937                                       unop(Iop_8Uto32,
   7938                                            unop(Iop_16to8,
   7939                                                 unop(Iop_32HIto16,
   7940                                                      getIReg(rs)))),
   7941                                       unop(Iop_8Uto32,
   7942                                            unop(Iop_16to8,
   7943                                                 unop(Iop_32HIto16,
   7944                                                      getIReg(rt))))));
   7945                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7946                                            mkU32(0x00000004), mkU32(0)));
   7947                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7948                                               binop(Iop_Or32,
   7949                                                     getDSPControl(),
   7950                                                     mkU32(0x04000000)),
   7951                                               binop(Iop_And32,
   7952                                                     getDSPControl(),
   7953                                                     mkU32(0xfbffffff))));
   7954 
   7955                      assign(t4, binop(Iop_CmpLE32U,
   7956                                       unop(Iop_8Uto32,
   7957                                            unop(Iop_16HIto8,
   7958                                                 unop(Iop_32HIto16,
   7959                                                      getIReg(rs)))),
   7960                                       unop(Iop_8Uto32,
   7961                                            unop(Iop_16HIto8,
   7962                                                 unop(Iop_32HIto16,
   7963                                                      getIReg(rt))))));
   7964                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7965                                            mkU32(0x00000008), mkU32(0)));
   7966                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7967                                               binop(Iop_Or32,
   7968                                                     getDSPControl(),
   7969                                                     mkU32(0x08000000)),
   7970                                               binop(Iop_And32,
   7971                                                     getDSPControl(),
   7972                                                     mkU32(0xf7ffffff))));
   7973 
   7974                      putIReg(rd, binop(Iop_Or32,
   7975                                        binop(Iop_Or32,
   7976                                              binop(Iop_Or32,
   7977                                                    mkexpr(t5), mkexpr(t6)),
   7978                                              mkexpr(t7)),
   7979                                        mkexpr(t8)));
   7980                      break;
   7981                   }
   7982                   default:
   7983                      return -1;
   7984                }
   7985                break;  /* end of CMPU.EQ.QB */
   7986             }
   7987             case 0x13: {  /* SHLL.QB */
   7988                switch(sa) {
   7989                   case 0x0: {  /* SHLL.QB */
   7990                      DIP("shll.qb r%u, r%u, %u", rd, rt, rs);
   7991                      vassert(!mode64);
   7992                      t0 = newTemp(Ity_I32);
   7993                      t1 = newTemp(Ity_I1);
   7994                      t2 = newTemp(Ity_I1);
   7995                      t3 = newTemp(Ity_I32);
   7996                      t4 = newTemp(Ity_I1);
   7997                      t5 = newTemp(Ity_I1);
   7998                      t6 = newTemp(Ity_I32);
   7999                      t7 = newTemp(Ity_I1);
   8000                      t8 = newTemp(Ity_I1);
   8001                      t9 = newTemp(Ity_I1);
   8002                      t10 = newTemp(Ity_I1);
   8003 
   8004                      if (0 == rs) {
   8005                         putIReg(rd, getIReg(rt));
   8006                      } else {
   8007                         /* Shift bits 7..0 and 23..16. */
   8008                         assign(t0, binop(Iop_Shl32,
   8009                                          binop(Iop_And32,
   8010                                                getIReg(rt),
   8011                                                mkU32(0x00ff00ff)),
   8012                                          mkU8(rs)));
   8013                         assign(t1, binop(Iop_CmpNE32,
   8014                                         binop(Iop_And32,
   8015                                               mkexpr(t0),
   8016                                               mkU32(0xff000000)),
   8017                                         mkU32(0x00000000)));
   8018                         assign(t2, binop(Iop_CmpNE32,
   8019                                         binop(Iop_And32,
   8020                                               mkexpr(t0),
   8021                                               mkU32(0xff000000)),
   8022                                         mkU32(0xff000000)));
   8023                         assign(t7, binop(Iop_CmpNE32,
   8024                                         binop(Iop_And32,
   8025                                               mkexpr(t0),
   8026                                               mkU32(0x0000ff00)),
   8027                                         mkU32(0x00000000)));
   8028                         assign(t8, binop(Iop_CmpNE32,
   8029                                         binop(Iop_And32,
   8030                                               mkexpr(t0),
   8031                                               mkU32(0x0000ff00)),
   8032                                         mkU32(0x000ff00)));
   8033                         /* Shift bits 15..8 and 31..24. */
   8034                         assign(t3, binop(Iop_Shl32,
   8035                                          binop(Iop_Shr32,
   8036                                                binop(Iop_And32,
   8037                                                      getIReg(rt),
   8038                                                      mkU32(0xff00ff00)),
   8039                                                mkU8(8)),
   8040                                          mkU8(rs)));
   8041                         assign(t4, binop(Iop_CmpNE32,
   8042                                         binop(Iop_And32,
   8043                                               mkexpr(t3),
   8044                                               mkU32(0xff000000)),
   8045                                         mkU32(0x00000000)));
   8046                         assign(t5, binop(Iop_CmpNE32,
   8047                                         binop(Iop_And32,
   8048                                               mkexpr(t3),
   8049                                               mkU32(0xff000000)),
   8050                                         mkU32(0xff000000)));
   8051                         assign(t9, binop(Iop_CmpNE32,
   8052                                         binop(Iop_And32,
   8053                                               mkexpr(t3),
   8054                                               mkU32(0x0000ff00)),
   8055                                         mkU32(0x00000000)));
   8056                         assign(t10, binop(Iop_CmpNE32,
   8057                                         binop(Iop_And32,
   8058                                               mkexpr(t3),
   8059                                               mkU32(0x0000ff00)),
   8060                                         mkU32(0x0000ff00)));
   8061 
   8062                         assign(t6, binop(Iop_Or32,
   8063                                          binop(Iop_Or32,
   8064                                                binop(Iop_And32,
   8065                                                      unop(Iop_1Uto32,
   8066                                                           mkexpr(t1)),
   8067                                                      unop(Iop_1Uto32,
   8068                                                           mkexpr(t2))),
   8069                                                binop(Iop_And32,
   8070                                                      unop(Iop_1Uto32,
   8071                                                           mkexpr(t7)),
   8072                                                      unop(Iop_1Uto32,
   8073                                                           mkexpr(t8)))),
   8074                                          binop(Iop_Or32,
   8075                                                binop(Iop_And32,
   8076                                                      unop(Iop_1Uto32,
   8077                                                           mkexpr(t4)),
   8078                                                      unop(Iop_1Uto32,
   8079                                                           mkexpr(t5))),
   8080                                                binop(Iop_And32,
   8081                                                      unop(Iop_1Uto32,
   8082                                                           mkexpr(t9)),
   8083                                                      unop(Iop_1Uto32,
   8084                                                           mkexpr(t10))))));
   8085 
   8086                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8087                                                        mkexpr(t6),
   8088                                                        mkU32(0x0)),
   8089                                                  binop(Iop_Or32,
   8090                                                        getDSPControl(),
   8091                                                        mkU32(0x400000)),
   8092                                                  getDSPControl()));
   8093                         putIReg(rd, binop(Iop_Or32,
   8094                                           binop(Iop_Shl32,
   8095                                                 binop(Iop_And32,
   8096                                                       mkexpr(t3),
   8097                                                       mkU32(0x00ff00ff)),
   8098                                                 mkU8(8)),
   8099                                           binop(Iop_And32,
   8100                                                 mkexpr(t0),
   8101                                                 mkU32(0x00ff00ff))));
   8102                      }
   8103                      break;
   8104                   }
   8105                   case 0x3: {  /* SHRL.QB */
   8106                      DIP("shrl.qb r%u, r%u, %u", rd, rt, rs);
   8107                      vassert(!mode64);
   8108                      t0 = newTemp(Ity_I32);
   8109                      t1 = newTemp(Ity_I8);
   8110                      t2 = newTemp(Ity_I32);
   8111                      t3 = newTemp(Ity_I8);
   8112                      t4 = newTemp(Ity_I32);
   8113                      t5 = newTemp(Ity_I8);
   8114                      t6 = newTemp(Ity_I32);
   8115                      t7 = newTemp(Ity_I8);
   8116                      t9 = newTemp(Ity_I32);
   8117 
   8118                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8119                      assign(t0, unop(Iop_8Uto32,
   8120                                      unop(Iop_16to8,
   8121                                           unop(Iop_32to16, getIReg(rt)))));
   8122                      assign(t1, unop(Iop_32to8,
   8123                                      binop(Iop_Shr32,
   8124                                            mkexpr(t0),
   8125                                            unop(Iop_32to8, mkexpr(t9)))));
   8126 
   8127                      assign(t2, unop(Iop_8Uto32,
   8128                                      unop(Iop_16HIto8,
   8129                                           unop(Iop_32to16, getIReg(rt)))));
   8130                      assign(t3, unop(Iop_32to8,
   8131                                      binop(Iop_Shr32,
   8132                                            mkexpr(t2),
   8133                                            unop(Iop_32to8, mkexpr(t9)))));
   8134 
   8135                      assign(t4, unop(Iop_8Uto32,
   8136                                      unop(Iop_16to8,
   8137                                           unop(Iop_32HIto16, getIReg(rt)))));
   8138                      assign(t5, unop(Iop_32to8,
   8139                                      binop(Iop_Shr32,
   8140                                            mkexpr(t4),
   8141                                            unop(Iop_32to8, mkexpr(t9)))));
   8142 
   8143                      assign(t6, unop(Iop_8Uto32,
   8144                                      unop(Iop_16HIto8,
   8145                                           unop(Iop_32HIto16, getIReg(rt)))));
   8146                      assign(t7, unop(Iop_32to8,
   8147                                      binop(Iop_Shr32,
   8148                                            mkexpr(t6),
   8149                                            unop(Iop_32to8, mkexpr(t9)))));
   8150                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8151                                                   mkexpr(t9),
   8152                                                   mkU32(0x0)),
   8153                                             getIReg(rt),
   8154                                             binop(Iop_16HLto32,
   8155                                                   binop(Iop_8HLto16,
   8156                                                         mkexpr(t7),
   8157                                                         mkexpr(t5)),
   8158                                                   binop(Iop_8HLto16,
   8159                                                         mkexpr(t3),
   8160                                                         mkexpr(t1)))));
   8161                      break;
   8162                   }
   8163                   case 0x2: {  /* SHLLV.QB */
   8164                      DIP("shllv.qb r%u, r%u, r%u", rd, rt, rs);
   8165                      vassert(!mode64);
   8166                      t0 = newTemp(Ity_I32);
   8167                      t1 = newTemp(Ity_I1);
   8168                      t2 = newTemp(Ity_I1);
   8169                      t3 = newTemp(Ity_I32);
   8170                      t4 = newTemp(Ity_I1);
   8171                      t5 = newTemp(Ity_I1);
   8172                      t6 = newTemp(Ity_I32);
   8173                      t7 = newTemp(Ity_I1);
   8174                      t8 = newTemp(Ity_I1);
   8175                      t9 = newTemp(Ity_I1);
   8176                      t10 = newTemp(Ity_I1);
   8177                      t11 = newTemp(Ity_I8);
   8178 
   8179                      assign(t11, unop(Iop_32to8,
   8180                                       binop(Iop_And32,
   8181                                             getIReg(rs),
   8182                                             mkU32(0x7))));
   8183                      /* Shift bits 7..0 and 23..16. */
   8184                      assign(t0, binop(Iop_Shl32,
   8185                                       binop(Iop_And32,
   8186                                             getIReg(rt),
   8187                                             mkU32(0x00ff00ff)),
   8188                                       mkexpr(t11)));
   8189                      assign(t1, binop(Iop_CmpNE32,
   8190                                      binop(Iop_And32,
   8191                                            mkexpr(t0),
   8192                                            mkU32(0xff000000)),
   8193                                      mkU32(0x00000000)));
   8194                      assign(t2, binop(Iop_CmpNE32,
   8195                                      binop(Iop_And32,
   8196                                            mkexpr(t0),
   8197                                            mkU32(0xff000000)),
   8198                                      mkU32(0xff000000)));
   8199                      assign(t7, binop(Iop_CmpNE32,
   8200                                      binop(Iop_And32,
   8201                                            mkexpr(t0),
   8202                                            mkU32(0x0000ff00)),
   8203                                      mkU32(0x00000000)));
   8204                      assign(t8, binop(Iop_CmpNE32,
   8205                                      binop(Iop_And32,
   8206                                            mkexpr(t0),
   8207                                            mkU32(0x0000ff00)),
   8208                                      mkU32(0x000ff00)));
   8209                      /* Shift bits 15..8 and 31..24. */
   8210                      assign(t3, binop(Iop_Shl32,
   8211                                       binop(Iop_Shr32,
   8212                                             binop(Iop_And32,
   8213                                                   getIReg(rt),
   8214                                                   mkU32(0xff00ff00)),
   8215                                             mkU8(8)),
   8216                                       mkexpr(t11)));
   8217                      assign(t4, binop(Iop_CmpNE32,
   8218                                      binop(Iop_And32,
   8219                                            mkexpr(t3),
   8220                                            mkU32(0xff000000)),
   8221                                      mkU32(0x00000000)));
   8222                      assign(t5, binop(Iop_CmpNE32,
   8223                                      binop(Iop_And32,
   8224                                            mkexpr(t3),
   8225                                            mkU32(0xff000000)),
   8226                                      mkU32(0xff000000)));
   8227                      assign(t9, binop(Iop_CmpNE32,
   8228                                      binop(Iop_And32,
   8229                                            mkexpr(t3),
   8230                                            mkU32(0x0000ff00)),
   8231                                      mkU32(0x00000000)));
   8232                      assign(t10, binop(Iop_CmpNE32,
   8233                                      binop(Iop_And32,
   8234                                            mkexpr(t3),
   8235                                            mkU32(0x0000ff00)),
   8236                                      mkU32(0x0000ff00)));
   8237 
   8238                      assign(t6, binop(Iop_Or32,
   8239                                       binop(Iop_Or32,
   8240                                             binop(Iop_And32,
   8241                                                   unop(Iop_1Uto32,
   8242                                                        mkexpr(t1)),
   8243                                                   unop(Iop_1Uto32,
   8244                                                        mkexpr(t2))),
   8245                                             binop(Iop_And32,
   8246                                                   unop(Iop_1Uto32,
   8247                                                        mkexpr(t7)),
   8248                                                   unop(Iop_1Uto32,
   8249                                                        mkexpr(t8)))),
   8250                                       binop(Iop_Or32,
   8251                                             binop(Iop_And32,
   8252                                                   unop(Iop_1Uto32,
   8253                                                        mkexpr(t4)),
   8254                                                   unop(Iop_1Uto32,
   8255                                                        mkexpr(t5))),
   8256                                             binop(Iop_And32,
   8257                                                   unop(Iop_1Uto32,
   8258                                                        mkexpr(t9)),
   8259                                                   unop(Iop_1Uto32,
   8260                                                        mkexpr(t10))))));
   8261 
   8262                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8263                                                     mkexpr(t6),
   8264                                                     mkU32(0x0)),
   8265                                               binop(Iop_Or32,
   8266                                                     getDSPControl(),
   8267                                                     mkU32(0x400000)),
   8268                                               getDSPControl()));
   8269                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8270                                                   unop(Iop_8Uto32, mkexpr(t11)),
   8271                                                   mkU32(0)),
   8272                                             getIReg(rt),
   8273                                             binop(Iop_Or32,
   8274                                                   binop(Iop_Shl32,
   8275                                                         binop(Iop_And32,
   8276                                                               mkexpr(t3),
   8277                                                               mkU32(0xff00ff)),
   8278                                                         mkU8(8)),
   8279                                                   binop(Iop_And32,
   8280                                                         mkexpr(t0),
   8281                                                         mkU32(0x00ff00ff)))));
   8282                      break;
   8283                   }
   8284                   case 0x1: {  /* SHRLV.QB */
   8285                      DIP("shrlv.qb r%u, r%u, r%u", rd, rt, rs);
   8286                      vassert(!mode64);
   8287                      t0 = newTemp(Ity_I8);
   8288                      t1 = newTemp(Ity_I8);
   8289                      t2 = newTemp(Ity_I8);
   8290                      t3 = newTemp(Ity_I8);
   8291 
   8292                      assign(t0, unop(Iop_32to8,
   8293                                      binop(Iop_Shr32,
   8294                                            unop(Iop_8Uto32,
   8295                                                 unop(Iop_32to8, getIReg(rt))),
   8296                                            mkU8(rs))));
   8297                      assign(t1, unop(Iop_32to8,
   8298                                      binop(Iop_Shr32,
   8299                                            unop(Iop_8Uto32,
   8300                                                 unop(Iop_16HIto8,
   8301                                                      unop(Iop_32to16,
   8302                                                           getIReg(rt)))),
   8303                                            mkU8(rs))));
   8304                      assign(t2, unop(Iop_32to8,
   8305                                       binop(Iop_Shr32,
   8306                                             unop(Iop_8Uto32,
   8307                                                  unop(Iop_16to8,
   8308                                                       unop(Iop_32HIto16,
   8309                                                            getIReg(rt)))),
   8310                                             mkU8(rs))));
   8311                      assign(t3, unop(Iop_32to8,
   8312                                      binop(Iop_Shr32,
   8313                                            unop(Iop_8Uto32,
   8314                                                 unop(Iop_16HIto8,
   8315                                                      unop(Iop_32HIto16,
   8316                                                           getIReg(rt)))),
   8317                                            mkU8(rs))));
   8318                      putIReg(rd,
   8319                              binop(Iop_16HLto32,
   8320                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
   8321                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
   8322                      break;
   8323                   }
   8324                   case 0x4: {  /* SHRA.QB */
   8325                      DIP("shra.qb r%u, r%u, %u", rd, rt, rs);
   8326                      vassert(!mode64);
   8327                      t0 = newTemp(Ity_I32);
   8328                      t1 = newTemp(Ity_I32);
   8329                      t2 = newTemp(Ity_I32);
   8330                      t3 = newTemp(Ity_I32);
   8331                      t4 = newTemp(Ity_I32);
   8332                      t5 = newTemp(Ity_I32);
   8333                      t6 = newTemp(Ity_I32);
   8334                      t7 = newTemp(Ity_I32);
   8335                      t8 = newTemp(Ity_I32);
   8336                      t9 = newTemp(Ity_I32);
   8337                      t10 = newTemp(Ity_I32);
   8338                      t11 = newTemp(Ity_I32);
   8339 
   8340                      /* ========== GPR[rt]_31..24 ========== */
   8341                      assign(t1,
   8342                             unop(Iop_8Uto32,
   8343                                  unop(Iop_16HIto8,
   8344                                       unop(Iop_32HIto16, getIReg(rt)))));
   8345                      assign(t2,
   8346                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
   8347                      /* tempD_7..0 */
   8348                      assign(t0,
   8349                             binop(Iop_Or32,
   8350                                   mkexpr(t2),
   8351                                   binop(Iop_Shl32,
   8352                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8353                                                          binop(Iop_And32,
   8354                                                                mkexpr(t1),
   8355                                                                mkU32(0x00000080)
   8356                                                               ),
   8357                                                          mkU32(0x00000080)),
   8358                                                    mkU32(0xFFFFFFFF),
   8359                                                    mkU32(0x00000000)),
   8360                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8361 
   8362                      /* ========== GPR[rt]_23..16 ========== */
   8363                      assign(t4,
   8364                             unop(Iop_8Uto32,
   8365                                  unop(Iop_16to8,
   8366                                       unop(Iop_32HIto16, getIReg(rt)))));
   8367                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
   8368                      /* tempC_7..0 */
   8369                      assign(t3,
   8370                             binop(Iop_Or32,
   8371                                   mkexpr(t5),
   8372                                   binop(Iop_Shl32,
   8373                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8374                                                          binop(Iop_And32,
   8375                                                                mkexpr(t4),
   8376                                                                mkU32(0x00000080)
   8377                                                               ),
   8378                                                          mkU32(0x00000080)),
   8379                                                    mkU32(0xFFFFFFFF),
   8380                                                    mkU32(0x00000000)),
   8381                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8382 
   8383                      /* ========== GPR[rt]_15..8 ========== */
   8384                      assign(t7,
   8385                             unop(Iop_8Uto32,
   8386                                  unop(Iop_16HIto8,
   8387                                       unop(Iop_32to16, getIReg(rt)))));
   8388                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
   8389                      /* tempB_7..0 */
   8390                      assign(t6,
   8391                             binop(Iop_Or32,
   8392                                   mkexpr(t8),
   8393                                   binop(Iop_Shl32,
   8394                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8395                                                          binop(Iop_And32,
   8396                                                                mkexpr(t7),
   8397                                                                mkU32(0x00000080)
   8398                                                               ),
   8399                                                          mkU32(0x00000080)),
   8400                                                    mkU32(0xFFFFFFFF),
   8401                                                    mkU32(0x00000000)),
   8402                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8403 
   8404                      /* ========== GPR[rt]_7..0 ========== */
   8405                      assign(t10,
   8406                             unop(Iop_8Uto32,
   8407                                  unop(Iop_16to8,
   8408                                       unop(Iop_32to16, getIReg(rt)))));
   8409                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
   8410                      /* tempB_7..0 */
   8411                      assign(t9,
   8412                             binop(Iop_Or32,
   8413                                   mkexpr(t11),
   8414                                   binop(Iop_Shl32,
   8415                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8416                                                          binop(Iop_And32,
   8417                                                                mkexpr(t10),
   8418                                                                mkU32(0x00000080)
   8419                                                               ),
   8420                                                          mkU32(0x00000080)),
   8421                                                    mkU32(0xFFFFFFFF),
   8422                                                    mkU32(0x00000000)),
   8423                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8424 
   8425                      putIReg(rd,
   8426                              binop(Iop_16HLto32,
   8427                                    binop(Iop_8HLto16,
   8428                                          unop(Iop_32to8, mkexpr(t0)),
   8429                                          unop(Iop_32to8, mkexpr(t3))),
   8430                                    binop(Iop_8HLto16,
   8431                                          unop(Iop_32to8, mkexpr(t6)),
   8432                                          unop(Iop_32to8, mkexpr(t9)))));
   8433                      break;
   8434                   }
   8435                   case 0x5: {  /* SHRA_R.QB */
   8436                      DIP("shra_r.qb r%u, r%u, %u", rd, rt, rs);
   8437                      vassert(!mode64);
   8438                      t0 = newTemp(Ity_I32);
   8439                      t1 = newTemp(Ity_I8);
   8440                      t2 = newTemp(Ity_I32);
   8441                      t3 = newTemp(Ity_I8);
   8442                      t4 = newTemp(Ity_I32);
   8443                      t5 = newTemp(Ity_I8);
   8444                      t6 = newTemp(Ity_I32);
   8445                      t7 = newTemp(Ity_I8);
   8446 
   8447                      if (0 == rs) {
   8448                         putIReg(rd, getIReg(rt));
   8449                      } else {
   8450                         assign(t0, unop(Iop_8Sto32,
   8451                                         unop(Iop_16to8,
   8452                                              unop(Iop_32to16, getIReg(rt)))));
   8453                         assign(t1, unop(Iop_32to8,
   8454                                         binop(Iop_Sar32,
   8455                                               binop(Iop_Add32,
   8456                                                     mkexpr(t0),
   8457                                                     binop(Iop_Shl32,
   8458                                                           mkU32(0x1),
   8459                                                           mkU8(rs-1))),
   8460                                               mkU8(rs))));
   8461 
   8462                         assign(t2, unop(Iop_8Sto32,
   8463                                         unop(Iop_16HIto8,
   8464                                              unop(Iop_32to16, getIReg(rt)))));
   8465                         assign(t3, unop(Iop_32to8,
   8466                                         binop(Iop_Sar32,
   8467                                               binop(Iop_Add32,
   8468                                                     mkexpr(t2),
   8469                                                     binop(Iop_Shl32,
   8470                                                           mkU32(0x1),
   8471                                                           mkU8(rs-1))),
   8472                                               mkU8(rs))));
   8473 
   8474                         assign(t4, unop(Iop_8Sto32,
   8475                                         unop(Iop_16to8,
   8476                                              unop(Iop_32HIto16, getIReg(rt)))));
   8477                         assign(t5, unop(Iop_32to8,
   8478                                         binop(Iop_Sar32,
   8479                                               binop(Iop_Add32,
   8480                                                     mkexpr(t4),
   8481                                                     binop(Iop_Shl32,
   8482                                                           mkU32(0x1),
   8483                                                           mkU8(rs-1))),
   8484                                               mkU8(rs))));
   8485 
   8486                         assign(t6, unop(Iop_8Sto32,
   8487                                         unop(Iop_16HIto8,
   8488                                              unop(Iop_32HIto16, getIReg(rt)))));
   8489                         assign(t7, unop(Iop_32to8,
   8490                                         binop(Iop_Sar32,
   8491                                               binop(Iop_Add32,
   8492                                                     mkexpr(t6),
   8493                                                     binop(Iop_Shl32,
   8494                                                           mkU32(0x1),
   8495                                                           mkU8(rs-1))),
   8496                                               mkU8(rs))));
   8497                         putIReg(rd, binop(Iop_16HLto32,
   8498                                          binop(Iop_8HLto16,
   8499                                                mkexpr(t7), mkexpr(t5)),
   8500                                          binop(Iop_8HLto16,
   8501                                                mkexpr(t3), mkexpr(t1))));
   8502                      }
   8503                      break;
   8504                   }
   8505                   case 0x6: {  /* SHRAV.QB */
   8506                      DIP("shrav.qb r%u, r%u, %u", rd, rt, rs);
   8507                      vassert(!mode64);
   8508 
   8509                      t0 = newTemp(Ity_I32);
   8510                      t1 = newTemp(Ity_I32);
   8511                      t2 = newTemp(Ity_I32);
   8512 
   8513                      t3 = newTemp(Ity_I32);
   8514                      t4 = newTemp(Ity_I32);
   8515                      t5 = newTemp(Ity_I32);
   8516 
   8517                      t6 = newTemp(Ity_I32);
   8518                      t7 = newTemp(Ity_I32);
   8519                      t8 = newTemp(Ity_I32);
   8520 
   8521                      t9 = newTemp(Ity_I32);
   8522                      t10 = newTemp(Ity_I32);
   8523                      t11 = newTemp(Ity_I32);
   8524 
   8525                      /* ========== GPR[rt]_31..24 ========== */
   8526                      assign(t1,
   8527                             unop(Iop_8Uto32,
   8528                                  unop(Iop_16HIto8,
   8529                                       unop(Iop_32HIto16, getIReg(rt)))));
   8530                      assign(t2,
   8531                             binop(Iop_Shr32,
   8532                                   mkexpr(t1),
   8533                                   unop(Iop_32to8, binop(Iop_And32,
   8534                                                         getIReg(rs),
   8535                                                         mkU32(0x7)))));
   8536                      /* tempD_7..0 */
   8537                      assign(t0,
   8538                             binop(Iop_Or32,
   8539                                   mkexpr(t2),
   8540                                   binop(Iop_Shl32,
   8541                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8542                                                          binop(Iop_And32,
   8543                                                                mkexpr(t1),
   8544                                                                mkU32(0x00000080)
   8545                                                               ),
   8546                                                          mkU32(0x00000080)),
   8547                                                    mkU32(0xFFFFFFFF),
   8548                                                    mkU32(0x00000000)),
   8549                                         binop(Iop_Sub8,
   8550                                               mkU8(0x8),
   8551                                               unop(Iop_32to8, binop(Iop_And32,
   8552                                                                     getIReg(rs),
   8553                                                                     mkU32(0x7)))
   8554                                               ))));
   8555 
   8556                      /* ========== GPR[rt]_23..16 ========== */
   8557                      assign(t4,
   8558                             unop(Iop_8Uto32,
   8559                                  unop(Iop_16to8,
   8560                                       unop(Iop_32HIto16, getIReg(rt)))));
   8561                      assign(t5,
   8562                             binop(Iop_Shr32,
   8563                                   mkexpr(t4),
   8564                                   unop(Iop_32to8, binop(Iop_And32,
   8565                                                         getIReg(rs),
   8566                                                         mkU32(0x7)))));
   8567                      /* tempC_7..0 */
   8568                      assign(t3,
   8569                             binop(Iop_Or32,
   8570                                   mkexpr(t5),
   8571                                   binop(Iop_Shl32,
   8572                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8573                                                          binop(Iop_And32,
   8574                                                                mkexpr(t4),
   8575                                                                mkU32(0x00000080)
   8576                                                               ),
   8577                                                          mkU32(0x00000080)),
   8578                                                    mkU32(0xFFFFFFFF),
   8579                                                    mkU32(0x00000000)),
   8580                                         binop(Iop_Sub8,
   8581                                               mkU8(0x8),
   8582                                               unop(Iop_32to8, binop(Iop_And32,
   8583                                                                     getIReg(rs),
   8584                                                                     mkU32(0x7)))
   8585                                               ))));
   8586 
   8587                      /* ========== GPR[rt]_15..8 ========== */
   8588                      assign(t7,
   8589                             unop(Iop_8Uto32,
   8590                                  unop(Iop_16HIto8,
   8591                                       unop(Iop_32to16, getIReg(rt)))));
   8592                      assign(t8,
   8593                             binop(Iop_Shr32,
   8594                                   mkexpr(t7),
   8595                                   unop(Iop_32to8, binop(Iop_And32,
   8596                                                         getIReg(rs),
   8597                                                         mkU32(0x7)))));
   8598                      /* tempB_7..0 */
   8599                      assign(t6,
   8600                             binop(Iop_Or32,
   8601                                   mkexpr(t8),
   8602                                   binop(Iop_Shl32,
   8603                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8604                                                          binop(Iop_And32,
   8605                                                                mkexpr(t7),
   8606                                                                mkU32(0x00000080)
   8607                                                               ),
   8608                                                          mkU32(0x00000080)),
   8609                                                    mkU32(0xFFFFFFFF),
   8610                                                    mkU32(0x00000000)),
   8611                                         binop(Iop_Sub8,
   8612                                               mkU8(0x8),
   8613                                               unop(Iop_32to8, binop(Iop_And32,
   8614                                                                     getIReg(rs),
   8615                                                                     mkU32(0x7)))
   8616                                               ))));
   8617 
   8618                      /* ========== GPR[rt]_7..0 ========== */
   8619                      assign(t10,
   8620                             unop(Iop_8Uto32,
   8621                                  unop(Iop_16to8,
   8622                                       unop(Iop_32to16, getIReg(rt)))));
   8623                      assign(t11,
   8624                             binop(Iop_Shr32,
   8625                                   mkexpr(t10),
   8626                                   unop(Iop_32to8, binop(Iop_And32,
   8627                                                         getIReg(rs),
   8628                                                         mkU32(0x7)))));
   8629                      /* tempB_7..0 */
   8630                      assign(t9,
   8631                             binop(Iop_Or32,
   8632                                   mkexpr(t11),
   8633                                   binop(Iop_Shl32,
   8634                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8635                                                          binop(Iop_And32,
   8636                                                                mkexpr(t10),
   8637                                                                mkU32(0x00000080)
   8638                                                               ),
   8639                                                          mkU32(0x00000080)),
   8640                                                    mkU32(0xFFFFFFFF),
   8641                                                    mkU32(0x00000000)),
   8642                                         binop(Iop_Sub8,
   8643                                               mkU8(0x8),
   8644                                               unop(Iop_32to8, binop(Iop_And32,
   8645                                                                     getIReg(rs),
   8646                                                                     mkU32(0x7)))
   8647                                               ))));
   8648 
   8649                      putIReg(rd,
   8650                              binop(Iop_16HLto32,
   8651                                    binop(Iop_8HLto16,
   8652                                          unop(Iop_32to8,
   8653                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8654                                                                binop(Iop_And32,
   8655                                                                      mkU32(rs),
   8656                                                                      mkU32(0x7)
   8657                                                                     ),
   8658                                                                mkU32(0x0)),
   8659                                                          mkexpr(t1),
   8660                                                          mkexpr(t0))),
   8661                                          unop(Iop_32to8,
   8662                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8663                                                                binop(Iop_And32,
   8664                                                                      mkU32(rs),
   8665                                                                      mkU32(0x7)
   8666                                                                     ),
   8667                                                                mkU32(0x0)),
   8668                                                          mkexpr(t2),
   8669                                                          mkexpr(t3)))),
   8670                                    binop(Iop_8HLto16,
   8671                                          unop(Iop_32to8,
   8672                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8673                                                                binop(Iop_And32,
   8674                                                                      mkU32(rs),
   8675                                                                      mkU32(0x7)
   8676                                                                     ),
   8677                                                                mkU32(0x0)),
   8678                                                          mkexpr(t5),
   8679                                                          mkexpr(t6))),
   8680                                          unop(Iop_32to8,
   8681                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8682                                                                binop(Iop_And32,
   8683                                                                      mkU32(rs),
   8684                                                                      mkU32(0x7)
   8685                                                                     ),
   8686                                                                mkU32(0x0)),
   8687                                                          mkexpr(t8),
   8688                                                          mkexpr(t9))))));
   8689                      break;
   8690                   }
   8691                   case 0x7: {  /* SHRAV_R.QB */
   8692                      DIP("shrav_r.qb r%u, r%u, r%u", rd, rt, rs);
   8693                      vassert(!mode64);
   8694                      t0 = newTemp(Ity_I32);
   8695                      t1 = newTemp(Ity_I8);
   8696                      t2 = newTemp(Ity_I32);
   8697                      t3 = newTemp(Ity_I8);
   8698                      t4 = newTemp(Ity_I32);
   8699                      t5 = newTemp(Ity_I8);
   8700                      t6 = newTemp(Ity_I32);
   8701                      t7 = newTemp(Ity_I8);
   8702                      t8 = newTemp(Ity_I8);
   8703                      t9 = newTemp(Ity_I32);
   8704 
   8705                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8706                      assign(t8, unop(Iop_32to8,
   8707                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
   8708                      assign(t0, unop(Iop_8Sto32,
   8709                                      unop(Iop_16to8,
   8710                                           unop(Iop_32to16, getIReg(rt)))));
   8711                      assign(t1, unop(Iop_32to8,
   8712                                      binop(Iop_Sar32,
   8713                                            binop(Iop_Add32,
   8714                                                  mkexpr(t0),
   8715                                                  binop(Iop_Shl32,
   8716                                                        mkU32(0x1),
   8717                                                        mkexpr(t8))),
   8718                                            unop(Iop_32to8,
   8719                                                 mkexpr(t9)))));
   8720 
   8721                      assign(t2, unop(Iop_8Sto32,
   8722                                      unop(Iop_16HIto8,
   8723                                           unop(Iop_32to16, getIReg(rt)))));
   8724                      assign(t3, unop(Iop_32to8,
   8725                                      binop(Iop_Sar32,
   8726                                            binop(Iop_Add32,
   8727                                                  mkexpr(t2),
   8728                                                  binop(Iop_Shl32,
   8729                                                        mkU32(0x1),
   8730                                                        mkexpr(t8))),
   8731                                            unop(Iop_32to8, mkexpr(t9)))));
   8732 
   8733                      assign(t4, unop(Iop_8Sto32,
   8734                                      unop(Iop_16to8,
   8735                                           unop(Iop_32HIto16, getIReg(rt)))));
   8736                      assign(t5, unop(Iop_32to8,
   8737                                      binop(Iop_Sar32,
   8738                                            binop(Iop_Add32,
   8739                                                  mkexpr(t4),
   8740                                                  binop(Iop_Shl32,
   8741                                                        mkU32(0x1),
   8742                                                        mkexpr(t8))),
   8743                                            unop(Iop_32to8, mkexpr(t9)))));
   8744 
   8745                      assign(t6, unop(Iop_8Sto32,
   8746                                      unop(Iop_16HIto8,
   8747                                           unop(Iop_32HIto16, getIReg(rt)))));
   8748                      assign(t7, unop(Iop_32to8,
   8749                                      binop(Iop_Sar32,
   8750                                            binop(Iop_Add32,
   8751                                                  mkexpr(t6),
   8752                                                  binop(Iop_Shl32,
   8753                                                        mkU32(0x1),
   8754                                                        mkexpr(t8))),
   8755                                            unop(Iop_32to8, mkexpr(t9)))));
   8756                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8757                                                   mkexpr(t9),
   8758                                                   mkU32(0x0)),
   8759                                             getIReg(rt),
   8760                                             binop(Iop_16HLto32,
   8761                                                   binop(Iop_8HLto16,
   8762                                                         mkexpr(t7),
   8763                                                         mkexpr(t5)),
   8764                                                   binop(Iop_8HLto16,
   8765                                                         mkexpr(t3),
   8766                                                         mkexpr(t1)))));
   8767                      break;
   8768                   }
   8769                   case 0x8: {  /* SHLL.PH */
   8770                      DIP("shll.ph r%u, r%u, %u", rd, rt, rs);
   8771                      vassert(!mode64);
   8772                      t0 = newTemp(Ity_I32);
   8773                      t1 = newTemp(Ity_I32);
   8774                      t2 = newTemp(Ity_I32);
   8775                      t3 = newTemp(Ity_I32);
   8776                      t4 = newTemp(Ity_I32);
   8777                      t5 = newTemp(Ity_I32);
   8778                      t6 = newTemp(Ity_I32);
   8779                      t7 = newTemp(Ity_I32);
   8780 
   8781                      if (0 == rs) {
   8782                         putIReg(rd, getIReg(rt));
   8783                      } else {
   8784                         /* Shift lower 16 bits. */
   8785                         assign(t0, binop(Iop_Shl32,
   8786                                          unop(Iop_16Sto32,
   8787                                               unop(Iop_32to16, getIReg(rt))),
   8788                                          mkU8(rs)));
   8789 
   8790                         assign(t1, unop(Iop_1Uto32,
   8791                                         binop(Iop_CmpNE32,
   8792                                                binop(Iop_Sar32,
   8793                                                      mkexpr(t0),
   8794                                                      mkU8(16)),
   8795                                                mkU32(0))));
   8796                         assign(t2, unop(Iop_1Uto32,
   8797                                         binop(Iop_CmpNE32,
   8798                                               binop(Iop_Sar32,
   8799                                                     mkexpr(t0),
   8800                                                     mkU8(16)),
   8801                                               mkU32(0xffffffff))));
   8802                         assign(t3, binop(Iop_And32,
   8803                                          mkexpr(t1),
   8804                                          mkexpr(t2)));
   8805                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8806                                                        mkexpr(t3),
   8807                                                        mkU32(0x1)),
   8808                                                  binop(Iop_Or32,
   8809                                                        getDSPControl(),
   8810                                                        mkU32(0x400000)),
   8811                                                  getDSPControl()));
   8812                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8813                                                        binop(Iop_And32,
   8814                                                              getIReg(rt),
   8815                                                              mkU32(0x00008000)),
   8816                                                        binop(Iop_And32,
   8817                                                              mkexpr(t0),
   8818                                                              mkU32(0x00008000))
   8819                                                       ),
   8820                                                  getDSPControl(),
   8821                                                  binop(Iop_Or32,
   8822                                                        getDSPControl(),
   8823                                                        mkU32(0x400000))));
   8824                         /* Shift higher 16 bits. */
   8825                         assign(t4, binop(Iop_Shl32,
   8826                                          unop(Iop_16Sto32,
   8827                                               unop(Iop_32HIto16, getIReg(rt))),
   8828                                          mkU8(rs)));
   8829 
   8830                         assign(t5, unop(Iop_1Uto32,
   8831                                         binop(Iop_CmpNE32,
   8832                                                binop(Iop_Sar32,
   8833                                                      mkexpr(t4),
   8834                                                      mkU8(16)),
   8835                                                mkU32(0))));
   8836                         assign(t6, unop(Iop_1Uto32,
   8837                                         binop(Iop_CmpNE32,
   8838                                               binop(Iop_Sar32,
   8839                                                     mkexpr(t4),
   8840                                                     mkU8(16)),
   8841                                               mkU32(0xffffffff))));
   8842                         assign(t7, binop(Iop_And32,
   8843                                          mkexpr(t5),
   8844                                          mkexpr(t6)));
   8845                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8846                                                        mkexpr(t7),
   8847                                                        mkU32(0x1)),
   8848                                                  binop(Iop_Or32,
   8849                                                        getDSPControl(),
   8850                                                        mkU32(0x400000)),
   8851                                                  getDSPControl()));
   8852                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8853                                                        mkexpr(t7),
   8854                                                        mkU32(0x1)),
   8855                                                  binop(Iop_Or32,
   8856                                                        getDSPControl(),
   8857                                                        mkU32(0x400000)),
   8858                                                  getDSPControl()));
   8859                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8860                                                        binop(Iop_And32,
   8861                                                              getIReg(rt),
   8862                                                              mkU32(0x80000000)),
   8863                                                        binop(Iop_Shl32,
   8864                                                              binop(Iop_And32,
   8865                                                                    mkexpr(t4),
   8866                                                                    mkU32(0x00008000)),
   8867                                                              mkU8(16))
   8868                                                       ),
   8869                                                  getDSPControl(),
   8870                                                  binop(Iop_Or32,
   8871                                                        getDSPControl(),
   8872                                                        mkU32(0x400000))));
   8873                         putIReg(rd, binop(Iop_16HLto32,
   8874                                           unop(Iop_32to16, mkexpr(t4)),
   8875                                           unop(Iop_32to16, mkexpr(t0))));
   8876                      }
   8877                      break;
   8878                   }
   8879                   case 0x9: {  /* SHRA.PH */
   8880                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
   8881                      vassert(!mode64);
   8882                      t0 = newTemp(Ity_I32);
   8883                      t1 = newTemp(Ity_I32);
   8884                      if (0 == rs) {
   8885                         putIReg(rd, getIReg(rt));
   8886                      } else {
   8887                         assign(t0, binop(Iop_Sar32,
   8888                                          unop(Iop_16Sto32,
   8889                                               unop(Iop_32to16, getIReg(rt))),
   8890                                          mkU8(rs)));
   8891                         assign(t1, binop(Iop_Sar32,
   8892                                          unop(Iop_16Sto32,
   8893                                               unop(Iop_32HIto16, getIReg(rt))),
   8894                                          mkU8(rs)));
   8895                         putIReg(rd, binop(Iop_16HLto32,
   8896                                           unop(Iop_32to16, mkexpr(t1)),
   8897                                           unop(Iop_32to16, mkexpr(t0))));
   8898                      }
   8899                      break;
   8900                   }
   8901                   case 0xA: {  /* SHLLV.PH */
   8902                      DIP("shllv.ph r%u, r%u, r%u", rd, rt, rs);
   8903                      vassert(!mode64);
   8904                      t0 = newTemp(Ity_I32);
   8905                      t2 = newTemp(Ity_I32);
   8906                      t3 = newTemp(Ity_I1);
   8907                      t4 = newTemp(Ity_I1);
   8908                      t5 = newTemp(Ity_I32);
   8909                      t6 = newTemp(Ity_I32);
   8910                      t7 = newTemp(Ity_I1);
   8911                      t8 = newTemp(Ity_I1);
   8912                      t9 = newTemp(Ity_I32);
   8913